mathgl-2.4.4/0000755000175000017500000000000013513030151013147 5ustar alastairalastairmathgl-2.4.4/website/0000755000175000017500000000000013513030041014607 5ustar alastairalastairmathgl-2.4.4/website/prepare_doc.sh0000755000175000017500000000167713513030041017444 0ustar alastairalastaircd doc_en/ sed -i -- 's///g' *.html sed -i -- 's//
<\/div>
/g' *.html sed -i -- 's//
<\/div>
/g' *.html sed -i -- 's/<\/body>/<\/div> mathgl-2.4.4/website/games/hextris.html0000644000175000017500000003320113513030041020256 0ustar alastairalastair Hextris

"Hextris" game

Your browser does not support the HTML5 canvas tag.
mathgl-2.4.4/website/games/pentix.html0000644000175000017500000003310413513030041020101 0ustar alastairalastair Pentix

"Pentix" game

Your browser does not support the HTML5 canvas tag.
mathgl-2.4.4/website/games/columns.html0000644000175000017500000002617413513030041020263 0ustar alastairalastair Columns

"Columns" game

Your browser does not support the HTML5 canvas tag.
mathgl-2.4.4/website/games/shiftix.html0000644000175000017500000003240713513030041020255 0ustar alastairalastair Shiftix

"Shiftix" game

Your browser does not support the HTML5 canvas tag.
mathgl-2.4.4/website/games/mk61.html0000644000175000017500000020134213513030041017351 0ustar alastairalastair Эмулятор МК-61

PocketMK – эмулятор калькулятора МК-61

T:
Z:
Y:
X:
rad grad deg


Your browser does not support the HTML5 canvas tag.
Ввод программы

PocketMK – эмулятор семейства популярнейших советских программируемых калькуляторов БЗ-34...МК-61. Основное отличие эмулятора состоит в использовании незадействованных адресов команд, позволивших добавить еще один регистр F, команды для специальных функций (x!, sinh, cosh, tanh, asinh, acosh, atanh, erf, J0, J1, Y0, Y1), команды добавления к регистру (M+) и команды вывода графики в растровое изображение размером 400×300 точек. Имеется два основных режима работы: режим калькулятора, режим редактирования программы (включается галочкой в панели "Программа").

PocketMK использует обратную польскую форму записи. Например, для вычисления выражения 2+3*(6+7) надо выполнить следующие действия: 2 B↑ 3 B↑ 6 B↑ 7 + * + или более просто 6 B↑ 7 + 3 * 2 +. Использование функций аналогично. Например, вычислим синус от угла 37 градусов 30 минут. Сначала превратим минуты в десятичную дробь: 37.5. Переключив PocketMK в режим deg (переключатель находится в верхнем левом углу в режиме калькулятора), вводим это число последовательным нажатием клавиш 3 7 . 5 и берем от него синус, нажав клавиши F sin. На индикаторе читаем значение синуса: 0.6087614290087207. Если нужно ввести большое число, можно воспользоваться командой ввода порядка EE. При этом для отрицательных порядков за ней следует ввести команду ±. Например, 1 . 7 8 EE 5 3 дает 1.78e53, 2 . 5 6 EE ± 7 дает 2.56e-7, 3 ± EE 6 дает -3e6

Внешний вид

PocketMK имеет два режима работы: режим калькулятора (по умолчанию) и режим ввода программы. В режиме калькулятора PocketMK работает в интерактивном режиме – любая нажатая клавиша сразу же выполняется. Вверху находятся кнопки переключения ввода углов, содержимое стека {X,Y,Z,T} и кнопки управления программой. В средней части располагается клавиатура, вид которой зависит от состояния функциональных клавиш «F» и «K». Внизу находятся кнопки панели инструментов и панель меню.

Кнопки переключения ввода углов имеют следующее значение: deg – углы считаются в градусах (период sin(x) равен 360), grad – углы считаются в градах (период sin(x) равен 400), rad – углы считаются в радианах (период sin(x) равен 2π).

Окно отображения стека расположено сверху посередине. «Главный» регистр X выделен цветом, поскольку именно с ним выполняются все основные операции – сложение, вычитание, умножение и деление, вычисление функций, запись и считывание регистров, операции условного перехода. Остальные регистры стека являются скорее «дополнительными» и выводятся серым цветом.

Кнопки управления выполнением программы позволяют выполнить программу пошагово (Step) и запустить программу на автоматическое выполнение с текущей программной позиции (Run). Для остановки программы (например, в случае зацикливания) служит кнопка Stop, заменяющая кнопку Run при запуске программы.

Клавиатура отображается в режиме калькулятора и в режиме редактирования программы. Ее вид зависит от нажатия функциональных клавиш «F» и «K», располагающихся в левой верхней части клавиатуры. Для удобства пользователя цвета кнопок изменяются вместе с изменением их функциональности. Кроме того, графические команды выделены зеленым цветом, а команды обращения к регистрам фиолетовым. Часть кнопок имеет смысл только при выполнении программы (команды перехода, остановки программы и т.д., выделенные желтым). Действие остальных команд одинаково «полезно» в любом режиме. Отличие состоит в том, что в режиме калькулятора команды выполняются сразу, а в режиме ввода программы они записываются в программную память.

Регистры, стек и операции

PocketMK хранит числа в специальных переменных – регистрах. Каждый регистр памяти имеет свое обозначение в виде цифры или буквы. Шестнадцать из них обозначаются числами от 0 до 9 и начальными буквами латинского алфавита (A, B, C, D, E, F). По сути эти регистры являются обычными переменными, обращение к которым возможно произвольным образом. Еще четыре регистра образуют стек и обозначаются латинскими буквами (X, Y, Z, T). Прямой доступ возможен только к одному регистру из них – регистру X. Остальные регистры участвуют в вычислениях и доступны только с помощью команд работы со стеком. Последний из регистров (называемый B или X1) хранит информацию о предыдущем значении регистра X и может быть только прочитан с помощью команды Bx. Часто в описаниях программ перед регистром ставят букву R (например, RA – регистр А), чтобы отличать регистр от буквы. Регистры X, Y, Z, T отображаются на экране калькулятора. Регистры 0,1,...,F можно посмотреть в панели «Регистры».

При вводе в калькулятор число заносится в регистр X. Прочитать число в регистрах 0,1,...,F можно с помощью кнопки MR (от английского «memory read»). Например, команда MRA впишет число из регистра A в регистр Х. Аналогично команда MSA (от английского «memory save») запишет число из регистра Х в регистр А. Команда M+A прибавит число из регистра Х к числу, хранящемуся в регистре А. Команда M+ отсутствовала в МК-61 и была введена для удобства работы и программирования различных статистических приложений.

Каждая операция калькулятором выполняется либо над одним числом, находящимся в регистре X (операция одноместная: x2, sin, erf и т.д.), либо над двумя числами, одно из которых находится в регистре X, а другое - в регистре Y. Отличительной особенностью этого калькулятора является то, что операция, которую следует производить с двумя числами, выполняется после ввода двух чисел – используется так называемая польская или постфиксная запись выражений.

Числа, над которыми нужно совершить ту или иную арифметическую операцию, должны находиться в двух регистрах – X и Y. В регистр Y можно попасть только из регистра X. Делается это нажатием клавиши B↑. При этом в регистре X остается копия числа. Затем в регистр X записывается второе число, причем первое число стирается. В случае вычитания уменьшаемое должно находиться в Y, а вычитаемое – в X. При делении в Y должно находиться делимое, в X – делитель. После ввода числа в оба регистра, можно нажать клавишу выбранной операции. Результат ее будет помещен в регистр X. То, что было прежде в регистре Y, не сохранится. Здесь следует обратить внимание на то, что если в регистре X находился результат операции, то ввод нового числа в регистр X автоматически передвигает старое содержимое регистра X в регистр Y. Исключением являются операции очистки регистра Cx и операция B↑.

Наконец, в таблице приведено состояние стека до и после применения различных операций:

ОперацияСтек доСтек после
Ввод числа r из регистра или числа πb x y z tb r x y z
Ввод числа n после Сх, B↑b x y z tb n y z t
Ввод числа n после других операцийb x y z tb n x y z
Команда Cxb x y z tb 0 y z t
Команда B↑b x y z tb x x y z
Команда Bxb x y z tb b x y z
Команда b x y z tx y x z t
Команда b x y z tx y z t x
Вычисление функции f(x)b x y z tx f y z t
Двуместная операция gb x y z tx g z t t
Команда B↓b x y z tx y z t t

Программирование

Составим теперь простую программу вычисления площади круга. Формула для вычисления площади круга известна: S=πD2/4, где D – диаметр круга. Константа π уже есть в калькуляторе. Величину D необходимо вручную ввести с клавиатуры (оно будет помещено в регистр X). Пусть D = 3. Для ручного расчета нужно нажать клавиши: x2 F pi * 4 /. На индикаторе читаем результат: 7.0685834705770345. Те же клавиши и в той же последовательности нужно будет нажать, когда мы станем вводить в калькулятор программу для вычисления площади круга.

Программа располагается в калькуляторе в виде отдельных команд, каждая из которых занимает свою ячейку программной памяти (некоторые управляющие – две ячейки – команда и адрес). Всего таких ячеек 160. Им присвоены номера, называемые адресами – от #00 до #F9. В силу совместимости с МК-61 нумерация сделана так, что первая цифра шестнадцатеричная, а вторая всего лишь десятичная. Например, адрес #F9 = 0xF*10+9 = 159. Такая вот смесь ☺ !

Чтобы ввести программу в калькулятор, надо перевести его в состояние, называемое режимом редактирования программы. В режиме редактирования PocketMK нажатие клавиш приводит к вводу команды в программную память вместо ее непосредственного выполнения. Для перехода в режим редактирования программы следует раскрыть панель программа и поставить галочку напротив Ввод программы. Стрелки в этой панели перемещают курсор (текущий адрес), кнопки Ins и Del добавляют и удаляют текущую/последнюю ячейку программы. Адрес первой команды в строке указывается перед двоеточием. Текущая позиция курсора выделена голубым. Курсор не показывается если он находится за последней командой (калькулятор готов к добавлению новой команды).

Нажимаем x2 и в программе появляется x2. Ее появление в таблице означает, что команда занесена в программную память. Одновременно прямоугольник сместился вправо – счетчик адресов увеличился на 1. Далее нажимаем F π и в программе появляется π (модификатор F в программе всегда опускается) и т.д. Таким образом вводятся все команды. Для останова работы калькулятора по программе необходимо ввести специальную команду: stop (клавиши F stop).

Чтобы проверить работу программы вернемся в режим калькулятора (сняв галочку), введем диаметр круга и запустим программу кнопкой Run. На мгновение мигнет индикатор Stop вместо Run и программа выдаст ответ. Кнопка Stop предназначена для останова программы (например, в бесконечном цикле). Для пошагового исполнения программы (в целях отладки или в качестве одного из способов ввода чисел) можно воспользоваться кнопкой Step. Ее действие полностью аналогично Run, но будет исполнена только текущая команда.

Следует отметить, что в отличие от калькулятора MK-61, переход в начало программы осуществляется автоматически, если курсор не виден (ожидается добавление новой команды). Кроме того, программа автоматически останавливается при достижении конца введенных команд (команда stop в конце программы не обязательна).

Команды перехода

Для безусловного перехода на адрес программы используется клавиша go (аналог команды БП – безусловный переход). После команды следует указать адрес перехода. Например, для того, чтобы перейти на адрес 60, надо нажать клавиши: go 6 0. Эта команда работает только в программном режиме и занимает две ячейки памяти: первая ячейка – код команды перехода, вторая – адрес перехода. Отмечу, что для совместимости с программами МК–61 пришлось ввести «странную» систему адресов. Всего ячеек 160 с адресами – от 00 до F9. При этом адрес состоит их двух цифр: первая цифра шестнадцатеричная, а вторая десятичная. Например, адрес #F9 = 0xF*10+9 = 159.

Чтобы вызвать подпрограмму, используется команда sub (аналог команды ПП – переход на подпрограмму). Так же, как и в команде безусловного перехода, необходимо указать адрес, с которого начинается подпрограмма. Команда возврата из подпрограммы – ret (аналог команды В/О). Подпрограммы могут вкладываться друг в друга.

Также есть специальные команды, которые изменяют порядок выполнения программы в зависимости от содержимого регистра X. Это команды x<0, x≥0, x=0, x≠0. Если условие выполняется, то управление передается на команду, следующую за командой условия (напомним, что команда условия занимает 2 ячейки – команда и адрес), в противном случае – управление передастся на указанный адрес. Например, с адреса 20 мы введем строку: F x<0 25, тогда если содержимое регистра X будет меньше нуля, то программа продолжится с адреса 22, а если ноль и больше, то с адреса 25.

Для организации циклов предусмотрены специальные команды L0, L1, L2, L3. После ввода этих команд также необходимо указать адрес перехода. Каждая команда ассоциирована с регистрами от 0 до 3, соответственно. После выполнения команды происходит вычитание единицы из этого регистра и сравнение результата с нулем. Если результат равен нулю, то программа продолжит свое выполнение со следующего адреса. Иначе – перейдет на указанный адрес перехода. Напишем программу вычисления факториала. Сначала перейдем в режим программирования с помощью меню или панели управления. Затем вводим программу: MS0 1 MR0 * L0 02. После ввода программы переходим в режим калькулятора, вводим число вводится с клавиатуры и нажимаем кнопку Run. В результате в регистре X появляется факториал числа. Можно проверить вычисленное значение нажав ↔ K x!.

Все команды PocketMK имеют уникальный номер в диапазоне 0...255. Полный список команд с указанием их кодов можно найти в таблице. Здесь номер строки дает старший разряд, номер столбца – младший разряд номера команды. Например, команда |x| имеет номер 0x31.

x0x1x2x3x4x5x6x7x8x9xAxBxCxDxExF
x000123456789.±EECxB↑Bx
x10+*/10xexlglnasinacosatansincostanY0
x20πsqrtx21/xxyB↓shchtherfx!asinhacoshatanhY1
x30col|x|signcls[x]{x}maxandorxornotrndpntlinerectarc
x40MS0MS1MS2MS3MS4MS5MS6MS7MS8MS9MSAMSBMSCMSDMSEMSF
x50stopgoretsubnopJ0J1x≠0L2x≥0L3L1x<0L0x=0wait
x60MR0MR1MR2MR3MR4MR5MR6MR7MR8MR9MRAMRBMRCMRDMREMRF
x70Kx≠00Kx≠01Kx≠02Kx≠03Kx≠04Kx≠05Kx≠06Kx≠07Kx≠08Kx≠09Kx≠0AKx≠0BKx≠0CKx≠0DKx≠0EKx≠0F
x80Kgo0Kgo1Kgo2Kgo3Kgo4Kgo5Kgo6Kgo7Kgo8Kgo9KgoAKgoBKgoCKgoDKgoEKgoF
x90Kx≥00Kx≥01Kx≥02Kx≥03Kx≥04Kx≥05Kx≥06Kx≥07Kx≥08Kx≥09Kx≥0AKx≥0BKx≥0CKx≥0DKx≥0EKx≥0F
xA0Ksub0Ksub1Ksub2Ksub3Ksub4Ksub5Ksub6Ksub7Ksub8Ksub9KsubAKsubBKsubCKsubDKsubEKsubF
xB0KMS0KMS1KMS2KMS3KMS4KMS5KMS6KMS7KMS8KMS9KMSAKMSBKMSCKMSDKMSEKMSF
xC0Kx<00Kx<01Kx<02Kx<03Kx<04Kx<05Kx<06Kx<07Kx<08Kx<09Kx<0AKx<0BKx<0CKx<0DKx<0EKx<0F
xD0KMR0KMR1KMR2KMR3KMR4KMR5KMR6KMR7KMR8KMR9KMRAKMRBKMRCKMRDKMREKMRF
xE0Kx=00Kx=01Kx=02Kx=03Kx=04Kx=05Kx=06Kx=07Kx=08Kx=09Kx=0AKx=0BKx=0CKx=0DKx=0EKx=0F
xF0M+0M+1M+2M+3M+4M+5M+6M+7M+8M+9M+AM+BM+CM+DM+EM+F

В целом система команд основана на системе команд популярных советских микрокалькуляторов БЗ-34 или МК-61. Так что практически любая программа с МК-61 (не использующая недокументированные возможности) будет работать и на PocketMK. Однако, есть и несколько отличий. PocketMK использует фортрановские символьные обозначения функций: asin для арксинуса, tan вместо tg для тангенса и т.д. Кроме того, имеется различное начертание ряда команд с более устоявшимся англоязычным обозначением:

PocketMKБЗ-34MK-61
MRИПП→X
MSПХ→П
rndКСЧ
signКЗН
stopС/ПС/П
retВ/ОВ/О
goБПБП
subПППП

В PocketMK добавлен ряд команд (выделены цветом в таблице):

  1. графических (pnt, line, rect, arc, col, cls) для рисования точки (х,у), линии в точку (х,у), прямоугольника из текущей до точки (х,у), дуги из текущей до точки (х,у), задания цвета (можно задавать и вручную выбором из палитры) и очистки экрана;
  2. спец. функций (erf(x), sinh(x), cosh(x), tanh(x), asinh(x), atanh(x), x! = Г(x+1), j0(x), y0(x), j1(x), y1(x));
  3. прибавления регистра Х к числу в указанном регистре (команда М+);
  4. удаления числа из стека (команда B↓).

Удалены редко использующиеся (по крайней мере автором) команды по преобразованию углов в минуты, секунды и обратно. Операция xy теперь стала настоящей двуместной операцией (содержимое регистра Y не сохраняется).

В нормальном виде клавиатура содержит довольно ограниченный набор часто используемых кнопок. Доступ к большинству научных функций и управляющих команд возможен после нажатия клавиш F, K или обоих сразу (для графических команд).

Ввод числа

Ввод числа осуществляется командами 0 1 2 3 4 5 6 7 8 9 . ± EE. Команды 0 1 2 3 4 5 6 7 8 9 . вводят непосредственно цифры мантиссы или порядка. Команда ± меняет знак числа в регистре Х, если введена до команды EE или знак порядка, если после. Команда EE указывает, что дальнейший ввод относится к вводу порядка. Нажатие любой другой клавиши (кроме функциональных F или K) прерывает ввод числа. При вводе нового числа предыдущее значение регистра Х поднимается вверх по стеку, если перед этим не была выполнена одна из команд Cx или B↑.

Важно! Команда EE превращает 0 в 1 (при этом в стеке меняется только значение регистра Х, остальные регистры стека сохраняют свои значения). Эта недокументированная особенность советских калькуляторов часто использовалась в программах.

Совет! Команда EE изменяет порядок любого числа в регистре Х. Поэтому для быстрого умножения числа на 10n в программе можно воспользоваться кодом EE n, занимающим всего две ячейки памяти при n=1...9.

Команды работы со стеком

К этой группе относятся команды Cx B↑ ↔ Bx ↻ B↓. Напомним, что PocketMK использует стек из 4х регистров (X,Y,Z,T) и регистр B для хранения предыдущего значения Х. Исходное значение стека будем считать равным b x y z t.

CxОбнуляет регистр Х. Ввод числа после этой команды не изменяет содержимое стека.
B↑Поднимает число Х вверх. Стек изменяется следующим образом b x x y z. Ввод числа после этой команды не изменяет содержимое стека.
Меняет содержимое регистров X и Y местами. Стек изменяется следующим образом x y x z t.
BxВозвращает значение регистра Вх в Х. Стек изменяется следующим образом b b x y z.
Вращает содержимое стека. Стек изменяется следующим образом x y z t x.
B↓Удаляет содержимое регистра Х со сдвигом стека вниз. Стек изменяется следующим образом x y z t t.

Двуместные операции

Операции выполняются над числами в регистрах X и Y. При этом содержимое регистра Y теряется, а регистры Z и T смещаются вниз. Значение регистра Х заносится в регистр В. Стек b x y z t изменяется следующим образом x g z t t, где g – результат операции. Рассмотрим команды подробнее.

+Сложение чисел X=Y + X.
Разность чисел X=Y – X.
*Умножение чисел X=Y * X.
/Деление чисел X=Y / X.
xyВозведение в степень X=XY.
andПобитовое И. Дробная часть чисел отбрасывается.
orПобитовое ИЛИ. Дробная часть чисел отбрасывается.
xorПобитовое Исключающее ИЛИ. Дробная часть чисел отбрасывается.
maxМаксимальное из чисел X и Y.

Математические функции

Вызов функции относится к одноместным операциям, не затрагивающим содержимое регистров Y, Z, T. Значение аргумента всегда заносится в регистр В. Результат действия функции помещается в регистр Х. Для обратных функций на советских калькуляторах использовались обозначения f(x)-1 (например, sin-1), в PocketMK они заменены на стандартные компьютерные обозначения с добавление буквы a перед именем функции (например, asin).

10xВозведение в степень 10x = exp(x*log(10)).
exЭкспонента ex = exp(x), где e = 2.718281828459.
lgДесятичный логарифм lg(x)=ln(x)/ln(10), lg(10x)=x.
lnНатуральный логарифм, ln(exp(x))=x.
sinСинус sin(x), вычисляется в зависимости от выбора deg|grd|rad.
cosКосинус cos(x), вычисляется в зависимости от выбора deg|grd|rad.
tanТангенс tan(x)=sin(x)/cos(x), вычисляется в зависимости от выбора deg|grd|rad.
asinАрксинус asin(sin(x))=x, вычисляется в зависимости от выбора deg|grd|rad.
acosАрккосинус acos(cos(x))=|x|, вычисляется в зависимости от выбора deg|grd|rad.
atanАрктангенс atan(tan(x))=x, вычисляется в зависимости от выбора deg|grd|rad.
shГиперболический синус sh(x) = (ex – e-x)/2.
chГиперболический косинус ch(x)=(ex + e-x)/2.
thГиперболический тангенс th(x)=sh(x)/ch(x).
ashГиперболический арксинус ash(sh(x))=x.
achГиперболический арккосинус ach(ch(x))=|x|.
athГиперболический арктангенс ath(th(x))=x.
xКорень квадратный sqrt(x2) = |x|.
x2Квадрат числа.
1/x
erfИнтеграл вероятности erf(x) = ∫exp(-x2)dx.
x!Факториал x!=Г(x+1), Г(x) – гамма функция.
J0Функция Бесселя J0.
J1Функция Бесселя J1.
Y0Функция Бесселя Y0.
Y1Функция Бесселя Y1.
|x|Абсолютное значение |x| = {x для x≥0; –x для x<0}
signЗнак числа: 1 для x>0, 0 для x=0, -1 для x<0.
[x]Целая часть числа.
{x}Дробная часть числа.
rndСлучайное число. В отличии от МК-61 не зависит от числа X. Из соображений совместимости, случайное число не изменяет стек (как в случае с π).
notПобитовое отрицание. Дробная часть чисел отбрасывается.

Работа с регистрами

Для работы с регистрами предназначены три группы команд.

  1. Команды MSN записывают значение регистра Х в регистр N. Значение регистра Х не изменяется.
  2. Команды M+N прибавляют значение регистра Х к числу в регистре N и записывают результат в регистр N. Значение регистра Х не изменяется.
  3. Команды MRN присваивают регистру X значение из регистра N. Стек b x y z t изменяется следующим образом b n x y z, где n – значение в регистре N.
  4. Немножко в стороне стоит команда π. Ее действие полностью аналогично командам MRN, но в регистр Х записывается число π=3.141592653589793.
Каждая из команд присвоения регистру имеет отдельный уникальный номер. Это сделано для совместимости с программами для МК-61.

Совет! Ввод небольшого числа данных (до 16 чисел) в программу удобно выполнять с помощью заполнения регистров памяти перед запуском программы.

Совет! Ввод данных в программу можно выполнять с помощью кнопки Step. Кусок соответствующей программы будет выглядеть следующим образом: MS1 MS2 MS3 .... Идея состоит в пошаговом исполнении программы, когда число в регистре Х меняется пользователем на каждом шаге.

Совет! Часто программы используют константы (или типичные начальные условия). Их можно сохранить вместе с программой если пометить соответствующие регистры при сохранении.

Совет! Иногда удобней (особенно в играх) загрузить программу с заполненными регистрами заново, чем вводить цифры вручную.

Управление программой

Эта группа команд осуществляет управление выполнением программы. Как правило, команды из этой группы требуют 2 ячейки памяти: одна ячейка под саму команду, а вторая ячейка на адрес перехода для этой команды.

stopОстанавливает выполнение программы.
waitПриостанавливает выполнение программы на 1 секунду. Удобно использовать в динамических играх.
nopНе выполняет никаких действий.
goБезусловный переход на адрес перехода.
subВызов подпрограммы с адреса перехода.
retВозврат из подпрограммы. При пустом стеке возврата происходит возврат на нулевой адрес (начало программы).
x≠0Если условие X≠0 выполнено, выполняется команда, следующая после адреса перехода, в противном случае производится переход по адресу перехода.
x<0Если условие X<0 выполнено, выполняется команда, следующая после адреса перехода, в противном случае производится переход по адресу перехода.
x=0Если условие X=0 выполнено, выполняется команда, следующая после адреса перехода, в противном случае производится переход по адресу перехода.
x≥0Если условие X≥0 выполнено, выполняется команда, следующая после адреса перехода, в противном случае производится переход по адресу перехода.
L0После выполнения команды происходит вычитание единицы из регистра 0. Если результат R0≤0, то продолжится выполнение со следующего адреса. Иначе – перейдет на указанный адрес перехода.
L1После выполнения команды происходит вычитание единицы из регистра 1. Если результат R1≤0, то продолжится выполнение со следующего адреса. Иначе – перейдет на указанный адрес перехода.
L2После выполнения команды происходит вычитание единицы из регистра 2. Если результат R2≤0, то продолжится выполнение со следующего адреса. Иначе – перейдет на указанный адрес перехода.
L3После выполнения команды происходит вычитание единицы из регистра 3. Если результат R3≤0, то продолжится выполнение со следующего адреса. Иначе – перейдет на указанный адрес перехода.

Совет! Для быстрого возврата на нулевой адрес можно использовать команду ret. Это работает, если стек возвратов пустой (не выполняется подпрограмма в данный момент).

Совет! Использование команды wait и переключателя deg|grd|rad позволяет создавать динамические программы. Идея состоит в том, что функция cos выдает различные значения в зависимости от положения переключателя. Например, следующий код wait MR9 cos sign будет ожидать реакции пользователя 1 секунду и возвращать -1, 0, 1 для переключателя deg|grd|rad соответственно, если R9=100.

Косвенная адресация

Команды косвенной адресации начинаются с нажатия кнопки K и всегда занимают одну ячейку памяти. После нажатия K вводится одна из команд MS, MR, go, sub, x<0, x≥0, x=0, x≠0 и номер регистра. На клавиатуре команды косвенной адресации выделены фиолетовым цветом. При косвенной адресации (индексации) в командах KMS и KMR запись и считывание числа производится из регистра с номером равным остатку от деления на 16 числа в указанном регистре. Переход по адресу в командах Kgo, Ksub, Kx<0, Kx≥0, Kx=0, Kx≠0 производится по остатку от деления содержимого регистра на 160.

Перед выполнением действия значение регистра модифицируется. Если номер регистра 0, 1, 2, 3, то его значение уменьшается на единицу. Если номер регистра равен 4, 5, 6, то значение регистра увеличивается на единицу. Остальные регистры не изменяются.

Например, команда KMS0 поместит значение регистра X в регистр, номер которого указан в регистре 0, но меньший на 1. Команда KMR4 поместит в регистр X значение регистра, указанного в регистре 4, но больший на 1. Команда Kgo9 переведет работу программы на адрес, указанный в регистре 9. Аналогично переход на подпрограмму, адрес которой указан в регистре B, выполняется командой KsubB. Команда Kx=0A аналогична команде x=0 XX, но адрес перехода XX указывается в регистре A, и команда занимает одну ячейку памяти.

Следует обратить внимание, что если в регистр поместить дробное число, а затем к этому регистру применить команду косвенного вызова, то от помещенного числа будет отброшена дробная часть. Например, поместив число 12.34567 в регистр 9 и выполнив команду KMR9, в регистре 9 останется число 12. Эта «недокументированная» особенность в программах БЗ-34 часто использовалась для отделения целой части числа и была сохранена в PocketMK.

Графические команды

В PocketMK добавлены 6 графических команд: cls, col, pnt, line, rect, arc. Графический вывод производится в растровую картинку размером 400*300 с началом координат в левом нижнем углу. Все точки вне этих границ игнорируются.

Обработка ошибок

В ходе расчетов могут возникать ошибочные ситуации (например, деление на 0, извлечение корня из отрицательно числа и т.д.). В этом случае на экране показывается сообщение NaN или Infinity. Работа программы автоматически останавливается при возникновении ошибочной ситуации.

Советы

  • Команда EE изменяет порядок любого числа в регистре Х. Поэтому для быстрого умножения числа на 10n в программе можно воспользоваться кодом EE n, занимающим всего две ячейки памяти при n=1...9.
  • Ввод небольшого числа данных (до 16 чисел) в программу удобно выполнять с помощью заполнения регистров памяти перед запуском программы.
  • Ввод данных в программу можно выполнять с помощью кнопки Step. Кусок соответствующей программы будет выглядеть следующим образом: MS1 MS2 MS3 .... Идея состоит в пошаговом исполнении программы, когда число в регистре Х меняется пользователем на каждом шаге.
  • Часто программы используют константы (или типичные начальные условия). Их можно сохранить вместе с программой если пометить соответствующие регистры при сохранении.
  • Иногда удобней (особенно в играх) загрузить программу с заполненными регистрами заново, чем вводить цифры вручную.
  • Для быстрого возврата на нулевой адрес можно использовать команду ret. Это работает, если стек возвратов пустой (не выполняется подпрограмма в данный момент).
  • Использование команды wait и переключателя deg|grd|rad позволяет создавать динамические программы. Идея состоит в том, что функция cos выдает различные значения в зависимости от положения переключателя. Например, следующий код wait MR9 cos sign будет ожидать реакции пользователя 1 секунду и возвращать -1, 0, 1 для переключателя deg|grd|rad соответственно, если R9=100.
mathgl-2.4.4/website/games/jumps.html0000644000175000017500000001363113513030041017733 0ustar alastairalastair Jumps

"Jumps"

Max result: 0.

Your browser does not support the HTML5 canvas tag.
mathgl-2.4.4/website/games/colorex.html0000644000175000017500000003316413513030041020253 0ustar alastairalastair Colorex

"Colorex" game

Your browser does not support the HTML5 canvas tag.
mathgl-2.4.4/website/games/mk61.js0000644000175000017500000007417613513030041017036 0ustar alastairalastairvar x=0, y=0, z=0, t=0, b=0; // stack var reg = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; // registers 0...9,A...F var ret = []; // return stack var prog = []; // program to be executed (codes only) var desc = ""; // program description var pos = 0; // current execution position var stop = false; // flag to stop execution var interval = 0; var pressF = 0; // key F is pressed or not var pressK = 0; // key K is pressed or not var prgON = false; // we in program mode var degF = Math.PI/180; // factor of degrees (1, Math.PI/200, Math.PI/180) var num = ""; // number being typed var up = false; // need shift up before new number var x0=0, y0=0; // current graphical coordinates var ctx = document.getElementById("myCanvas").getContext("2d"); // var cols = ['#000', '#FFF', '#F00', '#0F0', '#00F', '#0FF', '#F0F', '#FF0', // '#ccc', '#888', '#F80', '#0F8', '#80F', '#8F0', '#08F', '#F08', // '#800', '#080', '#008', '#088', '#808', '#880', '#840', '#084', // '#408', '#480', '#048', '#804']; var cols = ['#00f', '#08f', '#0ff', '#0f8', '#0f0', '#8f0', '#ff0', '#f80', '#f00', '#f08', '#f0f', '#80f', '#00a', '#05a', '#0aa', '#0a5', '#0a0', '#5a0', '#aa0', '#a50', '#a00', '#a05', '#a0a', '#50a', '#fff', '#ccc', '#999', '#666', '#333', '#000']; var ccol = 'black'; // current color function setColor(v) { var l=cols.length, c = Math.floor(v)%l; if(c<0) c+=l; ccol = cols[c]; } function fin() { up=true; num=""; } function checkUp() { if(up) { num=""; t=z; z=y; y=x; up=false; } } var cmds = [ {id:"0", exec:function(){ checkUp(); num = num+"0"; x = num*1; }}, // hex = 0 {id:"1", exec:function(){ checkUp(); num = num+"1"; x = num*1; }}, {id:"2", exec:function(){ checkUp(); num = num+"2"; x = num*1; }}, {id:"3", exec:function(){ checkUp(); num = num+"3"; x = num*1; }}, {id:"4", exec:function(){ checkUp(); num = num+"4"; x = num*1; }}, {id:"5", exec:function(){ checkUp(); num = num+"5"; x = num*1; }}, {id:"6", exec:function(){ checkUp(); num = num+"6"; x = num*1; }}, {id:"7", exec:function(){ checkUp(); num = num+"7"; x = num*1; }}, {id:"8", exec:function(){ checkUp(); num = num+"8"; x = num*1; }}, {id:"9", exec:function(){ checkUp(); num = num+"9"; x = num*1; }}, {id:".", exec:function(){ checkUp(); num = num+"."; x = num*1; }}, {id:"±", exec:function(){ if(num.indexOf("e+")>0) num = num.replace("e+","e-"); else if(num.indexOf("e-")>0) num = num.replace("e-","e+"); else { x = -x; fin(); } }}, {id:"EE", exec:function(){ if(num=="") num = x.toString(10); if(num=="0") num = "1"; // This is *feature* of MK-61 if(num.search('e')<0) num = num+"e+0"; up=false; }}, {id:"Cx", exec:function(){ up=false; num=""; x=0; }}, {id:"B↑",exec:function(){ up=false; num=""; t=z; z=y; y=x; }}, {id:"Bx", exec:function(){ fin(); x=b; }}, {id:"+", exec:function(){ fin(); x=y+x; y=z; z=t; }}, // hex = 16 {id:"−",exec:function(){ fin(); x=y-x; y=z; z=t; }}, {id:"∗", exec:function(){ fin(); x=y*x; y=z; z=t; }}, {id:"/", exec:function(){ fin(); x=y/x; y=z; z=t; }}, {id:"↔",exec:function(){ fin(); var bb=x; x=y; y=bb; }}, {id:"10x",exec:function(){ fin(); x=Math.pow(10,x);}}, {id:"ex", exec:function(){ fin(); x=Math.exp(x); }}, {id:"lg", exec:function(){ fin(); x=Math.log(x)/Math.LN10;}}, {id:"ln", exec:function(){ fin(); x=Math.log(x); }}, {id:"asin", exec:function(){ fin(); x=Math.asin(x)/degF; }}, {id:"acos", exec:function(){ fin(); x=Math.acos(x)/degF; }}, {id:"atan", exec:function(){ fin(); x=Math.atan(x)/degF; }}, {id:"sin", exec:function(){ fin(); x=Math.sin(x*degF); }}, {id:"cos", exec:function(){ fin(); x=Math.cos(x*degF); }}, {id:"tan", exec:function(){ fin(); x=Math.tan(x*degF); }}, {id:"Y0", exec:function(){ fin(); x=BesselY0(x); }}, {id:"π", exec:function(){ fin(); t=z; z=y; y=x; x=Math.PI; }}, // hex = 32 {id:"√x", exec:function(){ fin(); x=Math.sqrt(x); }}, {id:"x2",exec:function(){ fin(); x=x*x; }}, {id:"1/x", exec:function(){ fin(); x=1/x; }}, {id:"xy",exec:function(){ fin(); x=Math.pow(x,y); y=z; z=t;}}, {id:"↻", exec:function(){ fin(); var bb=x; x=y; y=z; z=t; t=bb; }}, {id:"B↓",exec:function(){ fin(); x=y; y=z; z=t; }}, {id:"sh", exec:function(){ fin(); x=Math.sinh(x); }}, {id:"ch", exec:function(){ fin(); x=Math.cosh(x); }}, {id:"th", exec:function(){ fin(); x=Math.tanh(x); }}, {id:"erf", exec:function(){ fin(); x=erf(x); }}, {id:"x!", exec:function(){ fin(); x=fact(x); }}, {id:"ash", exec:function(){ fin(); x=Math.asinh(x); }}, {id:"ach", exec:function(){ fin(); x=Math.acosh(x); }}, {id:"ath", exec:function(){ fin(); x=Math.atanh(x); }}, {id:"Y1", exec:function(){ fin(); x=BesselY1(x); }}, {id:"col", exec:function(){ fin(); setColor(x); }}, // hex = 48 {id:"|x|", exec:function(){ fin(); x=Math.abs(x); }}, {id:"sign", exec:function(){ fin(); if(x<0) x=-1; if(x>0) x=1;}}, {id:"cls", exec:function(){ fin(); ctx.clearRect(0, 0, 400, 300); x0=y0=0; }}, {id:"[x]", exec:function(){ fin(); x=Math.floor(x); }}, {id:"{x}", exec:function(){ fin(); x=x-Math.floor(x); }}, {id:"max", exec:function(){ fin(); x=Math.max(x,y); y=z; z=t; }}, {id:"and", exec:function(){ fin(); x=x&y; y=z; z=t; }}, {id:"or", exec:function(){ fin(); x=x|y; y=z; z=t; }}, {id:"xor", exec:function(){ fin(); x=x^y; y=z; z=t; }}, {id:"not", exec:function(){ fin(); x=~x; }}, {id:"rnd", exec:function(){ fin(); x=Math.random(); }}, {id:"pnt", exec:function(){ fin(); ctx.beginPath(); ctx.fillStyle = ccol; ctx.rect(x,y,1,1); ctx.fill(); x0=x; y0=y; }}, {id:"line", exec:function(){ fin(); ctx.beginPath(); ctx.strokeStyle=ccol; ctx.moveTo(x0,y0); ctx.lineTo(x,y); ctx.stroke(); x0=x; y0=y; }}, {id:"rect", exec:function(){ fin(); ctx.beginPath(); ctx.fillStyle = ccol; ctx.rect(x,y,z-x,t-y); ctx.fill(); }}, {id:"arc", exec:function(){ fin(); ctx.beginPath(); ctx.strokeStyle=ccol; ctx.arc(x0,y0,x,y*degF,z*degF); ctx.stroke(); }}, // x=R. y=angl1, z=angl2 {id:"MS0", exec:function(){ fin(); reg[0]=x; }}, // hex = 64 {id:"MS1", exec:function(){ fin(); reg[1]=x; }}, {id:"MS2", exec:function(){ fin(); reg[2]=x; }}, {id:"MS3", exec:function(){ fin(); reg[3]=x; }}, {id:"MS4", exec:function(){ fin(); reg[4]=x; }}, {id:"MS5", exec:function(){ fin(); reg[5]=x; }}, {id:"MS6", exec:function(){ fin(); reg[6]=x; }}, {id:"MS7", exec:function(){ fin(); reg[7]=x; }}, {id:"MS8", exec:function(){ fin(); reg[8]=x; }}, {id:"MS9", exec:function(){ fin(); reg[9]=x; }}, {id:"MSA", exec:function(){ fin(); reg[10]=x; }}, {id:"MSB", exec:function(){ fin(); reg[11]=x; }}, {id:"MSC", exec:function(){ fin(); reg[12]=x; }}, {id:"MSD", exec:function(){ fin(); reg[13]=x; }}, {id:"MSE", exec:function(){ fin(); reg[14]=x; }}, {id:"MSF", exec:function(){ fin(); reg[15]=x; }}, {id:"stop", exec:function(){ fin(); stop=true; }}, // hex = 80 {id:"go", exec:function(opt=-1){ fin(); pos=opt-1; }}, {id:"ret", exec:function(){ fin(); pos=ret.length>0?ret.pop():0; }}, {id:"sub", exec:function(opt=-1){ fin(); ret.push(pos+1); pos=opt-1; }}, {id:"nop", exec:function(){ fin(); }}, {id:"J0", exec:function(){ fin(); x=BesselJ0(x); }}, {id:"J1", exec:function(){ fin(); x=BesselJ1(x); }}, {id:"X≠0",exec:function(opt=-1){ fin(); if(x==0) pos=opt-1; else pos+=1; }}, // !!!NOTE {id:"L2", exec:function(opt=-1){ fin(); reg[2] -= 1; if(reg[2]>0) pos=opt-1; else pos+=1; }}, {id:"X≥0",exec:function(opt=-1){ fin(); if(x<0) pos=opt-1; else pos+=1; }}, // !!!NOTE {id:"L3", exec:function(opt=-1){ fin(); reg[3] -= 1; if(reg[3]>0) pos=opt-1; else pos+=1; }}, {id:"L1", exec:function(opt=-1){ fin(); reg[1] -= 1; if(reg[1]>0) pos=opt-1; else pos+=1; }}, {id:"X<0",exec:function(opt=-1){ fin(); if(x>=0) pos=opt-1; else pos+=1; }}, // !!!NOTE {id:"L0", exec:function(opt=-1){ fin(); reg[0] -= 1; if(reg[0]>0) pos=opt-1; else pos+=1; }}, {id:"X=0", exec:function(opt=-1){ fin(); if(x!=0) pos=opt-1; else pos+=1; }}, // !!!NOTE {id:"wait", exec:function(){ fin(); setTimeout(function(){}, 1000); }}, {id:"MR0", exec:function(){ fin(); t=z; z=y; y=x; x=reg[0]; }}, // hex = 96 {id:"MR1", exec:function(){ fin(); t=z; z=y; y=x; x=reg[1]; }}, {id:"MR2", exec:function(){ fin(); t=z; z=y; y=x; x=reg[2]; }}, {id:"MR3", exec:function(){ fin(); t=z; z=y; y=x; x=reg[3]; }}, {id:"MR4", exec:function(){ fin(); t=z; z=y; y=x; x=reg[4]; }}, {id:"MR5", exec:function(){ fin(); t=z; z=y; y=x; x=reg[5]; }}, {id:"MR6", exec:function(){ fin(); t=z; z=y; y=x; x=reg[6]; }}, {id:"MR7", exec:function(){ fin(); t=z; z=y; y=x; x=reg[7]; }}, {id:"MR8", exec:function(){ fin(); t=z; z=y; y=x; x=reg[8]; }}, {id:"MR9", exec:function(){ fin(); t=z; z=y; y=x; x=reg[9]; }}, {id:"MRA", exec:function(){ fin(); t=z; z=y; y=x; x=reg[10]; }}, {id:"MRB", exec:function(){ fin(); t=z; z=y; y=x; x=reg[11]; }}, {id:"MRC", exec:function(){ fin(); t=z; z=y; y=x; x=reg[12]; }}, {id:"MRD", exec:function(){ fin(); t=z; z=y; y=x; x=reg[13]; }}, {id:"MRE", exec:function(){ fin(); t=z; z=y; y=x; x=reg[14]; }}, {id:"MRF", exec:function(){ fin(); t=z; z=y; y=x; x=reg[15]; }}, {id:"Kx≠00", exec:function(){ fin(); if(x!=0) pos=modifReg(0)-1; }}, // hex = 112 {id:"Kx≠01", exec:function(){ fin(); if(x!=0) pos=modifReg(1)-1; }}, {id:"Kx≠02", exec:function(){ fin(); if(x!=0) pos=modifReg(2)-1; }}, {id:"Kx≠03", exec:function(){ fin(); if(x!=0) pos=modifReg(3)-1; }}, {id:"Kx≠04", exec:function(){ fin(); if(x!=0) pos=modifReg(4)-1; }}, {id:"Kx≠05", exec:function(){ fin(); if(x!=0) pos=modifReg(5)-1; }}, {id:"Kx≠06", exec:function(){ fin(); if(x!=0) pos=modifReg(6)-1; }}, {id:"Kx≠07", exec:function(){ fin(); if(x!=0) pos=modifReg(7)-1; }}, {id:"Kx≠08", exec:function(){ fin(); if(x!=0) pos=modifReg(8)-1; }}, {id:"Kx≠09", exec:function(){ fin(); if(x!=0) pos=modifReg(9)-1; }}, {id:"Kx≠0A", exec:function(){ fin(); if(x!=0) pos=modifReg(10)-1; }}, {id:"Kx≠0B", exec:function(){ fin(); if(x!=0) pos=modifReg(11)-1; }}, {id:"Kx≠0C", exec:function(){ fin(); if(x!=0) pos=modifReg(12)-1; }}, {id:"Kx≠0D", exec:function(){ fin(); if(x!=0) pos=modifReg(13)-1; }}, {id:"Kx≠0E", exec:function(){ fin(); if(x!=0) pos=modifReg(14)-1; }}, {id:"Kx≠0F", exec:function(){ fin(); if(x!=0) pos=modifReg(15)-1; }}, {id:"Kgo0", exec:function(){ fin(); pos=modifReg(0)-1; }}, // hex = 128 {id:"Kgo1", exec:function(){ fin(); pos=modifReg(1)-1; }}, {id:"Kgo2", exec:function(){ fin(); pos=modifReg(2)-1; }}, {id:"Kgo3", exec:function(){ fin(); pos=modifReg(3)-1; }}, {id:"Kgo4", exec:function(){ fin(); pos=modifReg(4)-1; }}, {id:"Kgo5", exec:function(){ fin(); pos=modifReg(5)-1; }}, {id:"Kgo6", exec:function(){ fin(); pos=modifReg(6)-1; }}, {id:"Kgo7", exec:function(){ fin(); pos=modifReg(7)-1; }}, {id:"Kgo8", exec:function(){ fin(); pos=modifReg(8)-1; }}, {id:"Kgo9", exec:function(){ fin(); pos=modifReg(9)-1; }}, {id:"KgoA", exec:function(){ fin(); pos=modifReg(10)-1; }}, {id:"KgoB", exec:function(){ fin(); pos=modifReg(11)-1; }}, {id:"KgoC", exec:function(){ fin(); pos=modifReg(12)-1; }}, {id:"KgoD", exec:function(){ fin(); pos=modifReg(13)-1; }}, {id:"KgoE", exec:function(){ fin(); pos=modifReg(14)-1; }}, {id:"KgoF", exec:function(){ fin(); pos=modifReg(15)-1; }}, {id:"Kx≥00", exec:function(){ fin(); if(x>=0) pos=modifReg(0)-1; }}, // hex = 144 {id:"Kx≥01", exec:function(){ fin(); if(x>=0) pos=modifReg(1)-1; }}, {id:"Kx≥02", exec:function(){ fin(); if(x>=0) pos=modifReg(2)-1; }}, {id:"Kx≥03", exec:function(){ fin(); if(x>=0) pos=modifReg(3)-1; }}, {id:"Kx≥04", exec:function(){ fin(); if(x>=0) pos=modifReg(4)-1; }}, {id:"Kx≥05", exec:function(){ fin(); if(x>=0) pos=modifReg(5)-1; }}, {id:"Kx≥06", exec:function(){ fin(); if(x>=0) pos=modifReg(6)-1; }}, {id:"Kx≥07", exec:function(){ fin(); if(x>=0) pos=modifReg(7)-1; }}, {id:"Kx≥08", exec:function(){ fin(); if(x>=0) pos=modifReg(8)-1; }}, {id:"Kx≥09", exec:function(){ fin(); if(x>=0) pos=modifReg(9)-1; }}, {id:"Kx≥0A", exec:function(){ fin(); if(x>=0) pos=modifReg(10)-1; }}, {id:"Kx≥0B", exec:function(){ fin(); if(x>=0) pos=modifReg(11)-1; }}, {id:"Kx≥0C", exec:function(){ fin(); if(x>=0) pos=modifReg(12)-1; }}, {id:"Kx≥0D", exec:function(){ fin(); if(x>=0) pos=modifReg(13)-1; }}, {id:"Kx≥0E", exec:function(){ fin(); if(x>=0) pos=modifReg(14)-1; }}, {id:"Kx≥0F", exec:function(){ fin(); if(x>=0) pos=modifReg(15)-1; }}, {id:"Ksub0", exec:function(){ fin(); ret.push(pos); pos=modifReg(0)-1; }}, // hex = 160 {id:"Ksub1", exec:function(){ fin(); ret.push(pos); pos=modifReg(1)-1; }}, {id:"Ksub2", exec:function(){ fin(); ret.push(pos); pos=modifReg(2)-1; }}, {id:"Ksub3", exec:function(){ fin(); ret.push(pos); pos=modifReg(3)-1; }}, {id:"Ksub4", exec:function(){ fin(); ret.push(pos); pos=modifReg(4)-1; }}, {id:"Ksub5", exec:function(){ fin(); ret.push(pos); pos=modifReg(5)-1; }}, {id:"Ksub6", exec:function(){ fin(); ret.push(pos); pos=modifReg(6)-1; }}, {id:"Ksub7", exec:function(){ fin(); ret.push(pos); pos=modifReg(7)-1; }}, {id:"Ksub8", exec:function(){ fin(); ret.push(pos); pos=modifReg(8)-1; }}, {id:"Ksub9", exec:function(){ fin(); ret.push(pos); pos=modifReg(9)-1; }}, {id:"KsubA", exec:function(){ fin(); ret.push(pos); pos=modifReg(10)-1; }}, {id:"KsubB", exec:function(){ fin(); ret.push(pos); pos=modifReg(11)-1; }}, {id:"KsubC", exec:function(){ fin(); ret.push(pos); pos=modifReg(12)-1; }}, {id:"KsubD", exec:function(){ fin(); ret.push(pos); pos=modifReg(13)-1; }}, {id:"KsubE", exec:function(){ fin(); ret.push(pos); pos=modifReg(14)-1; }}, {id:"KsubF", exec:function(){ fin(); ret.push(pos); pos=modifReg(15)-1; }}, {id:"KMS0", exec:function(){ fin(); var r=modifReg(0)%16; if(r<0) r+=16; reg[r]=x; }}, // hex = 176 {id:"KMS1", exec:function(){ fin(); var r=modifReg(1)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS2", exec:function(){ fin(); var r=modifReg(2)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS3", exec:function(){ fin(); var r=modifReg(3)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS4", exec:function(){ fin(); var r=modifReg(4)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS5", exec:function(){ fin(); var r=modifReg(5)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS6", exec:function(){ fin(); var r=modifReg(6)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS7", exec:function(){ fin(); var r=modifReg(7)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS8", exec:function(){ fin(); var r=modifReg(8)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMS9", exec:function(){ fin(); var r=modifReg(9)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMSA", exec:function(){ fin(); var r=modifReg(10)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMSB", exec:function(){ fin(); var r=modifReg(11)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMSC", exec:function(){ fin(); var r=modifReg(12)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMSD", exec:function(){ fin(); var r=modifReg(13)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMSE", exec:function(){ fin(); var r=modifReg(14)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"KMSF", exec:function(){ fin(); var r=modifReg(15)%16; if(r<0) r+=16; reg[r]=x; }}, {id:"Kx<00", exec:function(){ fin(); if(x<0) pos=modifReg(0)-1; }}, // hex = 192 {id:"Kx<01", exec:function(){ fin(); if(x<0) pos=modifReg(1)-1; }}, {id:"Kx<02", exec:function(){ fin(); if(x<0) pos=modifReg(2)-1; }}, {id:"Kx<03", exec:function(){ fin(); if(x<0) pos=modifReg(3)-1; }}, {id:"Kx<04", exec:function(){ fin(); if(x<0) pos=modifReg(4)-1; }}, {id:"Kx<05", exec:function(){ fin(); if(x<0) pos=modifReg(5)-1; }}, {id:"Kx<06", exec:function(){ fin(); if(x<0) pos=modifReg(6)-1; }}, {id:"Kx<07", exec:function(){ fin(); if(x<0) pos=modifReg(7)-1; }}, {id:"Kx<08", exec:function(){ fin(); if(x<0) pos=modifReg(8)-1; }}, {id:"Kx<09", exec:function(){ fin(); if(x<0) pos=modifReg(9)-1; }}, {id:"Kx<0A", exec:function(){ fin(); if(x<0) pos=modifReg(10)-1; }}, {id:"Kx<0B", exec:function(){ fin(); if(x<0) pos=modifReg(11)-1; }}, {id:"Kx<0C", exec:function(){ fin(); if(x<0) pos=modifReg(12)-1; }}, {id:"Kx<0D", exec:function(){ fin(); if(x<0) pos=modifReg(13)-1; }}, {id:"Kx<0E", exec:function(){ fin(); if(x<0) pos=modifReg(14)-1; }}, {id:"Kx<0F", exec:function(){ fin(); if(x<0) pos=modifReg(15)-1; }}, {id:"KMR0", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(0)%16; if(r<0) r+=16; x=reg[r]; }}, // hex = 208 {id:"KMR1", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(1)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR2", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(2)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR3", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(3)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR4", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(4)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR5", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(5)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR6", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(6)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR7", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(7)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR8", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(8)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMR9", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(9)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMRA", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(10)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMRB", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(11)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMRC", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(12)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMRD", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(13)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMRE", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(14)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"KMRF", exec:function(){ fin(); t=z; z=y; y=x; var r=modifReg(15)%16; if(r<0) r+=16; x=reg[r]; }}, {id:"Kx=00", exec:function(){ fin(); if(x==0) pos=modifReg(0)-1; }}, // hex = 224 {id:"Kx=01", exec:function(){ fin(); if(x==0) pos=modifReg(1)-1; }}, {id:"Kx=02", exec:function(){ fin(); if(x==0) pos=modifReg(2)-1; }}, {id:"Kx=03", exec:function(){ fin(); if(x==0) pos=modifReg(3)-1; }}, {id:"Kx=04", exec:function(){ fin(); if(x==0) pos=modifReg(4)-1; }}, {id:"Kx=05", exec:function(){ fin(); if(x==0) pos=modifReg(5)-1; }}, {id:"Kx=06", exec:function(){ fin(); if(x==0) pos=modifReg(6)-1; }}, {id:"Kx=07", exec:function(){ fin(); if(x==0) pos=modifReg(7)-1; }}, {id:"Kx=08", exec:function(){ fin(); if(x==0) pos=modifReg(8)-1; }}, {id:"Kx=09", exec:function(){ fin(); if(x==0) pos=modifReg(9)-1; }}, {id:"Kx=0A", exec:function(){ fin(); if(x==0) pos=modifReg(10)-1; }}, {id:"Kx=0B", exec:function(){ fin(); if(x==0) pos=modifReg(11)-1; }}, {id:"Kx=0C", exec:function(){ fin(); if(x==0) pos=modifReg(12)-1; }}, {id:"Kx=0D", exec:function(){ fin(); if(x==0) pos=modifReg(13)-1; }}, {id:"Kx=0E", exec:function(){ fin(); if(x==0) pos=modifReg(14)-1; }}, {id:"Kx=0F", exec:function(){ fin(); if(x==0) pos=modifReg(15)-1; }}, {id:"M+0", exec:function(){ fin(); reg[0]+=x; }}, // hex = 240 {id:"M+1", exec:function(){ fin(); reg[1]+=x; }}, {id:"M+2", exec:function(){ fin(); reg[2]+=x; }}, {id:"M+3", exec:function(){ fin(); reg[3]+=x; }}, {id:"M+4", exec:function(){ fin(); reg[4]+=x; }}, {id:"M+5", exec:function(){ fin(); reg[5]+=x; }}, {id:"M+6", exec:function(){ fin(); reg[6]+=x; }}, {id:"M+7", exec:function(){ fin(); reg[7]+=x; }}, {id:"M+8", exec:function(){ fin(); reg[8]+=x; }}, {id:"M+9", exec:function(){ fin(); reg[9]+=x; }}, {id:"M+A", exec:function(){ fin(); reg[10]+=x; }}, {id:"M+B", exec:function(){ fin(); reg[11]+=x; }}, {id:"M+C", exec:function(){ fin(); reg[12]+=x; }}, {id:"M+D", exec:function(){ fin(); reg[13]+=x; }}, {id:"M+E", exec:function(){ fin(); reg[14]+=x; }}, {id:"M+F", exec:function(){ fin(); reg[15]+=x; }}]; var keyR = [-3,-3,-3,-3,-3,-3, 0x7,0x8,0x9,0xf,-3,-3, 0x4,0x5,0x6,0xe,-3,-3, 0x1,0x2,0x3,0xd,-3,-3, 0x0,0xa,0xb,0xc,-3,0xff]; var keyN = [-1,-2,-0x60,-0x40,-0xf0,0x22, 0x07,0x08,0x09,0x11,0x12,0x23, 0x04,0x05,0x06,0x10,0x13,0x24, 0x01,0x02,0x03,0x14,0x0e,0x0f, 0x00,0x0a,0x0b,0x0c,0x26,0x0d]; var keyF = [-1,-2,0x5d,0x5b,0x58,0x5a, 0x51,0x53,0x5c,0x5e,0x59,0x57, 0x50,0x52,0x37,0x38,0x39,0x3a, 0x1c,0x1d,0x1e,0x16,0x15,0x20, 0x19,0x1a,0x1b,0x18,0x17,0x21]; var keyK = [-1,-2,-0xd0,-0xb0,0x5f,0x25, -0x80,-0xa0,-0xc0,-0xe0,-0x90,-0x70, 0x35,0x34,0x31,0x55,0x56,0x2a, 0x27,0x28,0x29,0x1f,0x2f,0x2b, 0x2c,0x2d,0x2e,0x32,0x3b,0x36]; var keyFK = [-1,-2,-3,-3,-3,0x54, -3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3, 0x3c,0x3d,0x3e,0x3f,0x30,0x33]; var keyCur = keyN; var needR = 0; function degree(kind) { if(kind==0) { document.getElementById("degR").checked=true; document.getElementById("degG").checked=false; document.getElementById("degD").checked=false; degF=1; } if(kind==1) { document.getElementById("degR").checked=false; document.getElementById("degG").checked=true; document.getElementById("degD").checked=false; degF=Math.PI/200; } if(kind==2) { document.getElementById("degR").checked=false; document.getElementById("degG").checked=false; document.getElementById("degD").checked=true; degF=Math.PI/180; } } function save() { localStorage.setItem("regMK61",reg); localStorage.setItem("progMK61",prog); localStorage.setItem("descMK61",desc); } function toArray(str) { return str.split(",").map(function(item){return parseInt(item,10);}); } function init() { if (localStorage.regMK61) reg = toArray(localStorage.regMK61); else localStorage.regMK61 = reg; if (localStorage.progMK61) prog = toArray(localStorage.progMK61); else localStorage.progMK61 = prog; if (localStorage.descMK61) desc = localStorage.descMK61; else localStorage.descMK61 = desc; degree(0); updateKeys(); } function updateProg() { // if(prgON) { var tbl = ""; for(var i=0;i<10;i++) tbl += ""+i+""; tbl += ""; for(var i=0;i"; tbl += "#"+Math.floor(prog[i]/10).toString(16)+prog[i]%10+"]"; if(i%10==9) tbl += ""; } document.getElementById("prog").innerHTML = tbl+""; } } function updateRegs() { if(num=="") document.getElementById("regX").value = x; else document.getElementById("regX").value = num; document.getElementById("regY").value = y; document.getElementById("regZ").value = z; document.getElementById("regT").value = t; document.getElementById("reg").innerHTML = "

Bx = "+b+"

Registers: "+reg+"

"; //"

Return stack:"+ret+"

pos = "+pos+"

"; } function updateKeys() { document.getElementById("prg").checked=prgON; if(needR!=0) { // if(needR<0) // document.getElementById("status").innerHTML = "Enter register"; // else if(needR>=0x200) // document.getElementById("status").innerHTML = "Enter first digit of address"; // else // document.getElementById("status").innerHTML = "Enter second digit of address"; keyCur = keyR; } else if(pressF==0 && pressK==0) keyCur = keyN; else if(pressF==1 && pressK==0) keyCur = keyF; else if(pressF==0 && pressK==1) keyCur = keyK; else if(pressF==1 && pressK==1) keyCur = keyFK; // if(needR==0) document.getElementById("status").innerHTML = ""; for(var i=0;i<30;i++) { var but = document.getElementById("button"+i); var stl = "color:#000;background:#f9f9f9"; var key = keyCur[i]; but.disabled = false; if(key==-3) { but.disabled = true; but.innerHTML=""; } else if(key==-1) { but.innerHTML = "F"; stl = pressF>0?"color:#850;background:#fc8":"color:#fa0;background:#f9f9f9"; } else if(key==-2) { but.innerHTML = "K"; stl = pressK>0?"color:#008;background:#88f":"color:#00f;background:#f9f9f9"; } else if(needR!=0) { if(key<16) but.innerHTML = key.toString(16).toUpperCase(); else { stl = "color:#f00;background:#f9f9f9"; but.innerHTML = "×"; } } else if(key<0) { stl = "color:#f0f;background:#f9f9f9"; but.innerHTML = cmds[-key].id.slice(0,-1); } else { const grph = [48,60,61,62,63,51]; const exeC = [81,83,87,88,89,90,91,92,93,94]; if(grph.includes(key)) stl = "color:#0d0;background:#f9f9f9"; if(exeC.includes(key)) stl = "color:#880;background:#f9f9f9"; if(key==0x0d) stl = "color:#F00;background:#f9f9f9"; but.innerHTML = cmds[key].id; } but.style = "width:55px;height:55px;border-radius:10px;font-size:15pt;padding:0px;"+stl; } updateRegs(); updateProg(); } function handleKey(key) { const exeC = [81,83,87,88,89,90,91,92,93,94]; if(prgON) { if(pos<0 || pos>=160) pos = 0; if(pos>prog.length) pos=prog.length; prog[pos] = key; pos++; if(exeC.includes(key)) { needR = 0x200; updateKeys(); } } else if(!prgON) if(!exeC.includes(key)) { var bb = x; cmds[key].exec(); if(num=="") b = bb; } if(pressF!=0 || pressK!=0) { pressF = pressK = 0; updateKeys(); } updateRegs(); updateProg(); } function press(but) { var key = keyCur[but]; if(key==-3) return; // nothing to do else if(key==-1) // key F { pressF = 1-pressF; updateKeys(); } else if(key==-2) // key K { pressK = 1-pressK; updateKeys(); } else if(key<0) // need RegId { needR = key; updateKeys(); } else if(needR>0) // input RegId { // use "nop" for prev cmd if canceled if(key>16) { pos--; prog[pos]=84; needR=0; updateKeys(); } else if(needR>=0x200) { needR+=key-0x100; } else // NOTE: for compatibility reason the pseudo-hex notation is used!!! { prog[pos] = 10*(needR%16)+key; pos++; needR=0; updateKeys(); } } else if(needR<0) // input RegId { if(key<16) key -= needR; needR=0; updateKeys(); handleKey(key); } else handleKey(key); } function stopRun() { document.getElementById("butRun").innerHTML = "Run"; stop=false; if(interval) clearInterval(interval); interval=0; } function posDec() { pos--; if(pos<0) pos = prog.length-1; updateProg(); } function posInc() { pos++; if(pos>prog.length) pos = 0; updateProg(); } function posUp() { pos-=10; if(pos<0) pos = 0; updateProg(); } function posDwn() { pos+=10; if(pos>prog.length) pos = prog.length-1; updateProg(); } function posDel() { if(pos>=0 && pos0) prog.pop(); updateProg(); } function posIns() { if(pos>=0 && pos=prog.length) pos=0; stop = false; interval = setInterval(step, 20); document.getElementById("butRun").innerHTML = "Stop"; } function step() { if(pos<0 || pos>=prog.length || stop || x-x!=0) { stopRun(); return; } var kod = prog[pos], opt = pos+1=160) pos=0; updateRegs(); updateProg(); } function modifReg(rr) { if(rr<8) reg[rr] += (rr<4) ? -1:1; reg[rr] = Math.floor(reg[rr]); return reg[rr]; } function fact(x) { var r = Math.exp(lgamma(x+1)); // this is good but approximate result if(x==Math.floor(x)) r = Math.floor(r+0.5); return r; } function lgamma(x) { const cof=[76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5]; var tmp = x+5.5 - (x+0.5)*Math.log(x+5.5); var ser = 1.000000000190015; for(var j=0;j<=5;j++) ser += cof[j]/(x+j+1); return Math.log(2.5066282746310005*ser/x) -tmp; } function erf(x) // интеграл вероятности с точностью 1.5*10^-7 !!! { var s=1; if(x<0) { s = -1; x = -x; } var t=1/(1+0.32759*x); var res=0.254829592*t; res -= 0.284496736*t*t; res += 1.42413741*t*t*t; res -= 1.453152027*Math.pow(t,4); res += 1.061405429*Math.pow(t,5); res *= Math.exp(-x*x); return s*(1-res); } function BesselJ0(x) { var ax,z,xx,y,ans,ans1,ans2; ax = Math.abs(x); if (ax < 8.0) { y = x*x; ans1 = 57568490574.0+y*(-13362590354.0+y*(651619640.7+y*(-11214424.18+y*(77392.33017+y*(-184.9052456))))); ans2 = 57568490411.0+y*(1029532985.0+y*(9494680.718+y*(59272.64853+y*(267.8532712+y*1.0)))); ans = ans1/ans2; } else { z = 8.0/ax; y = z*z; xx = ax-0.785398164; ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4+y*(-0.2073370639e-5+y*0.2093887211e-6))); ans2 = -0.1562499995e-1+y*(0.1430488765e-3+y*(-0.6911147651e-5+y*(0.7621095161e-6 - y*0.934935152e-7))); ans = Math.sqrt(0.636619772 / ax)*(Math.cos(xx)*ans1 - z*Math.sin(xx)*ans2); } return ans; } function BesselJ1(x) { var ax,z,xx,y,ans,ans1,ans2; ax = Math.abs(x); if (ax < 8.0) { y=x*x; ans1 = x*(72362614232.0+y*(-7895059235.0+y*(242396853.1+y*(-2972611.439+y*(15704.48260+y*(-30.16036606)))))); ans2 = 144725228442.0+y*(2300535178.0+y*(18583304.74+y*(99447.43394+y*(376.9991397+y*1.0)))); ans = ans1/ans2; } else { z=8.0/ax; y=z*z; xx=ax-2.356194491; ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4+y*(0.2457520174e-5+y*(-0.240337019e-6)))); ans2=0.04687499995+y*(-0.2002690873e-3+y*(0.8449199096e-5+y*(-0.88228987e-6+y*0.105787412e-6))); ans=Math.sqrt(0.636619772/ax)*(Math.cos(xx)*ans1-z*Math.sin(xx)*ans2); if (x < 0.0) ans = -ans; } return ans; } function BesselY0(x) { var z, xx, y, ans, ans1, ans2; if (x < 8.0) { y=x*x; ans1 = -2957821389.0+y*(7062834065.0+y*(-512359803.6+y*(10879881.29+y*(-86327.92757+y*228.4622733)))); ans2 = 40076544269.0+y*(745249964.8+y*(7189466.438+y*(47447.26470+y*(226.1030244+y*1.0)))); ans = (ans1/ans2)+0.636619772*BesselJ0(x)*Math.log(x); } else { z=8.0/x; y=z*z; xx=x-0.785398164; ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4+y*(-0.2073370639e-5+y*0.2093887211e-6))); ans2 = -0.1562499995e-1+y*(0.1430488765e-3+y*(-0.6911147651e-5+y*(0.7621095161e-6+y*(-0.934945152e-7)))); ans = Math.sqrt(0.636619772/x)*(Math.sin(xx)+ans1+z*Math.cos(xx)*ans2); } return ans; } function BesselY1(x) { var z, xx, y, ans, ans1, ans2; if (x < 8.0) { y=x*x ans1 = x*(-0.4900604943e13+y*(0.1275274390e13+y*(-0.5153438139e11+y*(0.7349264551e9+y*(-0.4237922726e7+y*0.8511937935e4))))); ans2 = 0.2499580570e14+y*(0.4244419664e12+y*(0.3733650367e10+y*(0.2245904002e8+y*(0.1020426050e6+y*(0.3549632885e3+y))))); ans = (ans1/ans2)+0.636619772*(BesselJ1(x)*Math.log(x)-1.0/x); } else { z=8.0/x; y=z*z; xx=x-2.356194491; ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4+y*(0.2457520174e-5+y*(-0.240337019e-6)))); ans2=0.04687499995+y*(-0.202690873e-3+y*(0.8449199096e-5+y*(-0.88228987e-6+y*0.10578e-6))); ans=Math.sqrt(0.636619772/x)*(Math.sin(xx)*ans1+z*Math.cos(xx)*ans2); } return ans; } mathgl-2.4.4/website/json/0000755000175000017500000000000013513030041015560 5ustar alastairalastairmathgl-2.4.4/website/json/json.html0000644000175000017500000001120113513030041017412 0ustar alastairalastair Example of dysplaying MathGL plots using JSON
Select sample

You can use mouse with pressed left button for rotation; with pressed middle button for shift; mouse wheel for zoom in/out. Double click will restore original view.

mathgl-2.4.4/website/json/mgl_cgi.html0000644000175000017500000000150713513030041020052 0ustar alastairalastair MGL script preview (SVG)

Enter script below



mathgl-2.4.4/website/json/mathgl.js0000644000175000017500000004045413513030041017401 0ustar alastairalastair/*************************************************************************** * mathgl.js is part of Math Graphic Library * Copyright (C) 2012 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ var obj; var ctx; var cw,ch; var deg = Math.PI/180; //0.017453293; function main() { ctx = document.getElementById("canvas").getContext("2d"); cw = document.getElementById("canvas").width; ch = document.getElementById("canvas").height; ctx.lineCap="round"; // global setting mgl_init("alpha.json"); // mgl_init("alpha.jsonz"); var t1 = new Date(); mgl_draw_good(obj, ctx); // draw_fast(obj, ctx); var t2 = new Date(); document.getElementById("time").innerHTML = "Drawing time is "+(t2.getTime()-t1.getTime())+" ms. Number of primitives is "+obj.nprim+". Canvas size is "+obj.width+"*"+obj.height+" points."; }; function mglChange() { var name = document.getElementById("select").value; mgl_init(name+".json"); var t1 = new Date(); ctx.clearRect(0,0,cw,ch); mgl_draw_good(obj, ctx); // draw_fast(obj, ctx); var t2 = new Date(); document.getElementById("time").innerHTML = "Drawing time is "+(t2.getTime()-t1.getTime())+" ms. Number of primitives is "+obj.nprim; } // mouse handling functions function mglMouseUp() { obj.button = 0; obj.good = 0; ctx.clearRect(0,0,cw,ch); mgl_draw_good(obj, ctx); } function mglMouseDown(event) { obj.good = 1; obj.mouseX = event.clientX; obj.mouseY = event.clientY; obj.button = event.button+1; } function mglMouseMove(event) { var x = event.clientX-obj.mouseX; var y = event.clientY-obj.mouseY; switch(obj.button) { case 1: // rotate mgl_rotate_down(obj, y*180/ch); mgl_rotate_left(obj, x*180/cw); break; case 2: // shift mgl_shift_down(obj, y/ch); mgl_shift_right(obj, x/cw); break; case 3: // zoom mgl_zoom_in(obj, Math.pow(1.003,x)); break; } if(obj.button) { obj.mouseX += x; obj.mouseY += y; mgl_draw(obj, ctx); } } function mglMouseWheel(event) { // var e = window.event; var d = event.wheelDelta? event.wheelDelta:event.detail*(-120); mgl_zoom_in(obj, Math.pow(1.002,d)); mgl_draw(obj, ctx); } function mglRestore() { mgl_restore(obj); ctx.clearRect(0,0,cw,ch); mgl_draw_good(obj,ctx); } // The function load data and set up rotation/zoom state function mgl_init(name) { // now obtain JSON data var req = new XMLHttpRequest(), txt; req.open( "GET", name, false ); req.overrideMimeType('text\/plain; charset=x-user-defined'); req.send(null); txt = req.responseText; obj = JSON.parse(txt); // copy original data for transformation obj.pp = new Array(); for(var i=0;iMath.PI/2) t += Math.PI; } else t=0; var c=Math.cos(t), s=Math.sin(t), d=prim[6]/200; var b=[d*c, d*s, d*s, -d*c, obj.pp[n1][0],obj.pp[n1][1]]; var x=obj.coor[n2][0]*scl/100, y=obj.coor[n2][1]*scl/100, f=prim[8]*scl/1e5; if(n3&8) { if(!(n3&4)) mgl_line_glyph(ctx, x,y, f,1,b); else mgl_line_glyph(ctx, x,y, f,0,b); } else { if(!(n3&4)) mgl_fill_glyph(ctx, x,y, f,obj.glfs[n4],b); else mgl_wire_glyph(ctx, x,y, f,obj.glfs[n4],b); } break; } } // This function change coordinates according current transformations // Usually this Function is called internally by draw() function mgl_prepare(obj, skip) { // fill transformation matrix if(!skip) { var dx = 1/Math.abs(obj.z[1]-obj.z[0]); var dy = 1/Math.abs(obj.z[3]-obj.z[2]); var cx=Math.cos(obj.tet*deg), sx=Math.sin(obj.tet*deg); // tetx var cy=Math.cos(obj.phi*deg), sy=Math.sin(obj.phi*deg); // tety var cz=Math.cos(obj.bet*deg), sz=Math.sin(obj.bet*deg); // tetz obj.b = [obj.dx*dx*cx*cy, -obj.dx*dx*cy*sx, obj.dx*dx*sy, obj.dy*dy*(cx*sy*sz+cz*sx), obj.dy*dy*(cx*cz-sx*sy*sz), -obj.dy*dy*cy*sz, sx*sz-cx*cz*sy, cx*sz+cz*sx*sy, cy*cz, cw/2*(1+dx-obj.z[1]-obj.z[0])/dx, ch/2*(1+dy-obj.z[3]-obj.z[2])/dy, obj.depth/2, obj.dx*dx,obj.dy*dy,1]; } // now transform points for found transformation matrix var b = obj.b, i; for(i=0;i=0) // TODO: check later when mglInPlot will be ready obj.pp[i] = [b[9] + b[0]*x + b[1]*y + b[2]*z, b[10] + b[3]*x + b[4]*y + b[5]*z, b[11] + b[6]*x + b[7]*y + b[8]*z]; else obj.pp[i] = [b[9]+b[12]*x,b[10]+b[13]*y,b[11]+b[14]*z]; } if(obj.pf) for(var i=0;i=0) // TODO: check later when mglInPlot will be ready { obj.pp[i][0] = d*obj.pp[i][0] + (1-d)/2*obj.width; obj.pp[i][1] = d*obj.pp[i][1] + (1-d)/2*obj.height; } } // fill z-coordinates for primitives if(!obj.fast) { for(i=0;i' ctx.moveTo(x-s/2,y-s); ctx.lineTo(x-s/2,y+s); ctx.lineTo(x+s,y); ctx.closePath(); ctx.stroke(); break; // case 46: // '.' default: ctx.rect(x,y,1,1); ctx.fill(); break; } } // This function for internal use only!!! function mgl_fill_glyph(ctx, x,y, f,g,b) { var xx,yy,j; var np=0; ctx.beginPath(); for(j=0;j Homepage of MathGL

MathGL

14 March 2018. New version (v.2.4.3) of MathGL is released. There are new clabel command for drawing colorbar labels, EPS output now may have mask, compatibility changes for complex numbers, and many other improvements.

Games

mathgl-2.4.4/website/udav/0000755000175000017500000000000013513030041015546 5ustar alastairalastairmathgl-2.4.4/website/udav/udav_data.png0000644000175000017500000017201413513030041020211 0ustar alastairalastairPNG  IHDR:sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxw|e${ADS,(wb; `NJS Bz!&[gM$$! E}Ivg}gf3; LbRhZŷB!Bq Vx^J|4oYp*X !B!ZEq=,+P4oOǠ, V!B!Ur)Fg=#@PD=:hu]GuEAQ B!BTp*s˳l$Sκ( _#"#CQ<(4 NAa!nMl ƭbd.!B!'q*s˳l+n"##ZݘR0)V8QbՁ^T++95+fE͔F\.6ZnE1(G1 } d2UBq98 JuB!NenyaR!ϥ`h 4T1CϯQRvP_Wܞ(<4-PkI^~{h2p:A^ PգsX8֭%*2B!١+]Qf3hтa^HϞ=*-رcfn7F?EDD'd^|q* ۟;yh٢:BqZRvƣi'uTՎєٜŒźɳϒx3f#M٨jqx̠Cbt8N{q1:#3 !{'~ffQ<Ӽ[.xRn7!!!n,]{k`ѢEׯ:nBST斧\oevfgU6zEqc0c4f`2lNh̤c7q8躊u3^e D׫d^\T.BDd4DB!JeggɧeKyyyҹS'FDr?0EQW^#]|liܸ7d~gl6-[s4)}s8JkR]*к,[ϿL3rM\M޾EQ )S(.*iۮ-C?߷,XEQxyt? ѣQbXXl9|3u Y|9Vv:DSBTՕuv:v8ǨmOOjPy'0 Ό3AfjerjGMMYL,Y;!9>71[d>ɔє8mid06{q!N?"qqdˤ{B!N+Xx z[1pp>r/ uN,X?6oI<'zÇ`dO?|*Zj䧞fɒ%5juMJ˯La8~]> (֙:#XrlْDJJ }}6ۏ#Gq3lpN'K-+ҥKq: 6S B-*-G^^^|=w[V~w+~~@ykee?ٳz" +W`SOUv5 8Q 6 | \49Dֻ;̋/b9 x(/l6c/r:Z JA~\/}{(c|喻u8 Ο2p@?֯_By?rHh!73.;( {;a~堸0{zx<&O_rꋯs,/YnYYً-bᬏHH۶mA_*ۙ$$$zof͛r`"/QPj]ॗ^bˤ']~K]&~̵w1>NN{Zع ~(t݊hd%5(};mn/.HKMddf{tg֬I=zrʾ~XiҘtp40~.>cu|W4lPϿ2s;~}3u4irӫW yc"33,_WwoL&~8ݻvd%IIIԯ_+wgpVxw!_/[Fѽ /ąCUiPU"9z6ҩSG U|xD$ob !g{D>c^Ml6ьJN <=i23fJTT$nφ W_s<;#GРA / ZVX7yy駱lDFFҭ[7ЩE2}:3Mhܸ17S&a8'G^|1O(**"886m+׷YuhL&QQQ$$&އҥsgҏ/KpUrrKXf5]vKXx1.q n̞/EN5+?ƟT歕=`䓑 @zZ*.C'3#e+WCW3Zx1V2}Aa1o](&M4ss.t͊/KFKRQ{&Ъhԣl߾p:tr<ٌlf˖-HLL >.F !g  !2!!YilkPnLy//}nر5}+WU>fMVfyՖe ^CPUMF^NEZի#"шduFhΨr $2*Ŋj0y<8vrs;i* brsދoҔpR&NWxD$qP蜦eRIaI !=2AC =x@Qܨj!Zzϒ cђBgaaf<ܥM%y>iѲ%8,V iKN&2<-[(>NfBqV*MO,u+iӦgd3ٲe ϽtBPvF3'M ƣPFt݄<(?En>ir`2h(`iҺU+bcc( !uo|LBb"o| 8B! Nen)d~W]Buثa)%+**nv1XV1 !gSq9AtXVt]^\Lnv\./Tgs. Tcl]~`[Q&2B鯒ؗ*?FA3] !N/$B!BIB!B@t5B!BҜ^FB!BIB!B4$B!B!߀7)Mk-SJ}6+95i߹U'B!g[rP]}v$m@׭i||ÏݻbztڅC^,_O>ǟ~"%(fݻqЧwS}zUWzۄB!cPP϶d.sx@Qi׶-fL6n[39+a>Ӹ\.^}7nDڵxwJklhB!BBQ݃_He˸ʫңFdx 6b$`Q|rֿKj/dfЭkW11|1a$v ?Aןoܼr|lEn=6b$0z.jŀУW.[W_K8p|C{etޓ1W]/j;,\+x-c6b mҺUuqTSm筦ǏB!u&۸i3?Z{3fƍ|0k֬᭙O<=i~˖H[n˖/O>fM{Xh!.aL gVnw?g&OU+xɼ[^[ey=|>֬XƷ|iLy~juXb%y˘{۰}}ݺ?5Lz1/\X6V~۟\2';*5ݧ'F˖?gnɓy'Nն@>o59~B!g/YjF Oj>^{|wD:$&KKO[1ޏV߿x|Ӎ 4%K=VZ纼[j&twm6U.SXhcԥu|gF:ua}verrrKYbo6_{Ít \x֡g6lx6c<9)zI]С;v?U㩦W'F7t | :׷˹?}圪ms+IUlɎ!B!ǭ9糵>T~rU Ȯ]끒Iu]Qպd}ѭ[z^gSՃ noѼyMe/aFrrs%@m{|rUoB!BAG;ii?1=K.=]*զukoXu7T4 ou}!B!N/,=Bo}qv6oI''1tU"ǏB!Mn]/C>}$mS<>r8rn3]-!B!?\/B!BExp/B!B(rB!B7`u}FfB!B!j*:&w=~Ivs#*/UPMB!٨oLFE9~+<5Bq_]wZ!Bb=>&Od6}!8TPwZ!⟭L'B!B x|yBB!BTB!B7MKB!B!_7|!B!o| _!B!K{B!BIB!B㙮BSg撑^'4lHtt4 W!gpZFJS7/Wې訳|e}vPTFWrrvlNBbB!=܄pOH\{⪪s Ӹgm'Ίٹs'۷Prssx%hV8͕иB!8{Ni+qOIܼ\uuL|"ǀsy?T?xk6s箓7/{~e=e/ַ/+N*ƭK/`m߇*}7_'a qqu[̬_vyyDXhƨ~1<.ſ ,\B!?eo_MQPë@QWAEU) GX֓Gfu`$#;q 5`J\Έ>9fvvM۶mkTv]?@?I"( {&::N5|uNqq1YQFU[ƭ2߬Mp*:;v$11MQUUUQϬY`HOxv )SK `<ݻN+똝)4 !~)9^OO(;_We_J3gS醟700!za $n]5KMC;.zmk#vHx?ঐ;sk[ d[ꡇO:ս;q@M[S͗×nCpٓ=A7_@܃zќ7?9y*:{S/*BڵM&qײf_-z4(;Yasl*NVH"S|-^IütR򇍣W9+iߢ!G3~v.7vD1k3zq^`f/-[KAB!yQ\uKDٰAk9oPL0{;Zr?AIi4طopwh;&`6lXC<߉4kAd,|r7o.][8L Y ƣ?Đ!CۧO~zUJ:5.dqKc TU ?7vRr~I$?i,ƏFb5?^Z=c-1ujƍ '$$Mn؁2&*2=;hvN1ƼIi\7+.{[,+>˻;:1(ZK&2.]p{o<=fM&0{c/;YB`n]Ig; !~GEc r7bnέo[?ng礡%28N£xq\ykt&RmDtX5lFnn. QcXj$= *i$mDZ6 +,o_UQ 6mѣ+]oذa~`Ѐ꺎{m7򗓓CRRolO|ͶiӆAޓ8VвYAArspkA/Ku>~>q۷- 3])cEs+£hlݗ^ɱ]ii)W3&p ݺ&i"#T^fun%9ig"q5ª& R}쿌{U6n]!и:v`…kMl2t)h!ё؎af+Wq0lܱ=s\·yk[;M 8v`m[ hysi!AovVn=1[ =΂u~xG5 ƠTB!8ygO 1رkfra.Liz8I{mQ둞Bi=t9(ގہq,X˅d4Zuk&q՗avqa*eX>#7 i){O{`vhݨV V͙\t[RoUUI~I_:_+-\Ġ%@i| &paaa%~i; @99"o|DnA6ё- &  .Ub")g?D`.9fJQwbekˉax̌3x1{#xǘ1c_~e@epwБ:t9oh<0("7nh# 5}%w]ځs;5<^é$ouqk\.B ,ްͻ1X}{kvgd6оQ8umTuM4ߓMtMPK/9.f|o2EJ~d`ٸ*^~_٭>Oq^w-?(ڥ3rӻWO&iۈX˶[q ׮_t˽A" pHaLlվ͘w8!hԪMJ̹2ֿu[I?fg(vx0G![wJؽ{ p847A͊g&\On܍?:S/ I^xEQ0*Gf_korʳZ뎣DEEr5q.;nR<@MyelԜ{@;RÇ 25~ u2Tc|6 4p׺T6n>I~i^^x\y.bl2,(lF3{MGfvD WcV fDb0`TG}$OߎoJq&0R塰ή]x:yvoƔ)Sʽ6rHO^O%-W*~ő\A F*!<:nӍti?rŰ{e' Ji cdges*KVnǯIl8߶pn+.uI5~>g]kM[ٸDxۭ~(+n7(h%W#NtT8.{>u{]*z0p8+c` 4 1.`c9֘=x{<BҲ^-> Gh,B;. ~APh'rP *\l[X& q{%mP܌ 39(gYbGt֯c] IlXU! qp*t0vPs.;111$uh*J~wcSn'Oߞo>io@B_Q7Ta/]7neGJm60*\EP,иi9`23w^T6lHC U5a21M:vYyj'cf+  f` .Ivn))deyд4> #-gƟ jV\ F+~uSro$T`6kˍ\3(*,P<[|7F妨NAA+EUAA/Weֲ$/@F࿘:k17's@"뛉fBQ4ܘ̦wUWz7&i49)Qфd`2PUGQX0Mx\ VGԌTb!:UE7. vGW1M&^puk`00- 5]h`6[0*h÷#<4.eI`0r%]v ʟӼO(YF 6[.T?X\9M%>~={Al\#;pσEcZ;^qCr:ЂucmX?)cp>h,lVp{s(*$0:3#b=NL[u @&cTuB!*w$oZD6&/NpvMyLeʣ *V;3ݾ.<]q%5{)k5[r'|~+~:ѣG~F.p TWT藔hܲe *Vam ʮm{=I VESS!-:gj~mE("`PTμҴA0/{}[R}xk4g+{ ـW\!B=wٻ B‚hn ' -frَ}DXɮzn@:͢_A`1)OIґ{uoNJu6oތ*Xr奢)&X[zO,='eЈësd&F4ωhzBOg\=&RKߌFG F7oADU%==IdEeMbx[0U؝A8N mE&]w:ntD0oO[ΫHحAV ʟIO([}2o<kͣ_~w?~I',+Yt+eݲy7]vze>}+3?sh0. GM>6fWTVt+{K+x8r}卙35|F^n$nm_˸L8w*ykmkpCTOOМa`U\_ 1x TBmMUW^EQ/rxa.݌1a<2?+0=*,MTX+BwW{8ARw-gρ4:jNA\0 3E1lאgctX_!F6(-? ]+L+% 8QfϞ=DFFjEuV+}ܹۓKhb3ؖ [8tww_Wv_clkQc׮][JNZڵÇpI轗fѽkWnbD =~Axx8p|VCØz zEc]#pV(f#Vwc/D-dEI :qDFM۶m}ɛ2e ӥtmdW>_@ll<P9K0JX;7ȦUx4_YUVAJOc>q4&L$Ngѧ koɅcX*=qQb@؋lNzux^ +CLHp;w*:UHfzx} 1BP=(R ta&5a٢>*<%`o۫6[16`]hDV h8k7_WPewj[6-O1ՏyeP'g~osL˖-ywݻw@.# l{?,4vە'nШh~.̴ 8ĴT ǃj4SMp〖Ƿ\Mr<^uQ׭c zMNTxCk@IYxGso׎ qtLH <̊Uٳw/> 5iy%~ɺZ;lhۣӼq%fg>05oH`ԒǫfX[ .jEzuM !Fsh\p.fCQ<`StoDH|:.{VH5ӥvi(FHQ1d. 8ctؔMҼY㖥߾I [WxwiҨ1>l F`F GQrrr d+\ĉiղegviބ{v$lƠ>]Y쏓._1c3fL zd{Y94t޽2z ޓ}~?lЁ=|T[fC׎mXvSnBDxH@H4t*Y0=ZFF\xFѷNe*߫,n] 4nn]7kXg_&77ޮմIwqQ_\45@dEP`f1 ix̣dZ41QG#̟J#{HjJPjZ^Rt/3?e.>g>y;\iuuy4ߝwP@Lx67G/akzq{-x㹾PuDDDstC{5ըV?Qu<:kexxw>$9P`X~V7 edNJP Et@C74/}\xtr81_ЩcGOHBwun6(JoX1s1sQ#G`kF/2vU-}0e|g==jFYhRq?*unWH.%.?pgXŦs\ K6w]VwJkA︲q{38'P v?MY ""jL|+h ߶h6I ~;T?@w؝dm~DwY!<n+b=mBBv GV ('RDV &=.p]ߎq7 6q[-( cQ|0"DC)OAP|wACؿ[\,y?\ ?ޛ9۷E%"""Wa톆q妎PL?7ޝlϗs`o :Rm1@DDDDO!D$uD@DDDDDnJ:s=Ë>\[ZOImߺE """";< ֍wh}""rmqvNJGA^]ϞuvdCv >Q+&h.9@ a<9T/R.]ub);\9@,%!2 ""%a|+%? %RR PZRbrںkaCt@O'Of͇Ahhb|d]յVD58wi\>}hQ1 襯WãBkWipm5=\ }B}>Rf6mڌ{+0畗1d.]ZW_ii+/wL|~#..6fw"4%[cw[df ^k ?PT(++CII o߁9i]={… bK}8|X\KOƧ]q; iPwvƑ#Gq=-k(ogNnݧ~ik1"##pyMy /N\xd(>|۷mwEo˗mv Xם|<|j7|k׮ѣxzzb(%&LxW^e˚]\09L2o8p'ロwt.[KaaaX֭T_~Сر#ڴi w%"RY3gbk|;5k&J6)/- ={@v CUU^7X7ҿns!bbѾ}{D\cL2fe| O'B]O R%_P dL?8gs@D3t(%%VŒ㡇zh0f8+{prl-Y;䓏t}}}-Bt@wz.WWUUH~iDZƩǷICO.0erCVJ4t1Z\cǎSpTU]sg/;PX}샋54MQ˫-vp!'\K1|;s8t0֭[X }]tM?cΜ0x鶗` Q*4$c?!O<{1 l36e⡭'ÿrp1Lwl[%uѽo亪*c~ƽq߀{6Xw[Xw{lۺ>N: A^N&")ߪ;VDEoU'Lߖ]^;t7fc||$p׊Fs^~yuy䑇Uny\[\Z[;uiӶ߭FiA@u @MM-JKmvgHNxx xoj2}yy9mzsT mW^CѾ,V_yy6B 4F(//wR\WexѲ9D$& 3/twbq.=mڴMƙEQķV;'d `ǎu4suD|P!",;7G̙ZZpAWիW1$yP0*>ض}ƍcwowog0$n(8A3A ţ!!C@U.|䵖z-MҺ={ox}_W&`O`={1}4%"j/wE-~6Ӱ:eW/cZnM*?}\\I|p{'3bرXλ[]> 3?c =z 'O2Hcd}ibq[X~W{ ]X~wߍח4[.W$:u3goG60o0jTlf ^7z!xyycժxu]vx߯?DUPœz-Z*+>Re}Kzy}xm?pk&'~.N rSE|}Dr"~A<x##&&_t|"<==Rп?36'O4dR^j0d>o0݅ؽc(de@ƼT ^XOQx9Gl5ߧG²eocFK<""c-hlEhRoW_z -^AϿskR شy >0޲REP4vW(E qNabG 9cfΘa^Pbeֻ "BBӰoIaui^?(v?f{hw|xѹR'wum e1זދ4zzb-%v-M)e_:yZ*_ N%"Wk hToZ?uΞ= o?<{)Є bҤ-`[Unjjd>~d;k;wֽ"+uۜM'AppWc``-iL4 a<9io#Uu""jah7hoVř3gヒO<OOO4i-k׿Xh!.ZSN{P_p]w=ktKuDXx/=4vOu?˗/λ?|:t`wxu&ԫ?QL؂닝Mr/Zò~-tDD$΢ clϐ']Sk2E]qwfqN ̘on}Qh+6Ԭn~E """7cwŇ#O$<ֻK!# b:v99ka< ;B%d s>(>t _0@Ddtv9"$M} ҵ06m"o_KMdOS""OMp ITҡY}Ic޻ƀl &hus|""Oೋ>۱LDtSj8z(:GO(\8@P\ͅZj5֯_/9[=zN)Ν;eso&Rѕ+W0g^^^ĺu H\iPPFe)T`.:Bm1[ݬXt^ P|6g}aʔ)FLL كǣk׮ҏ3<555ž={'=Nuu5ƍUV!::˰pB,Yx=nf֮1x`;v@nP\\yaR4DDdJC?)gyPXPҒ#"d͗fwt ///>\,yn쀮-P*peUxU|d;@JJ bccHIIAFFrvv6}SO!;;q(a׮]G֯Ѳe,ݺcͺRb)W""2Oi11A%f@\hv~9Fira[>|WRď㙏k70`4\cqLPPѣGۇxuػwdD,_vO2>>v-Mz\‹/NCxxUMZDZ1ZD~(m`Aq[UaP4MrhϺAAA8wAs!((j^R/((Af"@PTXz5"""퍈|裏tiR4DDdBǢc{Jm#{GN }ĤtI$0hŚt/~W߯@+=,8P(7^Lׯ7wH111F_4}/%r!""<lQZܛC@qt>(mΡQ^^nS>ri.d?õ0-w D3 ~@h'o80R% :/^֢ӧOǼytif̘Çw޺Ǒ-^بr՜\ dݬYtĉ1cƌK#%r!""c ^U IDATE}caKر*+/m3Rbc7^7Mgnb={ԭMKbS x]4^5k׮ŋ'Ng2 NbƟc€`hgcjtH7uT,\EEEh߾=j5233usfu]3331k,8q=z@VVV>k%ʠ[51d 0/ƌ#G@Raر_I\ib'8A/v~vq@j71VPZZ$dm_z}~?7N?i&N'MFp=,_W7G&Zx Vnt(/G@TMr΁M~3ڴѢb?ԩS޽;Eo_Yt:K0p}_^ƅ86D|QP~z}i Za{w!O v6GDD&p|oqۤ=w=DDRC{$z7o>&O4y4w3i&SQ%"jn(~w#0lMשT]ۇS(h`}Mߟ9u BCq)mRZٲDD$EVk> >&%(D~MDDDql}܀t 5zy(:ô6ѡ UrBq? . *z]Or®lfwnYKSUW[r>ƃ\'(D[i~*W*jo1=]NnFy;mQqt ?FdHx(V/# b:{fvWŇaoqwy?T vs-ka< )dbH.98(4O=_O~zÅ06m"Ui*%c4>رYD󙉈 "ehs(""""""VP@P8,>Q/R.]uZnvWK~(J AaAJKJ0-DDDDDDD 1ɞFAtL Au85Oѯ=^EY2y!77j^^^PX~}=5WHHH@TTe5g)))8ujjjpI̝;#F0^>}3///c8xZZ"ڵ6m䲚GJ\ͥ!""""ruuZZE XNcb}} 2T*u* eeef9}4ϟ;wr̜, <ݻw׭{LOAKaÐ۷oG\\2331l0掇?vN8Z_~ݺu/M6Wsimm]lsΡgϞuΝCPP} 0h |d3vZ 88>4JߦMDFF";;{wtt4~glɧD<̝Jիq= ==]r>Rj.-^""""VׂogSnn ,tV4B}m ,4+B~~|DGG~Vxxyy~h۶40|ZZKƣ#%MWsi\Fk|v+p .^a}öT~MX+6k)3fŋeTUUa˖-XxQWioΌȑ#1qD(--ń  6bڵkr ۇcbҤI4Cŗ_~W7nԍ%W\rfBRRQ<o'%)q58E,XrUs` BRZ,e-::5kN8=z ++ wl 3ІK.ł gϢk׮5j -4iϟ"gϞHJJĉuiN ۷ZFffQsRq)?` 3f 9Jcb޼y6#%OBcGXh^~`uMii{Xxս1ͶJHH@BBXx+抇}|}}4ibcc *͙U4G<\\GJGJ\ͥٴq2$'ٳ>fvKӽZ<fY,KiM/4DDDDDDD_C 1[U]Mg|x'""""""2TW, 78s`흈HfrZ!BX;[($<YaVۓ'IUW/Z-PX/RDV Y#""""""YU :?FdHx(wB.F@@tZ,#""""""rwQvd)?i1VMקo_a%͒/هp-!L=|gz/d3?9B|>yx۴q@DDDDdZ:"p >lE;GDDDDDDJ"eȝq(""""""V.%?@ѠyY إ P[L.DDDDDDD*v̱WC Pb'e-PaAJKJ5_""""""HTUhAd]bErEQȝյQ-?(]ODDDDDDdOA.^^Z\1=77j^^^PX~}=(v #vBBBѮ];sEee.B04u̙3=z􀗗"##n:[BCC1k,\z )i\EsܵRbVQQɓ'#$$ ARR***tinܸT}֭[%'QKq/kWZMcjz\;w~QF#Ͻ^*K}aʔ)HOOGyy9ӑ"eƸqj*+\HIIСCqa\t ۶mFȑ# Y~:/bǎ|2Kl2$''EEE(++Ë/h4a:O4 ?l>3 Baan}W^y_}6n܈K.ᣏ>BFFM׊9)(Z\|۵b+1edP|6xu|GNK'##)))EǎI7HHH@TT,eǞ={0~xM6 Ò%Ko>ʷl2#++ h۶-͛7l߾C ARb #%+hǏc˖-6m,__GXXڶm0|Q#;;Fdd$#""""TW_([/WUނ/,q|~Z[n?>>`]|||8RRRp)ɓ;w.Fa0"""""WPup AoC~]p;tp(eeePTT*si̟?k֬a%@fBbm6lrrrPYY\aƍ4ǎÉ'V^zaѢE1{TL8bq(--ݻ1yd-%fYYYoн{w] KOgEii)_RcEFc.i4.H_ O?=ڡ<˗MFaK݋Gbv[JF'LQSS_~SNٳgm>'""""P_΁|gcR*555];_mFff&f͚'NG}'1HǤI0|={DRRDjSN… QTTCV#334 /1cȑ#PT;v,͛KJzeh4qꫯbf&H9-] ,@||<Ξ=]bԨQHMMեILLĸqp1t G_|]_|yD;[E+cΙnel O}i|2gA`M鉈Z#*Rgۙ6^-DDDDDDDkBCq)y*MGDDDDDDD*v֘l|ݩZGDDDDDDD7hP >]i '#""""""2T7;V ᛣT*Q?_nvGJ,(8|!%(W5 cb K~DDDDDDD~N=[ϟ( &yyyzynHW^f?[ U/qeA4xoNC 7͟͢/ t}>>>"77j^^^PX~}=~i!戇B0z슊 L<!!!FHHPQQa9ܹQQQ.ck\l߾=.WUJҠ.׿G/vয়JR%n#@JJ bccѱcG"%%VMNNFBB.qf<믿믿0maaaHKK3tJ=]v-őx84˖-Cpp0mۢؼy\kw|B-:~VV^-:kH-Q ҥ <=<Э[0y?>>`]||OfוYscذaAee7t쬬,|7޽t\="׵رc8qj5|||ЫW/,Z555v/1ytϮopx#w սٳ6I|MNX|9r|2$%6lнFbb"K/aذa ??? <<Ǐ̙3lPɿujENNz衋ǥK.qJe,&A"P@! (8b|'DDDDDRx̢.M]qVqyH5n;qXh1OE2n⃂p9Sܹs 2OAA d^P<jxDGGk׮EII sJsZKIRzjxs=T˱x~K*DDDDD͠nP}Alr (/7^Q^n^v l߶ݑSDEE!??`]~~>cn|?+kx8pB񽽽:W%׹s1}H^PղJ IDAT)Ov* Z|΁M/3]П=zu iFRoKf̘Çwވ={xb[[FscСx饗p>}:͛gӱG'7Dxx8N83f`ȑ6;'r]k)if͚$CDDDDDCc&cΝ5xon<~Q&k%M矟>DG~:EZ1O? L̚5 'N@=ϡ|>Sb…(**BVXtR,X8{,vQF!55s;hxj_"4 /1cȑ#PT;v km*Mڏm\DDDDDͮ~ }>bN5h{S8w7ݶ1>n맟2p!x{{{똧Q @BB\bΚ#L{담492*[Ek-5M\\$ϖ4~DDDDD-F/,BۙӺmBΜ6|[-71(=Q`}73N9uJa}|tRZ.ݣu8ւB${Nn3a:+Q@h0S'Bn{͢}fA׽/'@/' { >h4m|۵ӭ3<\Enn.j5V~z=zz%4+W`Μ9ѣuڵ Gvлwo̝;6OJkqCP\mݺ?0|||Yfիft$7n@jj*퍾}b֭yHICDDDD X׊-t?۷oUUF |s?~ UnLo>L2(//Gzz:PTTd7nVZ%rׯcx"v؁˗/#;;ٺ4))):t(>K.a۶mh49rM哒FJy\l2$''EEE(++Ë/h2/G+૯ƍq%|Go5 ip.& [:t[:t0Jt17q57n/bivoJFFRRR;"66)))n(skx,[ Bxx8ڶmcͺ4{6m ,, K,}l*4R %۷oǐ!Cо}{T*Xyyy&:׏?و7"##j*,]j"""""WЛo|`ر.i44a]}L-Vkp".63ƞxuػw={+IR4W<֮]iӦI. 8}4RSSgSӭ-Mjm8IL:ő1RVVJeNR>OfVd\8vN8Z  -BMMQZBbʲ|RRg'Æ CNN*++u_aƍfIMMĉ ק~>,JKKqubĉ8w4DDDDD1 \BgϞK[oD:11˗/G@@BV\@ //3gQZQq #$$3gΔ̶lذ7tD^edd@_6X/W\aÆSN9r$?{ՕSj,4fbGAixOAs:'4xk4$C.D1al:朓fF $*2m;n!h"XPE**~=~]k[XkJMUϞ=]MgԀ:|Ū˗.ٽ~ҥe\id;~y/k_HhhL$*44il?~|W SQQh]V6lpX=ܣ[p#)nӧ;_z~ߩXz{[y5ZbN>F} ? 0چ]nҥ/t:=CNg;}>֔*"rd+bccUVVfwLqqqNq|O@|cvȏ|ݸqC{v+>#e|XMMM:wΝ/꥗^rY^.Ju^Ez{alk2SAA222tY >\3fL|{L=N'N(,,LӦMӲeleҔjG#FPzzfkF3RH<|̝;W+WTuu'Ţ$''A쮭w3F155UӧOשS4tP>lvYƀ?$>xAhW3RU<|+Wx'yMIIqHn6so=4"B<^R@^}}=M] v]zI/foU-mkw4mk"EΟ3Cu nj8mK mշYY[ZlV`|v`jnL&g転Gܬx>z.>?:y$F={YVZKK=vZM|D<?W0p wEGFf,]mCm'%(ͷn;JPVIe%>!|m\)^s[d ϔB>:ںyCZ1}P >vzIdI&/>q_x% < KrVwn OKēތG9~\h ݬ$Y=x^qcǪūqe}oSZ[]u/g>ɞ^|׵ =T[[Z ׿v^|Z4K3-VGNaVuaw]gelv~۶mX,2ͲX,*..6|ɓ'c^|L&ڵKN鬞;رC?էOEDD(##Cׯ_w;@n>ѝ:W0RϞ={{ըQd544\|YgVxxBBBtmݭu}VkZ}f|ήiڸڶrj*lPǝeTUUiΜ9ӥKtUWWƍ>}֬Yc3ᒯ ؕ[rVZi;[233ueUWWN/1Oaɇz4qD=zTW\ѻᆱz%%%L:U&Iz*++] t//,ѷXemqׁe:Ɠ n_cD~~/IWVVqNTrrbcc}wQw̙3*//׉'ٳo۹s~7ȑ#K1CWa7ٿZjl;j֭߿Lnn>عݣKK;<^׾#gܝwg?11\bb8i|%%%:sϟ^`\w_Vffp;2͊RJJ9i˗/]<͇>SOKK.\˗+!!v'PVVΟ?&}ZdI|m}kےzGGrF3D~WlX͙/:~G^]]΅5.\Pvv֯_MGMMݫٳgߤIe544 *--uz5k֬./Hyݩd2gϞΝ;UXXh{P} ޽{+22R8.Z]:=ڗ3z] +F۷oo<;ʭy,55Uz #;;[-RHHmm߾]ƍSHH Ti竾^ .RHyݩj͛:v/^<Ǐo'|po$&{ CپwzƮV5w&?1Q|~Y~]ՙPjĈs uzMEEƏd O6C魷Zqqq:}tW۵ceF<ɇ#[n=sbbbn:5v~ӦM:~ "IڵkUoXе3}H=O<ϻ\OllΕ)..5ΞYu>-[Kw^СC;~zmݺU>,!OH>{Zύ7fa@_ClG_~|j;ǎ~!,wȼy󔓓r]zUɱ[+)2ɓ'5c 8qvޭׯA1c_ou}yV $F;M&ٮflp|ֳJY=zoꏔ|]9Oũ@:{B3K3ҥKa|o?H͝;W+WTuu'ŢIRrr}Ϯ{ۓ|#\È4eggZ}ш#nիb %&&ŋrUGgܭH<}Unnrssoݼ_6/Z6;ϼX6O LxqMxq7#Һ$6k_k9 @we0,LD=tY\V[9;!I]EtGemiQ=rX[Zt4p@,w 9B {#:??؀4`@EtZ.P7;O.n^ }#=%VsCZ_d3ͷn;V:~1s['^x|_ Ȅ=9B:~m\SS^綷(^)+)&|tunmnm!:5IA:3cXWzI5Ȧ=k# >|װD$8iE; g>>fd,sc~#V2>@@c>j ~wڶm,f, _{IEGG"&1p@ete͞=[ Qxxueꑤk׮i>|fbbbyf]͇Yn޼˗+**J!!!=zvaWH>٣d 0@{F%Ke=zSA9oڵkUal"}_Oo/*͙3Gyyyt򔞞j1޸qCӧOך5k}YʇCZZ,XܝN*ɤJ]zUب &/{ァJ֭Ӻu Sw4F:٢Eo>ʕ+ڰaua[#ĉuQ]rE땔䲞}Һ^?~ %OyJ<6mܨϧūjҤ];??_YYY$+++Kڸqcfff*99Y]|9sF:q[}ںu/ITnn"""ܪ^Ӑ!CTXXh;裏wq_J>,go?^O7֭[~'55Umw󑝝E)$$5n8hРAJMMUQQ/^l+x@Ǐ7|O>DWff[477k۶mڲeURR 2Ynn4i$_IIIJMMUϞ=me6ժ7oرc ׋/貞}6o5}{47eW듣׿ҁ*}9#v3T[[PUTThvg6|?Xҳ>k(8>}MTTT$ŢEGGkڵ.Go_OXXmWφ  ]<ɇ#HfVXӧOQ~BCCʸ{G111ZnJJJ\XǬ~C)\=Hf=HKwXٝ+++S\\k=9|,[LK.U޽ s! fۯpUرc;OHg7TJJ{Oq z@:*&oGb_' IDATk ̛7O999*//իWU^^ŗ8pN<3f8|}ĉڽ{_jƌZpLRRf͚e\̙3>rH=JOOPO7OaHLLÇԤsiܹx^z%[#.]lGbܹZrկ_?Y,>"NV^+V(11Q/^5e-_ܭz{1=s:uN80M6M˖-}z'0rFj:uꔆ}vF򑖖lUWWO>1b5k,4߫i+:RO=fjkwnūuY=CzIz^j-IxWsCe%J|ǙnިG/ onnjA|=5wzwh1_qx[{[/ƍZݯ;X3~4a~4aotD zIRmuLh q><3zH߮Զ^P?]6gڛow1}PzJ}R/ ۷c?yj%>93e%#nV ~g:ϕYU1}F$LA> (g>X]m=?G&fhu{ >wMFڶm,f, _{IEGG"&1p@eܭH<{Qrr {WFҒ%K`^0ҏwrG7o=Z;v+c/_ٳg+<<\!!! Wzz._V[YV6x]9W#UUU3gt%)==].cqㆦO5kx|G4-Xe9OqOVV&NGʕ+zwU__$ٝ<͇џhѢEڷoJKKumذA:|~:uL&*++uUUVVλj 4A.Bs,##\w~~/IWVVqNTrrbccZuW>Μ9r8qKvVOg߿HZJR<֕|Y[:x*Iњ5kh"d?CmݺUUDD˶>_{)g}vڭgDs:p@񕔔̙3?ݗ_~Y۷PfEEE)%%EGwiiiх |r%$$x#h="o>eO<,?^MMMϵdM-[Kwކ9tflFq quOH~|MtZ}?eVkMP֎ǫ_ ?^qÑy)''Gz˕a4×8pN<3f8|}ĉڽ{_jƌZp[1ydUVV믿ֵkTUUiӦ)--:}|GWua555ܹs;w.^^zVH?&%%i֬YvϜ9֏ exXΞO~ᵮSAA222tY >\3fڀqҥK^rܹsrJUWW_~X,*((}DzHKKSvvէO1B'0ڏj:uꔆ}v3FqZbuE d&t{[E %lZ=f $$6 tf@@%߮ͷn;!}PzJ}R/ [?׹-J|rgJG!mݼ!mZA93 56 Wچ=zIɤg%1 >w6. >wm>ضm,f, _{IEGGd0Lڕ۵kbcc;ͧ2/_ٳ+==]/_v;@n>ݛ3 iU7oj劊RHHF;vtH1m3Vv GӰ(ǔ9?ەsu8RUU9s(//O.]R^^U]]27nhZfo;Wp~HKKӂ ʭ\RVWeN*ɤJ]zUo_g93Ҷ2-Ҿ}TZZ+WhÆ Ç3{zHA~sydRIt*)|W+++K,综633SɊrh]8s={ZWe>C?WddzHv:(vu%Ft3#m)[oiݺuQHHbbbf^ڮ=#-g?c-YHCQ^4te-YÇ{e?11\bb8i|%%%:sϟ{F_Vffq<Ԥ?\K,ɓOWxPfEEE)%%EGPUΌm4>Gl۷{Q3\?繿П'ݺuK㟴.]WW0saaaszͅ 󼮗uG>jjjw^͞=:RXX>HÆ Q^lz˭_=C'Se-Y?f>K4!%k ? $%''+99E<7|@ \Ǯ]\m$Wxw{0߾wvU&%%r|Goqr>}hZpCotό8w%I&j̊wZ'*?&E?Ŧuv{ >wR ~?(wѿ(|5vou!A9bO-+)I ,l5'OMzޢ''{^x|`'(g[x;A9Uu>w^dRl'DIU2h3]mgxF\wm۶bl6b'OTttL*׮]ŋ5|pfhͶwءӧ"""ׯ{Ԗ0L;koH<{Qrr {WFҒ%KtM|j;n޼W_ӘjXd~Ӯ]9Ҝ9sK.)//O骮v74}tY۷|466j„ /{髯Һun:[^{M|UWW^x]Ɵ<͇?#}|'++K'NѣGuw=@*'gjjj]~ΝL+3=@t|eee)>>^,kƍ^dv)|Wx4d=zwlܹu~ohȑo~V[.O]Ggљ}UVw=ڴΙb翦QV޽5j{կ~Ds:p@񕔔̙3?ǦMϻ˗տf42͊RJJ9iyg}m~t']pA˗/4{E9z),,\XX^seggktU>N:gbO>9r^y5559w5kmyL $&MҖ-[`ABBJKK^㨯1ҏc2ԳgOEDDح EI2)p<1i^xI'Oҍ7t)f/.%T8p_ڇ=#hnnֶm۴e׫DZx… n[e5n8hРAJMMUQQ}m~t'{~;vL=SۢR-Зo5َE 7=3s4M~ ӮÑPڝUhh***4~;rLlU>TTTh(::Zk׮Ն :ԷzjwSqqzH[*<ɇ#qqq:}t2x${QLL?Y>[/eʊ:}hЃ*rݱ*++;WVV88{s0W;vl8uVW߾}=j[e'pСC;窯ލ7:}[oܝ#SNNuU+''G/]@Y[*JOOWMMUSS3gjԩ2x ;O1qD޽[ׯ_WCCJKK5c F[0ɓUYYZ׮]SUUMq};"l2_ШQN*.}y]9Oũ@:{B3c={NSNՉ'iӦiٲe2jhh=k]~$sʕ+U]]~bQ{V>ēlUWWO>1b ҝA9s='5/%;B әyw$''+99E<7hK򑐐\rXn2n>ώkoH3?yj%>93e%#n;|)>%O-<@|P[AAu>w%A%2$| `gVGp!m>ٶm,f, _{IEGGd0LO6Rf׮]5/qM-_\QQQ ѣc2r6p@ڒk׮i>|fbbbyf/_ٳ+==}e_srj)1q+b7;۽HUU̙<]tIyyyJOOWuuoܸӧk͚5޾,_{ݶƷrJZ1h"۷Or6lؠ|>|VQҴ`jllԄ _W_}uiݺu2SNdRee^J]t_kEN_?t.Ze:v^ ; +++K,绌)33SɊu~?amٳG?c5_㭷Һuh͚5ZzΜ9r=nkiȐ!*,,TTTzG}Ṫ~犌T޽\tෟۺm_Z /T?0AM^ָOLL;t_IIΜ9{!ɷ lVTTRRRt4>Oc7_csZ_VffV[6mrG;=Ԥ?\K,Zx:olw:xP),,\XX^seggktU>&M-[6hMHHPii[m{1_駟3<566FfRmm555ڻwfϞv[NٳgeXԧO9R򊚚le Giذa:GۙZ'r].]C=dwҥKVjj^u}{5n8hРAJMMUQQ/^܍~n~\iҤI߿\ IDAT={:,E)$$m6mٲE*))QEE]333o'n9{A9op󎄆v5Uhh***4~Ll|nI|ތ*fY+VӧبO?Tz;СCzg=j+,,LEEEVHHvZmذVfӦM***b+ԥK]tY=`ƪ\YY^l7vgøǡCV۞͘[w7TJJJ˖-ҥKջwo;vlo6 _Oro:>@ң͛ի*//WNN^|Er6zU>&NݻwjhhPiif̘ նGbb>&;wNsŋK/ٕ;pN<3fx|JOO{̙:uLRRf͚ա hz;t6{Y3gfkxW<_CEEk:+..Nٳg5|pj̘1]W;wV\jOEwm9u0*>}N:C*%%E|AK*;;[zyc={NSNՉ'iӦiٲe2W֊+/j2emcȨ}~~ϴg9: W_Gv:{[rr]y%8x TG||`+m{#>o]|۵k ĒW͵;uF|uc;Onn6^KL&՘9@W+n{A ~n80]>w%&L߭f@`h5ߺ(A9['^x|)^s[d ϔB>:ںyC$S}\ ЪmL3VkE! k+]D,@cySp`=p!I&\۶mblbQqqkO٣d 0@{F%Kz$ڵkZx.٬m޼ٮ̮]H@૟#誌drx͛7|rEEE)$$DG֎; 'K~3VܷO6xh׌qJsQ^^.]!|u<3?yj%>93e%#n;A9o|$}?(VkvڥX2LU7 Ǟ={{ըQd544ؕ3׮ruVKKGsܬf㖚oc=$ɤZVr>%&NR^ZڵkLIQѿke/Yׯ_+HUU̙<]tIyyyJOOWuuoܸӧk͚5޾,_cʕZjҴ`f[|deeiĉ:z\w}WJJJ+g]%9ED]D% k͙3[>7v^~y.k:7??_YYY$+++Kڸqcfff*99Y:e>V,gΜQyyN8v=j|}UViv7~m -o;}M6u߾}9h{vwaQ\ ߙ]R ( vm{%5vĞb57F)ػb  lc癇)-9gN"ۺwK=o͸r /_825}3f `0!.S!Ih"t4WZڵk#44&MB-Loر \/4$}59DDDDDF${gϜEzz:RSR,&O//"iE+ɽ{Pqo߆wm޸}v$$$`鈉{ ܹsػw/Kg-q4iRecٳ'&LPdddGnݰf۷ofBBuoO """r &?Ϟ9 "zˢ ڷgΝ=M-na/oQ&a+W >}:aggg0!`!2pDEEaܸqذaEߴvvv߿?<==eR'":z2235 C$!""""2ٳ觧#mۧf.Ҷ}{[ӹW|~Æ)vjժ"ےQVӶgtر،l/=k>bccq foq<bؼyI3˗Mys`cc ̞eVDDDDD IMI,Ke޶L}Zl߱_~JزeKm[lADDD4#91e Ǵi0uTښue>rrrL̍ĉ[Iqtb,YO"""""K*(j ,_Qz![ լYƴꋲ}n܄vo^oƎW_}h۶-8s |9x" `+2.sѻwoDEE!88$!..&L!C,УGDEE!,, * {Add$Mf񸈈ʚo|%ɨ{7./55pvr6-c6ia÷v7ptt0pXf ƏWQFѺuk'*SNӡT|_̘p,WE+cȐ!>}:9{{{<3:t(\8c>GCFYfȑ#prrB@@֬Y}~{"""""*+eRB^IIIAfpbׯ8m+QzW>b4ӧ غo9e}<Ƙp,5(k׮*[qL,!:77/_>!1͚5ylTD@^nE+\%I$"2({_0A,CÙdsJ)o^S%Hb~><ڶmа0(6uߜ\m8I9viʆ[k׮HMME'c uǃݾuSCDDDDdMEt- Yy\BBBNjX_o״pm͆Wu39bbЩKg3ǎmT.qQ\t t1[i@C 蟕^g*/Ce@݆ h&{[{ݑO ,t|S3h"X)DDDDDV!TϮݵ+qq|<~<\X)Ny* Mt-^gq3yY.9O!""""&Y,El~už@ p 2~_]گ^b,pITKE 1utdff@^_J/ɱ ADHWސ_wqqٳt)DDDDDVN_|I֎E;yp$<CF>_7lW M[4Ȃ6kL|h1d, KTduיgo2֪i A-C@(`_x6r8C#+1U/Oo/[l#\t Z;_E^j/ܭUig t!!ECt۷Vϳ#: ѕ7޼DDDDd+V]ݠRAЎ/-QR8Sgg+ٯ PeYyg'""""_<5 qN#0( pzcHqpww{ Batrgm\U NLJDDDDT|SA͂w?{wY$1nnpssG@+Ƭ=>UnqQ阛7椱2/""""z`~5onĘŗ_*8*#DDDD,[ODDDDDDDJSpR""""""ʧP}-DDDDDDDUN!=UJ#ۉ*:=[|'""""""4MJ]DQQI Yc Aо>R:0U$O^O "Qe7 Cd,~ "k|TE*իWG`UTz 슉dX\vm+: Dḩ+FU-s.M`cc',(BDDULᦇb- 2/5R"Rc>]ߤa QyPOi͸:*P3DU-U̧_U-o0~>DDT4%Pq*Q+ <ӨK+fBVt2_8 .B@E4Gg8eDDDSAΞ=om9k;v(mURVVΞ=ZeJ~pqq)Qe$Ԩ^|"9 5j>.U}/?61 -ZTF).]Gt΢%ODDd@+jIr…>|8ÇPՐ% 6J%srT(PF xxxh)O~MOCnM~ /ekCAq <ή4 );TTy4| L3fdgeAV`ck;:9 '77߬[?$%&߯۔:ƪ |͏ŋ!];^Ƽ] MLoU6wp)BU>AMq4 y1ۮ#MR]گm[qflmmѬY:wdwPyl|0xܯ̹ {ü̶Hm8qnݺ{wJ F BRBT@E@$ːfNDD-6몕+ѳW/<|ǏP*VQhԸpNܼlcq">Jqk* @:ir`=QeU% |HE}lbAhР EvcIlwUoN~͆H͵5XO\ 6t@ iӦ㛯",,sLQkCAk{ɓHpxg/8~:C6pXq.vG!K9[[;{⢙]_y]_yq`ժոx0j(4w'EGu됒 Y̚9_}5n݂7Fz/( _Z]B}J3aBMGKw  s/dPWw3#3>Qu0FUujؠC*ׯ_%KqjYPfMx?2iWL X+W ü2IDATB(v-ʕ+ /t\qy||CCmFHYZY?ZǍܱǞaFϊ"*^ة3jyϿ 4~I恚O|n=ZC~÷e>t(27mFwc߱ wl=a42~݈X,X|l9>6 ǎ_'ڵ%@DDdm4|A@iW> "00@F`oo71rƎ ~]l>ôSйS'888^ݺXE2y|Kgڴ Za)J VPO@3`[]zc{8;oo̚5tQҮmjyyi_˒~GpkΏg{3]nܸ <~ی6[Έ?/r̢M6ppp'&OVzz7n*rMлw/¿~^yeTwq 5k+>uT-pK0g,\| ,I81iwBuV,Z˖.ŵ+lR,\ viu׆2lTNaΝA[@{7B'O¹FYKaWsЪU+١^ݺ7w~ucWy|2Mr]/_>}ݻeQ*!2޽ '''dfdB?`޽q&df>ŋѼy3x?P3$8аPL2ňwZ>zkb4\@ժ:t%K y8ovӦNAet"2RD{@V޲qH߰b܎eoҭ[?8mU~t&E^}ͤt]:wG3f"%%^^^}6ΟGΝ oޯ_D-Ѷm<>]/\Aqԧ[6CBP‍-b]Ѻ{O$e\eZ${Οǿx ˲vŒ;4Z{yYKИ1c o5% p!Ȓ$ 5V5Ы׫U[1yljժLM)ߑ:^3իVᣰk Aqhs sE͛7G\\\~380yT:twjZs &9R RE囸`=? A!"&uUгgn߾=fΜ}K/hvz8mcG jԅ sg9j݇l R;8t0 ܹmA1rBCBJ*Y'ڵÇQ q`X_cQ1'2pgZ_bݻuŗkbʕz>?[@lI߻w/LaCbX$&&ޯojV7i7 UR (JA"^Z~s^g mzŶK_RCH^)i?GMhMϿB74C"""k"i7nݺCڵ%KGz[l۶o{Rp ̜9 ]t3z(̙;{EVVnܼ'N4)gcǐ#Gbܹ6tv:IL$,cհÍ7p Ȳ?=z/sNCt=&DJ'bO " .R* g<@ݎ Ž4IW9MK nsL˗@R!3ۇנA}/~gΞ3LNz!2Y^2Dvvv>ԫW4V,,PKn.??8xȶ7tRà x!Jt6|jֻz^ '=k6ZX|c##dشy3߿l:tC +C"""`1+V믿T8::B$$''?okE|G3Z^^x饗0r10m,t)._OOO*C)Sooo= ڷhL$''CVc9r$݋MBeܹsGtIIm[1hz>gy6|… t> ޻X~gSlRlDw ۨ$E֟WqcصrfjrW=f `kk͛c;h7g.LE;n{O-BQE ~X3:} OXqn1cFÉѨ^-[ɓ'11z-ZX!]넷ݷ_˗!xwQp?& }ѰC{)< V\+WaYe-7LjK yǨmڴA/_xA>]}M]o sg^z55a$I>~Z6mބCރgjr3fc#GM}DTkBd|6 K߃+^*Ղq9ԭS.cuCQ*݅}:+`ر:vPbaj.U:L޸ m7ݻN&/}J}meka97RnjMCşKbOEMbuFo@DDdM b=Qtz*6lZ AP(S`3]%1rHٳgΜ(pqq[͚Ɔo7`P* ߟiެUd۰aZHO" ]ދSRP $ͺp 8:ujoE'3e}C2\7w» ]ڿڿc :}[6 }Ip"1x *U9EQSv:v"GO(v'ڴn]࠶Ѧuv="{ܙWWo ?ymnRdVCT( =2]l[ewLc?|x܈&~3OQe_6 !!JN0{ޯGe+ߤa;99Ad(JT'"ÔJ%$Is!s2$T@T0.U1Ok?l;+ߠf< 1eHk׮t K ̧Y-ߤ~C""4|AdV-/$ 9<|Vy999nneEȉ(BeVtJO*[Jk MQQU|o/NJC#""BQ)  2< g'NtE y<}mo:_W|}fBm݊{t?2pss3|}TtR*LU-""" ~[I "" aNDDDLQ Ȝ񖈈rL$>Y%""""""ʦN.DDDDDDDU~E"قODDDDDDTODDDDDDTODDDDDDTODDDDDDTODDDDDDTh*T """""""c_ 5+UaO^YSW K,YO^2DH =*-h݋RneYB(E__OnE (AJ>([~. ׌ep>([~u?_ "[JI B~|CU,c^/l5;U0c?E#5@ {E٧JdL"CSq .#LHzDDDDDDDQ# DyKUi""""""""R3^;~JkqlSa#""""""$=%!1KB!s |/]eo?7M}f[IENDB`mathgl-2.4.4/website/udav/udav_var.png0000644000175000017500000004154513513030041020074 0ustar alastairalastairPNG  IHDR +sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxw\G{G(`Ql{KFncD{]l`7#bE,( E(Wv?;zr3373Pg2y4]@(GxP<%%yNak'W898XA`x I 3deeY}})Xƹ'Ά% q%FG2ód%᷾)3vt76ٰ* 0`E(>.\x0x` `t>S<6-P i /?,3sXYۀ!7bHAP}֧Z6EQȲrECer)@Qc`@ fjVi+0m8x<s8]*(hlajM(>) f%I,lWHYy {SKi #hKrʆo037G 0B ( ..hbGj}Y}kEUz-,ׯ3|>fffؿ/g}l,֬Y K}aΜ]6mڨs}'R6` >4#u˷ X03O'XZ n]>AAȊHy:X<D  %55yyE @#7oh t2l۶]fo|>7~1puy]:~9 ccFS|FIuՐeg~",_||IOWlQLM)6; ff)0H'm8܅r0,0 lAW͑0-˅%* ;'Nop}3P{[k-_<\|G]+W@Q'L+Wb߂(oy3Ǝ8oNNaeevځ-s,̙%6lɓ&RJt8xO 33vvvh>}zQF^|#G7( իWðGKs98w<>||[=SNvZn5k!44˃v:>몢=o}ږl,,Zl6 `ƍ6nڤr%{b 4ƍ0Fb+|XX~EOצ ֫?6HHH@LL9| \.a7oJ EϞ@ z}'NbYrD=|q&شy7d2D?{\D^pqgϞa`p}uÒpƍ<{-1x^O^}pǴi3\۷oծO~233gNN6޼~u٢ӘAB({Ϟj'Ye9r3gkf>Ǟ={.ضu+nǏჇt"=a̘1sGGg'.)̀IIhPU+>>Ih , 6֭sAQ(@ N9sx|>܂|py%0x5򂥥mfa :bR/.PTQۚTrwOor8hJĉڵjzx5j_Ç^:Ԯ\GE&ML N(ί:Dx5jGbڴiDʕѸq# <*Ty0JX✣FY}ڱ# -D=*IVً3gbܹcXf<6قZ}u؉}jǏX*ɅZl'Osn`Q 22UN   vʄaXHLĉ?q{;;TAvv6 Jnc!BhAJX[m%uN硠,G^}]WD\\ns޸>$t@.]$t~yn!L >O7#C+W!C၂ Xf8h>#Ox歌{귛UEi!hߡ#R>kT]Mu|.{C߻7Gu܂]q9,^,敕HZ0l󆣣#bеkm8:ZjʵW0fP4bnf+k+|NJ>iħ$''S|>)) Y28:t(Bgk( aPJqO ܱ\EQڹ3lڄ۷oc!}6l6t 01 Ih>̇ p3, 3O}QQ8Z}VeXYEuR$l.޵N 6sb<89Z=<zOψ}Z;'`eaG 8x'&LBB1Ď`UVM@Ŋ ZL̞^Dnnd\ f Ϣm^Prb4)b]] 'p\$|vF-3X^<#FSǎh$:; r9x(ϯ >}Oflt \.˗EΝaVnH/_ܹpI<~ރW J4mLf_`nnP~|>3g^Reɥ#ꓼf"k هωHI^wR~/i]< ^A{)8vڶmVb4m; 111puu^NիPBOѿq׷#._}ݬސb cx{쯙r;8:G*t#D*ȡ57Ư5I?[^awH|4Ar+Z 0b}f@dd]>>0`n/ 1|6}:ߏ-[B 2{L:Y*=pIlۺK-Á5ksU~eiߋ 6'Ees\Dޒ!Uٲжv; 7; )ɟIѹKW$+,[DhQPCC-k lKڳs#߫/(>VѶ C[A pĥVXv@LL"V:ND4?'ŋptp@oWDžbfx)rr8h *h''89WXl6h"ooP/bs'#KQ*"1^w@ji>}DNQWY"?Kgck .͆''i)IR5\*, 232QxOUSWOlO?+X9`rA5C[@@ۀLr?#;deeVpwwGA~,,3jAeO }֧^vcTIo00CSy-[0Nn~E׉>OlPzDP)\|hjg"N  Q @Gv@Yļ  )l# }dؒ@ ȇv A  @P #zM # $A!RSÉA d&XAe[ p8)OL0I\\aok*Uo~- ( .!Vֶ֣E!hp'$nJa ~'{Q`ϞQ?cHj\ '-- 4MHY!-5 __LYKBPeAs() T& FY@c@ @3 i0%DoWo+KKTpO^ݳZ揗^Dk&A ]2pD xCYYxy0Ӽ%uꂹ "S"2}ѻ/C4/YV5f>}w͛04o}!xny1m]x-~9 ժ׀g*1GHG9-Gf)Spe񹙳fcv*z*Vğ7(R^Deysn-nc`hWVI\[qv8:oS3ضeOXUT'ؼu;͟{wnawڴd^wvҲ%ϩas7;D WYϝA5YYYhݮCs{ETmI1st4n%.7)9cO/(|;6|hZqeΆ_6xL Çe^kժF]<±Gо][ qhYXn=z/_@azMԯWOs U2k֨!A좈^G͢(iޔadcŸw.K5 cƌARr2WZFMuHRɞ{իW^x1x{cpuqGIe?RUʔ5h'7/7]{fdS͛bpss@ @*UsԀ̝3 ,DVvs̖MrQ< McGN[|ؾe3lllOl6z+ˣ (WC ðj]B3(1=ɓ'8t lmmQQi4r m󑜒ׯ8?ר^'NF~~>^|%AR==AիWÇp?|qvvUq. Q Q4ӓ@ !AT@|A1 012 *C1p8ar+mPJecSJ5 EQҋ(81E\BllТEј?Vx8' )Ѡz!U A}-֨]p1p`` ~*Wt;;;ah.=za՚Czl3O-˖-ʕ+-F DpBBCEf{vK%A3a8vұ|j|$smF7j՟p#&voVScl=K/ri;wpY?zG:;T }Sˮ՟s.޶VVVz40YEgz'$`߱uF4l7>U*ë́7ًϑ$3'v+ESVދ‘ǰga֋|$fzj2J2mF&&&1f ??#%7A>U4Voc#zCyyyξh?`gg HgϟUl}?N0uyfzj<%}ۿ?_eLŗ[L{"9Cr JQFY k(ZA #kb_HZ/d*A%dAh׶k EZ1KLO }3K J/Zb> W7WcYb Z60]=L/( Ao!DVOcSգ"ŌmQUt'$EjjE1..p/saJ5 ,|b"~|ZGQJ@, Aʫ%ך. @P`i"ӏ i€5x-PN`F r <I\B85n+sJu‰[F;hglQ4䱿0qOjĤ$xI*bz4^D$3={5Zv:z C}(kqTHIJ6:Th(HJ$A Le/ҲRx$|d)۷@ `(v$3= *Q|_ȀY0kHZ/zu>M 7gr&d800_~+KNDN-ZK^Xf-t4Pz4^$w׻`{N̜>MOM-[+W[bZ .#P,F\G޳[["8qcF#"< BZZ:Z'1 ңR4CM:u펫\nn.zΟ#JM(?cWLeg`y,^8 @%Z<0uyH%/?R\Ν;Qb &1<֟/_BzQF~@9{ 2RB Q8JB, -o'('.!dW7Wڕ[]Ex*A5`cc-Ɯ<&NI<ÑOww=IeXLQЋ03 [ QwUdpY=IcxLUӋ6!()S#%)b Sգ"r_PB9@7=l  }~2cHa %!D}!fCY:;ҋEݿ#G*r I/ ׯ_{~}em&iVңVY<<1 Jت=x'fN۔-[+W[bZ .#P,F\G޳[[w ƍ0;|iiXjCz~A ^DrM(?c'eg`9,^8 @%m4 G}8?%@M|U>{NTy[2|)S}8яKE:%yBGȮ]*`B[ԟw`wՔlo@=Vuaew36?, Z]agGE&S8tYYY0nZru aa|V_kbaƬ߰zrJ {M5}T?FM.0 aaD?fzRFVi0k 4l@1@G7DUϹ puٹVVVj`G}8[:9=gΚD5O(=d/^&ocń2d^^^p-u 6SMj+ݠDE܆JKqG]M]I8Br/"##rJèRV7"h(1GIj/ވfz4dQ|=Bk6X,P,Z!kI!bec)9HvZЮm;D0KQ䳢. bhE^B`z)F, =jlt:Y,|>\\ƳGEry aokp]P,6[fD?)S>LUҋhLl:lJ= %OHTcb\\]`g_ v=j>B2]>K$荪UԯgdIPH] H082|(I L!` n# 0@(;ZF@ 4NHaLQ#95WpL6>qus]Q C%$z2(vx8sJ;eEE }mdѮC{p8uFYѣz)l# WHKK`ֲAZjP eI!> b;i鋲:T_^  C&h 6eBh0c`҅Ѵh. #U( zD/x$99ؾ#W_Gjj\ѳ{wL'fW&LB, D0_D~~>F {<=<3v 8|p?,-P_ay/7==˄5 %LF3d~W˖zj077Gjt *Vtþi}pI͚g~8s|2nĠyKvC H!t4|3~_h٦- LqzC'NgBljS{y0Ӽ%uꂹ ">`htǎGvVj.nx7AWx7Ah>hӶ\*&Xz \^ tu0*((қ,t'O{>n'Kezmݷ_hE,~58h +bIjլ)913V[G#0$z_}hW\ͥdPP23*-]oԨyWdddϽymҴmӦM:ϟGRWUxcƌARr2WZFY*媣7]wmT*oS֭[c֬Yӷ/ك&`mڴ ._^zǏ`h޼yfƉaggSU_zIT+TU>6VwߣZjj׮Yc<~OeL4G?Jgnn.yŨQ:N8gOɃ(~]U7\",K4Ah$'}FJrRS$عsf6- b`osf+̣ }MSLMMƻ2u lѣ7~;n,vlwЋ" 3гGw"ڞPC?n:ύFXr<{'N@fsl6[aE]&>*)[ڵԖE4'֭ȻR#""Q^=iҤ .^,((fl38 /2ezDW:[=~"uFdڵ8|\P }!'DEG[ӻZVV6~9 -FFMJ/JcG#))Xx|cHII>#Xz5&M(r2glܲg_@ff&p/* ?ME5WljS/_bI`uOܽwD9|*PJjC  q99و _UΜٿa_H[1bhׯ딦 o2ezDW:?v VZG#//?ƊUJÇi7=1mt| Cfaĉ/ܩl8 Эnԋ"> m kkk݋m;?~憞ݻas0&E,Abb"<1ЮmuVlF`hMxc ZX 7\0t V]K"11i$)604-;ΥLtwHIÌ$$|B*1sttM:"rڵmн{n̛74M׷fLV,uP%J2I+u)))`!RRRQ#G`݆ʟIByyy3f,~6k۬.Xcsƈ?`5:,&nb޼RHJ&%RCCZx"EQu0lKcqN$5wFnMxu\p7mVL^`!$~#(h&3 s,ĄqcQJyK0軁Jd\0kQAQ?vi2k͙xzz`cjacc۷_[lFy쎈`ͧV>1p@Ǹ5 %Cv/:.u- zPb]ov Pru, |NEg=jĞE#'`og11hMceoɷ,hƳgpw0(:,Q+vBNOP JիWÇp?|Q,{{TVآ茲G]腌5j[(z L"ALHW@ (F(]"earH@ qzAjPaP"@GA}$D*#@Jг{7-KKK4n[6P=az0n?6_ǎb`5''GdddHܲF$AAʇٞUTA-KT 8穈{yyyŝT^ȹ_Z)C`\F$!5Sף$C? @ ($*$( @PUb@ yAM3=baC} Uoևagk[7o@ 0kSF)I%U*#>!O'W7WڣJO%Ѕ!mPRv )!rdOObU`H+p 6=O[RAjΨj>KH!*"VC*+2 10')-lKP*+bqHzM+L+k[t˰rn#>!hJ*HXfYޮOާ"dj'4Me>5o$7 '{ah Vhס=Ο=v>J kGt0 |j'q˼|dKF҇AQ =dE0*ݑU=4Z Tl5Q^& h9Xfre>:!kv0f`ͅvf@ӴVG^n.֮^-ó jVoZCږV24mkf&Ν  4yT:[[y?z:u`gpQd6 UIONOͽ܂ vj׭fZãg.tCm(ZQFIrгWO4i ϡjժ W^v*䔐FXNܹ4[>&L3 04?vlWWlشuԥu\۷? jDU1vHWp©'ЭcTsbIHOKѣs'Ts_8|@];G5Jh֮_3fahMM7ӳ2m݊5k5k-[͛.?yssرQdgKlG }y~I˯JM;c$XT|6mXK뷸r&4\rsfD9x-:Ȉ;QbZ/޾'u76o6`(Ǚg1stfLgΈ?ܱc;:K.vZF]3EIBЌj?yjVZƕ7[XX`ڡTM[w7@tmVflJtPzue5ύn#ύ6h N^ZBxu6-g|!>3m+^/?÷}zI0 X,TG/Tȯw/[tNZK._~Q_y(ԨY o߼A3 LM}}G`\] РV%蜕By9">FŊ%xH U0147VxZjUګWC5i'O`ذ!CR\)4K ^Qo޶UiјtT'K_,7B;rW/]V(.Yftsu`Ӧ2mڼwѰAC>u AQiF%   ]81v$$cy \_3q3_8]p!pr9Ƣys/O?ƿבŬ鿊O ֬ǐ'wxGC)Frd| 3f@l{p}3g")3~ir 'Ш]Μ9M6a׮qxjjI2">9=5=qq{`꤉_Z@1j85kq)6n'`Q+<ߢU+,Z ֬BsF1 -[_o[w%Z|7aJ֡B6֤-k++9} vvvn`ԨY -N< ,qIDATK IRyUsgN#4t6nXj&n&bPCC_[tMt'<آ**Ύk*;8hӧѾ][Рid!F뙏 Q[YNQu< a tE} *`5톃[Pb -BC, Qay /Ѱ*0Lc{hXl6|)G An'''iUbI2 "S>@=7l {;փb)@oVn*{{?gAc{ԯhrT^ >|{%Ӏҕ^`ojժe5ƴP?p A95j00$*@ 6,ĸ  ^x l(P ĝ@ C`1$v;@ Q!0uA d#\j&t[ KB dA1 XĎ[Ð @ 0`3FrL$r)l0)@lg H@(xP4T=l;IENDB`mathgl-2.4.4/website/udav/udav_gen_set.png0000644000175000017500000011141613513030041020723 0ustar alastairalastairPNG  IHDRu3AsBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxyXTU%E@VͽrR+}I+W\\s_TRqEW@}10: w`yyd=s^X[[^^^hٲE'''cJ% ֭];;;ر}:>>\yL o//,YT{U*رs'BB!>> ժUE Mί3G4?wvV=|h8ovB_\"Vַam} E>}q4V Je  h Q}j[Y!+3CoܜXYW]Uj7DDeՕ m+bܹľQA}t( /ƨ?ā>} :t *С^xA{mZZ> oʜb;44кeKܺq2A@C__z5n݈IM7ʕ(5kТG''ɟztƏÎ;q=89UwKz8מ={lEtt4DQDoo;h֬{#"R3iZj Ziy`͚1w_gR)w}b5+5 2 }9r9DQDPPn޸%K[X(AitX==0pP#wm`]&oV S 9zoDV#1!\\]lt!1!ܴ,(½۷믿uҜ?;wmvWm۶۷P!''!\t?Usv2rH8v8ip\pӦ \áNzŗ\ct0iRみOkpssE~AkϞ=3g sV0c,={֨{#"P3+ƌ{{x5\zg҂򎎾$gܴTD]\_v‡ÆVY| _ ## .D#&孧ѡLȁL<r#xzƢnػADdK(P$B.OL,г JBjJ*ܜ׿";Kxvvl* 5%CT~Mi)x[MU*pK{~/r6pMܵ aHJN֦ۼe+T*ԹxwcƎl߱'ߕ :@&3nLdԹLK ۶oڭ۶CEL<9HÄI "maԽe(4=- co`ۖ͘;gun3iAyoڴ ƏGrRiSa;7'{Ŋ1bl۶lX"T6okcM[Qy0[_ Aȅ dC&BӦpA0Μiip{{F͚5q#&#p ԬYuk-g:/}5i#ź ѻEnn. Ųe˴颢onhݽ{ה(U 77\UܸqCk^s]nn.jMD僡g[?aϤj_SNE7;??YW6a֭ض}[NJz l EM D$&>4)o[Q ؾ!]l6 ׮EHMMQ@Qgb'CG鞎e+VB!S)sY&"2E7O{ޘocccu; Rѵ٫7v트5)efd[= =$oŹ=)ɸy<pEmQ'N^uըDQRFߙ^?ꫠgQ~Сc'$ܿWgҧNIJ?{{{ 2 9Xa#2R2G֮E5s- vefwNv6ϟÇcDG_?׎L2wN=-5:!hI|/񰱩KpAwhQT@_3JMEܻ*!++SZ{`SV s߉J; ..Nի#8OM oCGBu 8p/]@.#44Ahh(r9vb4ܻ} ׯ^6:*TMӨgfEW䳍YYYAV#'v9% |\Wu~ jBd =**ܼq&?wJJn\ê~Dͱf:ܻ{ II{[7cwn 1rd޸q#NN:wDNΝݼ :h۶ܹsrt999;+s.eyQ o#66999ĮSޏf}hXYYʕ((J$$$`L2Up-r ++ 7nZ5k"!!KdTtS&O\qy hRԩ]DuQ\ƃ}Ā PR%$ce8u$QjU 89#"hz5t7BCCaX P*xGzkϞ}8:9Ʀ" ++ u 7",R>2of@, 2y 28\Qm Ԫ'8 cʕqW6:Ѓ;wz5F ]U˻JDDT~g=nGDƒy;rܐ9cw$' TvP+A%BTDhQTK';Xlpak[ GB|>ykW`z: V2 A`mek;;ĉ(Oq ll|&eyK\ $FIDFI"""""!"烈D$%A7#""""#ɉ """""IADDDDDUDDDDDTDgOIJQcoBZZ>L,P9/TGiWJ(ھnʺ^{A!ZADQc{jxzvļFB{:㵎PJUBբrE&Cm?q~223VڵbxPbEvUȂaC.PyVCa"VG_d,(Bqz4ͅ """2NtpD#j{A&T*K>T< qRdiW,!EiBET`|P*P(&GDDDF%s<8%Xë"xJDDDD%s"6DZU: %')+(sDDDDaUjo@>~G:eVF{k#iLDDDTBѾM|*xw ۷3gKw6k?zoor*7%'%ga̽*r ""d&2?BaMѶukV+п}N?܇: M@=oW۷oG:uaĈX> QE\z 0j{ó& z<ΐBzu xש'gWtv2Nvy=vUt^OӦ5Xf-5njN.hbsyN>ߤW |,k{$""燦Qυڴy &gTڰ'0gWX0[܌;pq,YL'݂0w#V1y'&o~}`>ap)""/ _|9ۨmS'pM,^~:%?z b.w+fL4-]Li{g`m+m^-[>oK1yT$%%WU5z4ڴ{ ~o?9>}a&x۫XwPTSXO֡^7s0DDDD%*!_sBԲ&j㡀񻋇{7jv$wu1acS`73fYcwE^q8r87֦IHxmzU9ZTn$Y'O{ 3ZOuM~{| 2 لnݻkzrTO?y.!|9{k4ňL ܽMSƌ>Cƍo͇(Xp}- o&*UK.Wc3g`_⋙3x|ŗhժ%>B1t̘9VV8ƍt=_7dNpffZT,xU{G.\+^ͻLԾd2a >89UCb՜ͧnݺ:oݺ~C.uÇ Cѻw/n tu* CǥKжM4mzoeɏWc矡U˖V-[?G#G[0o>|}5WT ӧ}47oGJ@ƍuؗ._ԬQ_͝?mt9?QI6P0:upg'%>k?xx0I ^gL C`b>VV:y1x{#p{w4d1sg.ԮU G6rJ #?)));ߣHMMRDB7>sb-HLLDFF>ocREͧNo[8w~ODDD$®ѹS'| o +8ԦԱ6[͛QS .ǣF4T,[۶nGx:$@7p0,\^uѤi3:tk~ɤ:},L8 .nwV1v1𣑨UGGUÇ 9sqa&cǏm >GCffW#45kԞE_L?O(c6ĘPRի~b=(Qp)aJC_̹͝S?A|yu)ԌCj T*o| W@ bf1b8^}[iWs S:r}xg/lڴ=/?~A7ۯѡcg{-b3SO={o/q(zժq-:ڬeRoC:ijԮ]8}?z$ds:ȢUPk~ |;.\_amm]u2 7w]Abb"nظ7oAW#++K[ʘ >~቗__# Y899/gaP*\L?s| ''c\QQ ;o4/gwT. B`mm;;;rWlټWd.ܧ,'-q 6K.GB2t8 @s8w?buk1|pblX666: >mڴFc~Þ={%_2 W,[5<ѿ_Ba\QQOD&hcw)ݭdoʄwnb ;I׌+2ڵh;7I2I5qB8V+V>+*L&ǎmСKF_7հdfN ;'r99޺}3>aax!|ئML0={}!e-[@NR27D L  1e\)0f8|jQ IqEO#݋C`] ћ>0p ݽ۷nB{rz&v~٧ؽkjժBj%rOT6 d0-㊌?y~ OOOa|>^^^z1\d.YXL<[lGuy5~m/<=< seN:s`lڴ؇oMK. ___m]t}}a !&Wd J#?رcаaCc|>o}˗ukLqE?w=dѲ0d(f͜  >>>BZy{{cÆ4y͛71:p a5j^1L>o3FFFq08^^Y*WdLC^=ѩcGc|>#G~8?WD!77;,: &}GTVL ڴi}9޿_?hS~RuKaS0vL Zhh٢>S L|ŋP^lG?E`\1֭[>k0H *_w; A^hڬ9{ 2W$5!oU-khJT\Pիd9cݩtQ 9A3973ADDDDDb7u"""""DDDDD$)6:HRFp"""""+@T\#qJ*d\\]`o_?Wd*IqER16JJ^]d".F@ѡSҮ Y ሌoWTT-㊤b(JD> }U өsgٽ+**IqER1[%" nd**}ø`lW$t9@Ү7y͌2*izSI?QyeF+zx=z{""""rȬ=)8v3Ǐ=c MDDDDDdys:̳|դtٲg/]&N9d+v܅/wCumQF#ѣBӯY[BuOtNƶѺM;x֨^ 66V{Mtt4 C ]CXODDDD|5 tFܾ}c{AAbLD]՘6mzwڍ-7!et{e{ظlܰ/EU˖6Sm!Cc?sg+fϙ[&""""zm!0iD,Yce4i"d2V@akk WWW̙%*4 Qn"00X`α'Nj>_ Tӧ!88LDDDDog}޽{ʕ("66QQWѻw/鼯VթjU%''kߺ}CNή򮋸x ke2 ƏÊ+! 'PO S_9cТys|899ARóIecߥOG^=qy?= _FלΞ= gΜ-* Ánذa#233q|8&M\U"""""*$h؁:u? ]%""""rAzټ4\5j[aC ց `OIJ0UDDDDDkg$%2#`OY4WҮY(}ø`lW$sŏ 0D%G*j9B3[$IPlvBR$ȈٽqJ:d\\]_B0([$IŘ*I s:Ȳvb\T[$uADDDDDb$F<Oo嫈gOIKŋG\&{{G_"qEblW$ccA-b:u)ȈHxqEE")0H*b$iQYGҮYN;cg\QQ1H +*A㊊ER`\T?lt """""Iii'gWΟ<u7+zx=z·y""""rȬ;'$ر?zRRSJ%vYtL8K-{e1iDc2 7w]Abb"nظ7oAW#++Kk֮EP;uӧmvn5jW>5X6N{uFܾ}c{魓v:$s׭ 8u4.Z rwڍ-7!et{e{ظlܰ/EU˖6Se񄼍:!0iD,Yce4i"d2ݪ>_ Tӧ!88Q߯#>'ObȏZE n:E`` pc'N4l"""""2ٗݻ\Bll,bccu{z&ݭ۷0 | /ﺈמoӦ &L`矡IƅYU $Fy*Ysf7]A=}l0xNF͚5 L_F@Hz;zԨѸt2233ߙ34i X"""""$u7nބ4#F /jS aNGI{x] """""*3^EDDDDD'6:ȢvBc!KFY4{{G9tApH =ϸbl %L$7ÎDRAdDމq]..pppOiWT-1qETf@q](_iW!IED#9DDDDD$)X.DDDDDTv{:HRltzYHJz'(..w'Wd*Iظ"* @,eD\ C.]  _?3[$CqETy tEKJz>}*jԹ3Yyc`(,tE**}ø`l;d """""Ii8J hv갈'g2O0CG3y """""%[Z0do/D4֭Gm^-ZƖ-[gT-[cѢP* """""zQ6z: C~Νnn=gN%K"h"\%Ay9tH{ɓo7_+ؾm N`f"""""zRht>_ Tӧ!88X'_v/sAPy`Ibj +VDڵ6o1ĎnƌgxX>|:iڴi]v7nDQԾd2Ѯ"""""zn)@(JAWsJϚ&呞EZID2 p9?nnnP(8s3iN?v4h}ߤIۿ_iV*]ذa#233q|8&MLiӦرHOOѣ駟a1SNW_}-[!#dddHh(9ob֞'gg^$h؁:u? \;fl Ǝ:ucqȗzcEʕ*Y}LO%@oW"I(F!eH+HzLjJIJ`x_T c`D\]v٢8::C^ !HLLM7U'gW[Z{uOh[l}&ݺuѲUWDVmaF111<8 |P/ G}z~srvΝnQ> 1jh$>zdG"OAFZpCB"*WTb}=}}~\ñڴiشi36{.s͓?oݺ /jNaG/NyO׽8hA+cUV^QYgFǐ1tHϟù !U%K"h"\%Ay9tH{?ĢŋhD]E `…8p/maGM;~ 1ׯcyس1 |1k&\BH?PjL6 %g^ ÆRd".^f}1 F#Mc7QUP}l߾ 1ףn׿?֭_͛7ڵhպLs͓?/Xsfz0*&O\ht݋b\1[-KzY6 qhpW'B:ߣ7`jUOMMEqY͝prv ѽcۇ{~ x^=z^C?ʕEm:8o( -'.cƔQF4{#Nnݺ$xy{?sً/"guptġ4nXgƒh۶-]Z`t݋%Yf N>]֭[>xL&͛f qŸ[cK R9drض ڿd5*A=V!}ݭ۷0 | /ﺈ796mZo׶.]z~jڵmv/!*!eL<[mC\\71<y_Z5*!bJ0ObccWQV-ivݓ/־+Xrrr'B^|-OO_㊱*/qETvyNG`x{{!$ܻ{o݄JU^O{ԪU :bժ%-S&$0 њx {wq1 IDAT-T*ƢKWG>Sz[IG-&ٝ={7<'NjS(U5Xa?5cO@jմ/;_K4gL0A{1bI*c%+N6lDff&ΟǤɓuW^G18uڴ8v8q1|g7vc:i֦y8t0222]`yeLy$† si-|qaTJ*zбΝ;?ǽ{w Ũ?.vZp.\`0֐qŸbl1,)ʨv i%%A}ԩ[9?k L<= ]2ƌ qQn};'MB׮]_5;O@1nL?^wdX8-qp(~Zc1呴Dע }ԭWC?3> SNg GAy:VEMoWsfC.˯^1c^|qblYҋ2ZzUQpwpzڮ;ƛo Lrڥw!c`(̡hWV!,HD#~1([$c⊨ʋ_M$'Z\NL .+* I"*4 ǡUTQ!Z &d~ȽWd"I"*—=dXɄ(&0DdIBdT[&4u**8Vs,4 ㊊ER0&,dq!< ޝՔj _cf*m[(햐ʌY2A(>vɾ0veR*C̠{TW.ux9;hCCNʉb\tYfrW  A"+HE|"Μ:uMajZ͛+,ü"M0HQ%I I!Pļ"0:2 ("R"""""H8*\A;=DDDDD$(6:HPO r_))AFzC!=`aiccS886+"!WDUê\k))§}G]BzKrr3HS-"lt^A>ugw耘m 3HS-"Az's!}W\>1*\t 03,JA;D9H """"̇2?[ZFDDDDDUSQ7d6uF۞9{[8a5۷oc4mk;v>)Pi:t~ďAAH~۷E!!!Qnٽa!Xd1 -ݐ۷naNh(bbvjQ۫t?τ_@ hoʭ\k׮C̎hԯ__֭ӧ}@XzVb'""""+.L0;v{[o%n t^zڷ! tZj*-۷o#)Tu'OB(ԯ_O;,]LPHA"c:2^^شAtu> VÇ0'lPQ :fq0q>|yyy}6Y\VN+֮]']8v8={<9z 6[ """":v Ȍ<ɽ<<3Cz7vܲMc|i_<9C FxxΞ=ڵk+WwADDDDT}dgQ:H.obz聞=z-NzHΝ;sN)i?ej@z{UHNDDDDDMUDDDDDD\Ҟ3_zW4:Az’3͓fs!}T{:HıcX*\ϼ"M1HH]JJ b!#=C)94SXyE`nT+ʭWsptuT1H(-" @$<DDDDD$ """""Aq"""""HA;۫63x{ O">~TbaiccS88IEBP5*FtJIN>;:#/]•+pptyEbnQV`O]Az}ަp=4"!(+"}P8I?TYü`n;@r""""" """""H C[jQuU:ŋXd)p=f x{`hSaa#ӫXr%O<ɓ;w^6:2lfnYjitܵ asBaoo5j}F̎hiE%]m9as5*2^k%>~˗/ n'|еL0yTٳg8y2Æ/Uׄ <'`Ҥ=JƍISp>|drZ9a[VXvtyxpQ4l@X;:#/]•+pptyEbn>`Znn| =ӾCDoSyEbn>k=4UV0<[$黂FSQp"""""h@"""""/^ bx{7}|@13}UT=DDDDDT~O˜xV\Ǔ'Opd<Νv>>GfZO]6'vQLMMѧOowR7o7i0p dggK53ҥV !"""""Z g>L[Ab \xΟ%Ϙ)큃gn>e٣z!E8r̲!CK/!"""""UDDDDDTPF p]ADDDDDUNa;=DDDDD$(6:HYXZ:SeʃEB`c)N;0H+s, ՊH886ÕDoCFz!=`aiS4sh 4"!WDHt Q!Pļ"0:219UWADDDDD*:BIP4z=DDDDD$(6:HP|z齔 K O2H]-󊄢jnU#H*O))§}G]BzKrr3HS-󊄢,*BQ;=rssOt: &z+s"(˭1؍L*+wWT-󊄢aU0O """" &q[:""""*UU\g>L4231U&Z}zUɋu^UWvPѷ3mރ ǫW-zqi k9-[G}p]m֮]ngm W7DFnV͛7?h4EFv8pu[R5v""""Ҍ8}4BfYulSXpLۣi#R_CΝ_bÆ?a:\0q6/@D@@l'Lƍw.{6n2?{zx" Pn0uHLJ£G;Qu&mto<\peəLD2M9 .m 8x̐F؉3%} RwR)дiSeϟXYYΝYodd|eBNDDDDTU1~|Cy sr3,w&LDBB"I&#`(e5j7xɬƉ' ;+J獎v>>Xz56o g6h]#1: `___eG֨(4@(~ڴ4m2v""""DZĀ޾M.8`R-ZÇd2X=zgP;Q$Dd""""" """""A6:t43~EDDDDDTIQVI’3fs"?HNU)N;0H+s"(˭dTOAՃc3\IIAL6dg:011E3f 0H-󊄢JnUvN H  EB`^Qe%*UDDDDD$(7WQŒu;=DDDDD$(6:"""""TACQDDDDDT  """""AHT9036ݷN+elU>C~TUD2~:9i>1'Ia;C=˖-Xlw-e^}nohpԩӰ|.@Tʖ[Ir(~n03pquÄ8\ۺ2v 3sK޽[fyj uP{923Dn=֭N>3sKubX:[XQTuiy bSfmŻ|];駟`xZuݻw...EJeEnqY ش:[ɷ#9*,>!66ֈOY~".|;2/#!!DTQFX~O7T⹩z+6\hrr2j׮?Hde-v:u@=k[!R/жm۩ mC36lsro޼ AC`ߤ)6-w5jkzݻv튁D,%Ke};=a޼pzJX,2eefnk֠K[Xآ]lٺn}>zwl,K~eGQrQoή1L)]sm amcN`ǎʛN:!6L$]q2$:uT*o6mY֮ۢ]']WV);ƍVjbر+;g|L ~[$ףrMϹT>6!S~ӦHtWSک8eQ%sdepj s u$:H)r3|e "|n^p Ec2e#"˴z*bX"Ƅ  q\8VV>cX l-]vi̚ٳ׍غ%IIp"[E-~UrkhDnڈХs'|ŗذlX׮+&L$*9XDY~)+gKpMts̐ I }愆"&ft¹sǏq @z! q9xyy9as`~n^C?_Sv~%}aʕ+e)))ӧLYU- P477}_({Koa͚5n CRR3g0w^8֯[5kԣSqJ:p ލԪէ$\,`&y 5z;NӾ}!T˗ԩ >5@nct>7x@A%6_]uݷ˖-G̎hiGE2YYYWx KϟþI3ܻO?ɓ'U+'iÏ>SJ#a[ 'agvMJ-sqmn\nJ}ު懲eUͭW {쁵u=Kc4lqWO7ygN|qA߰֯C/B/>GϞ=qeL>[nɡ}>aJ2ے9TStwl}ݻOj[:|tҦ̺9GIIIe6|$VNN-k'uJnwQ888T1 a"jx{M> i6C]QFA;pssáÇn&󳧇'^c(sݺue便06s% } IDAT6CFC.d[wXZY²-wQ>xVƍw.{6`UCYRQd 4o!!ecGGN#6oق }7qh$x{LGFr*UsKމ"j~(YjxM#|\?p@\9fIiKI׫78z4 u#$|}K7:檰 0&0-…1vLs*9,ϊ*WWW8::b*+Ϲ$KտYY044͛7UkJ^GT@A+Q=zܺyC[7o >!=]R)дiS} FFF8wJcN<|GeNNNطZ'ai[R'+*?" K"ś*> VÇ0'lt*yӤ=_\v wޓ~cݢEs}ְۗYfr8.^Kѳzn)+4)Xd)dZR}Qȑظq؇U 66Vn}^;': ~~]PNuԁ_DEm݄ <'`Ҥ=J}=x),K$ј!88 ;'Ϟ=É8|KbinJƉ'~sHK\1cǡ{1>cǏٳgÑGѰazUgkCCCmE[[q5 &N*1tG$}8^UrDYi#GǴi,б&Ot<{ 'Oc* ܹ#GahѢVZ>ALk]GQ5UᮕM~ b5jHDc&5:Aɽ},#akTc?,UAޣ'6oي9r#jԨ!-kV͛M: <<?Z1Q4TNVT~L6ƣ-coSߠ!k4k3_?G9f}fh'aߥU͛N|gROkQ{cbQo1c0zL\J(3M}H*,$$б`ԟP}-c&|3Gk\b..2e $}:^US:7gOI~pXاWO!""""4~zyɉz)\QQ#BxGVvo"""""oEm ^EDDDDD2NCDDDDDK"=DDDDD$(6:HPlt """""A(I.3sSS awDUMجr-R"!W99xȼ"[ZHT0v/RS 20OU!/]•+ ![  EBP% 2@j92wqǏJJ ߗV9'U1;t@L6[  EBPW999ٻ7$v)N J]Tes4ż"0HeÌ 'OUnJ%A7E8DDDDzN"Az9JDDD 6499Þ҈{:DZ!O"'YɉD,ī`-A]3s4lC~G2V\N`bZ-Za5ճ{^xzy9Zt١xe[}J2f'0X NӾ}!T#{n{KgNGB-eׯJ˰Q*ۇZ9Bkgg&/'iu|i_L< Z9Iݿ~1NJTUCDmo/YoaџcLǍY酀@e2?׭[Wz Uoȭݺ…)r3?~˗M KM͛# uH$RtHi(ӡSu⋄in_߾׷/`hD\q3220x,^Yɬ `aaQ,DDDDHR0R\#1I7Q###vU-___guy)L:EV"NNNطZqF>L8 C||&MQ#GU5N8X)T [}>11;/_֭[OkWu <_|t,wAA-gp"._RX*6Vt(ң{wdff" p `cc1OzMqA#??I7v,V\qAAP^=cʭ#66?'EykVƜ0b1\\ 00@7ODDDTI>[}J2u@u^EDDDDDIW¢3cLU]tUm t """""ADh""""" ADDDDDH{:HP HqQU1DDDDD F?#%99H|_T5XXZ,"uWDDDT tic_))§}Gm쎪˗.J88:]"M(+"""XF@sA>nTe1gn&U,m/Tes4!""H8QUfVt铳EnnZۼ1ڸ("*[$郂Fc:Inn>Sm]}["a`rfn1]HuwKT8O{:xw*e˖c2y CE斶/fSeVy 텁AuɁ!!sR;Xa&Hh lN(6Enu(T ‡ʣQFX~èXDDZڵkA$!99YaY3sK]m}?0+WKK=m̜166]jI"":|]?5;pssáÇn&󳧇'^*QutKK`4m3sK4ld yF*<=lX=wGff& -- 666]/iDŽ|j_>Xz5愅a Æocpuq`ʔI0p٥RNʣJVv^UOu(jg>[}J2 fx DVbx|ڷ/b]Zۣi,Uo˗,ǟ~"ws4UV^9tV}7N]:WDhѶ un3=: '+nҮʔWTu"jx{M>Dg z:D"pRr"B&&ؼKlC.skذ9j>\q~D+n-*>fHqUJmuUQ̭voݹ[[|Wۡ:*Y  ",xk ~}yf^EDDDDDJB*an;DDD#mty)N;&:[`7iBY^Q(Lp%%1ې]R`aiS4sh sԥJ^Q*htha;jEDDDT I>5ɉHP HY9""""""hNADDDDDLy:H nUDDDDDT :ADDDDDbF c:H  Vc``XP*CÍlP*)jghѪSBDDDDDUƍ:oUqQU*7XW*>2F """""TAC$%"""""*IQIMKC^^2t Y]U-X:"7E=uN`Uq3{ư?oeqvrT;wPoCס._{iiu(DTEMKCZ]W/euVD$I Ӣ|rШtTSyyyڭ -hߡGmuDT=C.~HĺEx jFq wX,*;/ާqFtTG즭^2&MtUQYYYy!<+^D ZwADDDHɆ"v_zT91$*"F'$'""żSJ_sDDUmBDFFݻQߣCS+"b|DEEۨQ\\\0l0t=K".yUz:U؏JB"C`gg֢aÆx9N>eKხ~-r*U"Xgline#\c$fmd)Cco?ri{bߑ/]в"l_pj? .^]ѭgovu!eٲ5 셖]е{ODTݹ1m=0*p rrsu[R5ZIʥ-;bI}eŢ$Vy\D"Ν;쌚5kQF1c^z%%KаaChٲ%~zڵk۷oll2١FhԨ֬Y0T|055;#?YYY]wXIDATqPѠAԨQvvvXlʃ XRqſv؁yᰳoԀ)>Cٽ[Z&5k~}ԳA_"33 f Lyy~x0b셧7ꚙEK'̞/^ b $*So aV.-\{&02zu꼍Ν:c֭J_:o͛uѰQc -oiuk֮+ \Wi%]z[; ~2u&~%]:ǎmd߻~;=K i{} -MEVeׯ] mZ nέ?d_S4:Ν c H:y/]a2ݏ"18xa=~c fl|JL6 I'O`/Ӱpb'$ʍ#plbđ`an^\tAR';~7 'a͐Ř:bxhkIEݶF~ǔ)SpBdggChh6m޽{#tݻwNJ+sN<|5j6!!!XbrJ8x>3 >iii{.1a„ $uݻ5k ;;+V@HHʐHĂ-,p2|3`WR|VVV4m۶صkLvm۶055AbR"f̘9sBoa($$& b~Ko[֨(=Ji9Eǯxaaa1WܺN8?AAA2G`@~i%j q 1UGt}zFwIF ܽەZ֥[nؾ#Gcn]T%=}^}CU%vy}ۖH4kT,;;=? 'CXĝǷ? ,o\D.]鲴4t7nܐnwU4-|999011)aÆɑnsNKZ;cǎ)?GGGܻw\{i׮~GSZϮ]лwoiLa%;~_/E"{E@@hݺ5 nxxz"eܹk֮mۤ?c G^cԩpnw8s yF8V+xwڮSSE˖-e2ၿ v 6 {[*ُkIʎ뇫#vRo\߳4LGa#е[w{`ؾs7xXYՓ1нg/߳4ÁAfYQLYaպ UX|Dǔ*CCt;9"‚3Yqu|W n*@cAr=yDf֭e~vui?O0;, gϞCvEAٝ;^R{{MLLXX=ƪ .ݽb= %oRlcccˊj>>>2?oǝ;w0f!3?4^%992u:ݺ ¹iF<|9ڴiw&ODd^B"kW7߇߿dA"H_}K#UꮈJe"2?55Evvt˗p_x*x?Ezn2{z"(0@aBNѭG/quO0OI /2ckԸQvusãTLr~.4:=̬n^O2N-[bOQ^[ۨ{I.fUEiz)ݻ++2 98X`,,,+ԪUmT$ QUm-26~}~}?l߾Fɸ#Fť Bg D"F7ЫWODFF" `4"7Gw^x #H$b<}.^EK(]6jpuu)\YǯH$x-UVz{U9c4$)&Wq1:Lc0xw5k*ШzJc佋y=$ȘGf8+D8s9 ƍ喽9 q99Yf!KtbW&*2V##R۴i ?E?͛-bҤIN>-^۱׼ysoatg=5y< ۶ΝCzfmn߁ى/7c; mM+㫯dk>>hljeoOe0?{b(,,Dyy9a0PSSŋիQWW^ZhZj58N\pQ?3Ǧ<;i d !uU&6Cӱ!o2 1fr >طf":*3gEDh%$/K>{r*j)ldi1w+}6bLAw:LLի'ޮUC7 tիp$Fh4\|١zIwK|NTիW ?\ɜxltrdi{>es;Xong!9h|hGD䪬'Y1ŗy5y%w\%JMr!  11ʕ+jѐ%9`Br&Vb:ۮQ#Z\mjUrr2SI6>̫Mʫytleo#ADDDÔE! իVKr;͏QjL7቟7Fc_䬤P(`4v˳}WYP]P(0CbB} C#ȸp󣣝 ɬiƪ*Z.]BˡP*erDQD˥W%y5yU{{_#5ܔ pu@$tuA?1{[>:'iO0Kcu mgB2=*:;"rq׮]`ݻeDJ5jk7{CB!i 6'B簧U&;7""Kb^2kC5TSHU""""""{ lDDDDD ztDDDDDD$ UDDDDDD"DDDDD@H I """"" H Y2NS!""""""t"""""rN.FDDDDDD._} έ""""""Ǻa7a1 1:;&"""""rw97J~,E S_Tc@7 nv)C)``x"O_H9݊l!`ol;,IENDB`mathgl-2.4.4/website/udav/udav_txt.png0000644000175000017500000007674713513030041020137 0ustar alastairalastairPNG  IHDRh\)sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwX"%ػ(5JL4آFX; &QK{{C9~N<(*xu 4W !"V}WEe?+]ɒ)/BQDaF:ϟ"ݚ* r#@kX^`G6oK+B 3f\!LaP̶_PBjhZ  " B乜gn9/ ˻[<3ǨTQ(}#'O(DLtqqb")WOQ VKlL ӷ__S/ E˖ԮQ-Z.\&AM.]ms.h9^6o79y  ԩS,X_3o>gp%N]f:]/2iT*3Pz } O֭{:[~nQҊקo?9УgOΞ;55^}wuƌǵיǙsXRΞ=,/SŹ}v|r]} ?={9{/t swrN1 {{^ڕׯ|6/x5˱_ +g1{s5k"7o⫯6)v:"*9*TxW_̙`fT(U(Ψ^<11齎>Bl,xtmPv%u?{IċI՚<==RŞw7OO49{:%7'^ ԭqFRyܹqnՊҬ߰&O&>3bH6o5uzco[[ |u^ېʔVnnqI^x$:~8J6/R3poՊcϿ!66/+t6f̞;7KqL=cƎٓSnوx8F P(~Fi##"xp6g7;w6m(u3z4uL8˗g9v|\۷mg̝˦M[X˚l)u1+֭7۷/ǎaM8ۙ,áAGEQ\\2mn&O>Kw0nnQ((HHFWyZ!.>u+ߟ:u`i\efF%^PlLIX`xx8G6 *2ƍQɉG2plmV +W\|ureܹCʕ^ Qi杲27Ζؤ qH:uriF%ԫW=zk۩?|02ےuyf1e2$&:={rr;FΝq?eKw,-QǧS]|6iЌ1er +V$*~RFe거 AFզXfNBBёhZSS~)SN}N< -7m(_~ɘѣ0q"_Ms|Pdz`"?RU?Q^]j֬G~Jx뭷;.<⸸ۖʹRɓ0I',áZ-ټ;w~MӸq}$mTŋ<J@V"͊9Yb8u||%aR-KPK\l_SS*?&/K;y}zݻ5^-۷?jG!!xxxxx($$q`XR_tTooQ'3݊9$;j?3g͢Gw)Wܺu9os.]_7X1MT1ԋ~xȈYq>qna}1hn]R7p* 7ceaཞ,]0v%4yh|TKŊQ4?Q#3~ÉJgcVkEzR¶]LeכPT?wےv(U,rD>}qrǃ ~G>y% z⵶m8wFEy^HlT$-Z$((s`nk3v0WejO;31&Nnܿ}.M : sssV\E`5j5?f߾L0Ѩ|8:p~̔)xqqV˦My&H_fS՜>}V[*fc:l0,--8qqqgq,2~^]u\li~,[Y''IXľwo+kн^؍5b-Fs5Bٸi3-Mn3T@z΅ (]66V޽qpxP1cӿ4mږ{ҩU1UJ%v< ~3ӠA}^< O3}I[;N>%vB˳[7Jn/;đ5k2w|ZpiؿzۼMͱNݺ,[F a⵨ݻ8ٝcǎѸQ#j5ݻwg}Nyiȑz5/!22z^Cz ظy K/o!22;;;4iϨѣ@ύ)Szխs ٳ qT|:Ky/_&** WT,[~ŋ1w/^36jߙZ֬y!sw{sIM9w;..cGgWlCU6DxN`VΣ=C[ڏ\PUQ/"~\}BbE -ռ^5_ѠNH 6:OtQ+VDɒ?s_vPϟ~%J\.MнD$Kr[/V:kJammR"A&2"CC~@X+F2AT&*2'ONVv.YRwXz=Ɣ)xo|شy1Q#jU?ߟ7];6vYZYQ.]|\aCu!cWVˌ_[bC<*YsNR U!q22*2 2VcAMB Qg(Q‚=tHr.ϠܺyϟSZ5ʒ`nܺ]ɒTVd(66EpFE퍾ޝ!^Ciڴ>M-'E=ɕs"mmU(  %wӳB!PR,-g!"Q8!"i嚳B?I,B3R9 !FbTB!D>X9k,B%-g!"MB"W !yGPP5g!"_Y!g!B{AXؓ.JU%b y]!"y[Xҵ[[ L?v{Sbż.2Pdh"""LE^ű.V ' c]۠HHb^J%n-*R '- ggVKuP*բhs&Jqa=Il1k4y]MAT;;{ND)7Qlaer}juv333㕪ոt5kU}\%㛷n?$y?RESU(9.ӕsDD|sŽDžT1Z؜| MQ$[K($[Džۼ!`+" dZm!|s^8.Mn"i=TJ9<<}, |3CXZ&+e6E~|LWNboߕV.W+~p{˒ᄃ'4I3y]4a'^1&܎yfT5j?Hs{Ph"7-kWu 8ǃX跀gNs`~uxnmc_Flj*5nJ2eiԸ)Z΁͛7Ӻk8-GWk0h`9^u}1ժנmھofZ#2"jkɓT?vѪu[˖a&̝:>}K_T@@'OE9,r_b嬀)y֨U[C iފ&;yנ!;v'!Y޻װatnNc^5jֽZiK\\^(ZٳTM-ONXO8r`T^ sssJ,A6mXzi7lHNS>:ufӦ(}ZYjڼ֎1Ho~ѓz Z;6oUo}v|6jԪͺБMΞ;mԹ 5۱9>X˝[7Xˬ9sٵ{^:Ln߼Ch49ϞM~ҷZhݿyuk16lƗ>7oF׻`ooɓxOܽ}±YpQw eS-_l9üݹs#F܍&\:|8O>խ7VKgw;s޺ K!JHQ1K|N8ζCͷ޺7~ _p$+W,3,[ lԨѸ4mƞݻ8J$ܯ]{խSmcݴh̔''oNa?_7_p|ca:Ә$ cpAjÇԉ^bdgcΝ,N൶m8hlfqQ4n̷MktڗJJ^hbΙM6)^mZ3g,ǥnk1c:Mbyovv[XФi~yu1ʢEheo`РϜ5ŋҼysJ*,^5kj6@_ uˮ^Jpp0E/^>x)Xd61FeN鯿1b(ׇ̥ i~Ϝamm#'}ΑGu.^4i҄bVVTTӽҌy]^ %KbnnN Xha??+Vԛ ߷J䄻wRj ӭX/N bSO<ʥoFKbڽTT9gȮφ7PjU8p ϟۯ[v3& OR^{KZs5EP^=˔)͓'8`ۼ1cٰa#!kkv$ƴZm\x;Q#`P:us]ʘJ%üÏt~XCP*O۶ͱD=Ç3l cI3v:.dϫqkܤ\[jժwR}\ʻI4gXj()}Q/|:wDƍqwoI2eLubGZjJ䥛7oꢷ̵+LR~dt \J 7tcdgJ*ۖ,ip/Lk\(1S^NL|\S3/ҳϮ]|d&א!i>l ..Y~7gdD/]ʙ~[tu޼y>]R z3gqݏJ&ϰ1'=~3Ϙŋ9zׯƄw[(},Uš\|\&?\z\NscOT"͓U?N7Ogu+m +W֭[gJXZZfGv}6f2ԸLlzkԨc9z5kf#r333 Nݺ >~Z}̚=7ݻAPP'OCxzz̿aFǮ<LT2dgX+V5dOJWo\|ϥtbL>1Q~Ɯ_]]]{OAw͹ [.gv5kdp+,ѭST>]t&$8Ϟt)[˓Edd$Z033cA E{v9_6|=78xP5.;se.]ŋ ~u+DGGs ~Y 8ǎ :|ʕ+֗/_cǏHT*{fiݪUF)ON׷/?fԩܸqZ/8t0WO{:'O"**N=}:Lfjdt Cϲx+U2BMٲic*U^aDpe6|Z3c,BCCɓ0!1EFeNV^=VZlظ1G\ %}Ls[2ssn,Yŋ0oj4jؐ!'/ X[[Ҭ |u'NWӾ&88]{' .KKK~YeW0l߿6O޺t;v߰2 pvvk<ڵ3i4wu勩Sˍ7qttL< EN5I ח'){zzipd:vCgcxvF2e-WKl{M[mә2u*>Qti>ިgc|Tf̜IŋT^!3vlw;իn/L_(]uRKehB1_x W7  9صkWQ9ܜS'N}\=v6!!!7m|򹖯Rd tYSXA# :Be~9u7\D̛7~뢈B(=ϹTiGYbʕ]T(IO˷R5jզXb,)#Doh^A!r_|B!rUv +Jq-y>.; .ߩ,U j5j:"RHMCqބ"w`+*ߛUM{"OaLZq4aE};UM+gϞql,0DqR"ݬ9MP:w8|Ĵ֭3]Z=K{R!z~Z mھץEȖMLF4",˷Ri4=$dmJeֺߓJU4. ![b}\`J%BVR9 !LR,bBXKY!g*g&B%-ci9 !\sB!i9 !TB!D>8C BCeB,ϭ-ȟd:vfBd,r`B:/WR i=N9 QD޽vpPf.͙?ZMLL ;fZocκyG'+<:tsJ4nҔk_g\\(\W7~eMe(}G'.X)C| r|& OMΞ.MsDBmNb̝3ĉP*5WD7OOWO3o/; '''ZO`<[|>;,^ƍq9 #;wJ{eT;Mܐ\.J͛7MΣX1*I,,$_!S\w}GTT+W6y{KKK^}:_Lʩu8Y~\S޹"[z馿}6}V8WHٺu34"..N/Fdd$jT#DV4lؐ]wf߾[{vrO֙u#i?q\oٱǨQf Ky; رcIHH`֬Yؘ}ll,7odƌ' ?χkW?yسg8~\v[ ݼ [sN?[;g۶m%e+Al޼E/KΩ̞5ټi'Nd%&#!R8q<3fdṀ>ݻ >~\JYr9G޽{8;;s!4My7S௿۷:tnСCu~m {U6,]C bذqo0vB.KJaÆŊc֬Y[բJq+Hj׮͉'SH:u6ԋ+?3O7aP:tnݺk̠!Cʪ8OFkWqQb,ŋ'0cƎk$#G`);v\/}z$**HOժUt 133cРx G033|?A;B! 3fϡwOҌޠ!U']+Q9q 3Vz {d۶z !(23 LIrPfm a.B|(T9x._Nݺ9ECrx`"<}jERVmZs42 LB-#4-DvʭKDRIYBXYYf)^LLlRƒ(rYOdikHŧDI,D!IzxvLƆlظ9`0! j9TkژҒ&ZYHYBL6GkS#+EQ޼]2CVE+ [b% 5ơTi7h/k֦Jg˘)S8//߱ZtG7hsryU_ZM.t1'e!-g! 1V+-yhԨgϞe/ʖã]2&n^8yoooa3nxJcnj1r!Q)I,D!?clYh-ݙ9s&^R^MYk3gpB7j+TaႅtޝѣFg`YjO6yܫrhmClт#Fd9ocCet:u-K~)lO"۷/!q}+VO>1yHb\BB$_'i]>M3׭觏s-[`^h8a<'O,QƧsy$ʖ+-3gj6vv4uiC%hhtL?A)ѣǨUVy>ҟ1tM=)]n݅ 4lؐ?E>}}fLxoo/xsTOӤmvܑC2N< I" \j9O4mhؠϟg)̝弍^{_|W_~Aɒ%9{,Ofq 8K+K:u숥%gΜaXvM* y|#zO>CXkڦ>"" ,,,2_+ח粉Ad$ 6ѣGA˗g1{m6&ngx˗_Mã}?N55r^CҴrwgՊ̟OBдiF) isc6 ɓٽ{7[nN|>8t2&àmX/UzKonnl޴)UOQg$q O=sJ4sij#Sr"UT^9.>3;f͚%z^?ȧq9Ν=CrN|==xO`\ onرi0pnn9qob9l۶=Ͳ5hP͛ؾt{{;Nb̞5ټi'Nd%F!4ZՊ~9Ut^4R?"""5kФI\]]ٵkvՕ^zeKʊɓ'Ѫu ct*Udɢ4ߺu7|;M4fժiŸCsA7lȌީΙ?_5j+/oFItFwnbʥYQDiPQ5Ç3dzuCP*!+8AXX**.^DVhў7ťmkd-[ښ={ҥKg޽Vnݺ@0ZRWΝ;wzlݺɓ'sUzE--GЬiSfL2$$$Pbײ2)S;o{e/;f 6CX;t̆"##9t+{!PjuM!RZ@ҥr%\J%Æ cԨQPX1f͚xfff$$$赌Ϟ=5_?eu#xzOv:utݻG;PxÓo& C3v|6lȮݻ+%L*U/\^zT"DVh4.^7MNʓ[˨Q7n+Vt,ggg:D۶mu]ժU_ЧOo]θ㍊5~8x ʪ-Z4;A/ WZ-j*̌A5t8ffĉ0` VVԩ#V>s_ukMEߠ>ϟ Q*]RJS^\/i@XKekk˾} Lƛ6KƍHPP < a|F÷8::2ˋIdݽ%3fx3}L] lY'ƍM1r|g -[`e ?b9I۴nOV1LJ?GЬYSFeE] BShcŻNjVRcT]|=4 /I۸n-;v0ib?ٶm{#B\J-6ѺۨQrOY[9nvp(Fbr{n {:6!g\ܸi&+脵5˗H8B!|3vQ x !0F2BגgB|F*g!"Y!grB!%6B!Nrm,-g!"I*K!B]},-g!"Q%g!"%?%RZBTxl/DHBR/WBͯ"HE{h hҜ}QѾ#k?} tY"/{rM@ZUϓ'O }9?B.wk^sn_ qPu5'OfeoȀ0!SN1slfϚl޴'NxyOĉ>ͼj]+qheHOi~\8sgPzOϰl{߂,^׮; JӾZFaҤY+Bҭ}& K*Eۜ9>,QTR??_zFI {}6~kpV,_د'OU6nhbf͜A˖-hٲ3gOz%ԯ_wFO,W*ti6wȶdx]^ Vսt1f(L{v"% 6dٷo?֭g]\ufffVgϞcQ+W333QeU'O[vԩ4R Qx( ݓ/ O@o'5rd#o>(ϥKa8-[մܾ}>}Qv]+T}lݺMGɯ #22ZixGSL83fa&<}JTT^p] ?.~\#Fq=9t& WyUCpqwo*ƞ{ٹcGeA5cܾusmvY4[bl?t錽̔GSiݚVbƍ4nܔǐ!w~1fpi֌/Bfڴ/7~"+y g|6oBWkз_?kT:uȈFWk2bh>4 zB{wWqHQ>rgF5}IȍqZw`pݻѾ{5kXcz}\pofz8:q~ԩ׳{L:E7r`zN30 8}#Gq葼.FQ*Ulٴ֭܍&)~!ã}{?A+7ޒG#iի1#W_i~hoxҌڶlٲioٲٳ.]:s]Zm-0++ϕ+7^zu5h ,$ߟ88ck·pr#WS:u W^y={Ҫu.!rbذqo0]f#DaҦm>40bH>} b 05kÕWwᆴY~=#=FW3ȘԩV IDATSaCXb9>t f} OC֭kGСܻ{G3xgs$i`9辴* WW|=/MbF8p QQQDFFo~V[oh4 kp<ڽ )B£V{?RvwoɪU?X\MGiԅCb2F~G<~޽?!(< 0npr^^ [2]Zlق;thO\٭ݺZ~quJ2e,cf#U99GC)6[q—)lBBBΆ (", *ʨy%$$I962Εs㦍s#|,_cF /%JJRwxZFCLL,FJ9W9'K -򂹙9Ŋan.k U B7;eTv@"c*JZBdBkrY쑛ߥPX!c)¤,B3J B!TʚXZB!D>#BO$Y!grB!B|CfB!Y& B!>Yʓ0JcjԪ%Kl9ke!D(vI%i̅z}hڬ)Kd׎DGdr&kn7ifvBI:QQ͚^\i9?K7OٽsG8exm1#9)j M4MbNPq-5j0:={2w׮_\r| 6333]WvtSvoK+Z%֭mkkmҫ"sBCCX}ѕfϙìY3_!!4i2J#Gו-ڢ(KT*X˖-KXw<\]\(VU<6lhza(kB= IG'~7vdd0 חM*KXXZV*V-K11:z:uqÆ <… };u-o#p"}l ˔)wT-7<vmnǯ^ Khqqq:r8RLiI/.O dmjCGXRL6oި6md-kw4m l6k)>|Ν;Dfn㦒'shhE:֭ZTU2TWյw>uulneԩ֯x"Ag7 .RX7ї?SuUxq//^T+:zڴmB_ڴiS}jGt.w 'gEy9 ߯ɓ'~zCzq 5p {i-:uj#5j[ÇOUPau^nEVoPa/o… S)EEz\* _AA1+=-_Myc~GIRhPuڵՋC th:%W-Z%K4u4 >B6M kA=Bê*4>y29KR.]ԵK4ˤyy۱'xuDDS} +ԾO orqBg+6(wˍ/X%bX+r O`2W ؓ3Cxa'dZ 'gvf9̑i9`2$gL„0ɾ6csIEGGK$@Pja^ ȿ #ww$kmWʖ+`IR Wk֪u۶*\#/_M%kUxqs+U$PQ6WMTp,ݯd2p\.f7'"sp[cNn9&&F111jߡo$snWDD"""Իwoqծ[WNJΟNV>ϨZ ZMO>G/_do:t~fÆбʕGp;;\j$B3gֵk\K*ի?SU|Eպ+W'u/zmի@Jyʕ1o|+X oC^ttʖ+z+22RUV$8p@O>/^,I*V~Rհhر7o_M~ M8IӧMՅ\ӦNUDDSEG3fW%IShIV-]pQ#G,Ţ5{&NzScǍˣFSӺ7nܨ5Beʤ cc.]3tkr(+TRG_{ /|kWLLJ̒TBܹSW\QK.Y-]*TH#G WVm2׬ٳ5axo$bE?͝;u~ڴ9cԩ8_A3gN<@ϟ;jՒ$i믩EiӺǍKbFvI~{hZf.^VppuaC_TѢE^2ٳ3uݷOddO͛7K|.$Cq~Yv5kp{jݡU<~?@Z ;t=իtJuZZW{_kjF~լY3ϮQQQjݺ;Ƥ/^40p*U͛7_ϧ J{Fx\\"=sgoogu9v['<@HKL/Pҥ4g,UTI PJ4{L, ԥKVDׯߠ6mTrjаf̘6٣DPI-\HuSPpb)TO?]ګLH9UQK}~;O7pkI.YD5ɓ'uIEDDvUPpPu>|DP%CM7YרQ]ڕ:kk iቔbɮʓ/^H܀/T@@6jk׹_v6j߿_&7&Oԏ?h}7o56n5k}|͜5K6FN~m[7f4rˮmaaa:zk6$-^X=rXUZXJÏGjK#Η)SF_)͖jC_|Q~U[lU\\~ / t6l&M+Vʕ+ΝGO)Ȩ:kgڕ*VԩS'ոqΝIӓޤO xK…ԩkgp򔢢~r=.௠`uU{j}w7͞37ssӽzZ޵ѳ\:u9uqO 3Bêy{tϽyi.8 1}׹siҿ( |&NOedwo\H}g*Z~+_Q-/>_}XX5vxx-ޒ%Z| WX9s--#E&~?nƏniA)hV)-2XjߧUGz܌ W>Ε aZчQ$zr6 yr*IY\ؙ .OJ@~FrdH Oյ,ٴ0{r 9q@;y⤢u%I@Jj0/GRC[^*[%I/(66V_Ym۪p™d2p\2ñ-g. ڷA+^\J%I+TԦոq.\(jr  lݺM;v!1':jIH$si&f'ծ[WNJ\Re護U~*:e԰Q-W^M#郥Ko(zgj߾ʕZwQtJ*:3IRttn/VŊWttmܸQkvs6m֜94gL;͘>Ms̻ܬs4f̫ڼilM/-)%~99vp|k'utˍ;Veʤܚ7&NMOM6 o(7\5oL~~~*Y2Xc_M۷8V 0seBطUl ]SXq7 ϡ*;q5nvu%fn]@~x*g^]]fkP4W"~0ܘ1&.@E_/* ?r jhZ%۳ IȜr*zX>66VAAYgjմ~o2\㓥xQ0=tH/?|)&FGVժY[-5ݷOڻoF~%)SF_)͖xpL˟S¢UzM )vwVf jN ) kƌvZ_Aw2!T~>#6jeʪa&ZtYWDPI-\HuSPp,״jۮʄSԷo]n\/ϫDPI-y=7h2!eղU8xP+VT&*[}~ ՋѺm[m޸^/_J̥m޼QmڶڷSUV:?ޥsg߷GʣT,ݗ3j2e_]zGl_efH[чjl*9Oǜ+V]T)6|Fu븎y{ڿoOtU?uKy[.Կ_uuluZ`֮=-cVոnjr.TR[lw:fZ%yy*ݻqЍЪa7kа~"s.^V25S}T@U5jؿW˗ߟao>@V%&&ʕX{0jѪ+Ԣy3UzSOVԭ[W5l@[Rp8?:u$JkfռyT)E4p;, UzOɳVܒTfMׁnڞ~^U$-V]z5"wUUh6'┴lB=OBBB裏>O}3˓On6W^UIcUGߧ۶kÆ=8d{YIR\\tKbBWJ{ĝ^2XnÐұ֋GѣL*9;FVQC7T ԨQCwі͛4ut׹:u3t5jh׮o҈uݽgwZ3Z>R{|^ެ{C&OOÇԶuU]zU۶oKGϹ|ءxi֭T))ÇiId ]rEzN=CWy)**J:߯zQڵkkn5Z^b}-kzq{"37*Ovksє7ǟ~$V 믏qXt4s,}mѴ}m-Z%K4u4 >B6M kA޻YM8^&NҩS'\RC_:ߥsg4xΞ= 5L,\ܕ^xܸ B@~fOF^z ǐd81-gLƾ+U7Eq9ȟ @vȕK{rD3M Pb[+g9gƜڵkJH˵'K3 C6M cX,h\[gte%$$'JLLT\NJ)"Ex; sfL `B&i<UI0Ɯ0 !H `?g̉ a0%3&c$ [Fu|LJL LcƜ:vH=9L X[s"9`2$gL]0Zk6h9`2$gLƱ+>&`Jd0993&CrdH ?JœT0%v4XS"9`2-#4h9`2$gL (&a(DrΟ;+-QQ*ūp;%I06;L*$ߤL [\KH )wk3 7ҭ ޭ+nmLޭ#0ڴ0BT$93 gb mZUJxR`Jl|rdH `Lə ax#rdH kk`|Lq$g&m;i9`2,B)]"i9`2$gL&Q*z.i0! SJ,A &Erd乘3&cfaJf0%!4XSJͰ3"$q̄0ʐ+rdX 8ƜpM ;; =IDATɐ0DŽ0oX["9`2$gL ؓ33>H a?ĝ0'3&c13 0! "`03&CrddXĜm/BB6^LǴ0Gr +Dr,$gL 8Vv--gL ɐ03&c(,9wv3&sf2F!9`2$gL 2x oscZ !9`2EHXXXS"9`2]x oQ*Lʑ1! 'gx#rdH+9[X& S ɐ0 !H}HV Və>&`J$caB0LEH0 #3&Crd6CI3&Cr/Ird`cLɾ Ru]0dcΌ;UcqJ„0ɱ0 Z 'gV̴03 acmm/Gd`J$gLƱB=x3rdؕ S0\krdH !9`2], )0 sH a?ĝ1g̉ wbΙi9`2Ldh9`2$gLƱ+! .G* ɐ03&c_G>HUb0i9`2Iə3ޓ,rdH !9`2ؐ X,|L'g ə1gt 0 rdHc?g>{> 0! `7X>p+dk{Պ7-Tn9׭['bJV[9nnR`NV)i =]0%3&HΆX& o,/BH];xf#nmLهMrd9IŴ03&Cr$+v(Cl0Xl-g@2dMRb# Ν]r>1-:3iǒ[ I2ٮT5jy3K0ӭ Nڵ>2 ibܓwXЦ6wvx$jz衼K\v]WԱK7͘5[ _2# x@WIwo$}qug-|ԤgIq^yŐ䓭8׬js},tk|w;zXҼ3uI1uZ];z!x,/ ן~-iZL%9aM]wz=xڵwo_DY,fH*߮MMrR0zt->߷_?ə sf4N5d5#د/WBCq%cIe۵ <!)PBTqk˶nm߮{;w·VbbRwʯ y6P|X_:Z3c[חQ֬JxHu4Rm5QukŪOΪ]M+VJH+.SUN\@y^?ʦ޽ڱýujHGKM״a%6bakUZʢ2e Y,Rd$^|~lںբ䝳&Q[ sڴk,{~% uן9Lch/ٽE?f(ޕcɻ#֜y 4zHkM}w,q2%ׯuB֘WFiƍlѧ ]zizV\.fӄIoo~]M?N{Z^{MonN};ʵXo6HI]GkbGR0tum˖ *C>Imrkr&S9sm0\9'U|okf:fۻnuVjd}s2 &Lnm51ju|oj믩~*Tʕ+q՟*˯ꮎtm@V-͞1=BKєIոQ#)RDA%JhKôknwQ#Gap)RD ki֙1a*Ud 6-6MΤt{'f{[~wΝTaAE,OS"ȰkM69W{̒G'u_Ϧ֭3J3ٳ}}i@@t'#Jrm2 CVkTw^:hT%Jf. U_W]GׯV&e}TX1c%%ܧ];PӦz'[%.|ѣΉ쳾ǎ5\z&ɪ}'٤Ӳn]R<ؖ:~ܦ!C쉶Gy챤_{pLq۪t0,]ӊ>T\:6H?;rH=#]eErejeifڀ~_KfއdOKN r~ڵ'(3y\gZJDq~oرYdСcc$u_Νκ MY˯K-pfh`{]SX|yEn{B_qݟyUf[nQZ55wL-CIj֨۶{}Xժz?OhZc-xs\bnO>>JbREFGJuZ#;XO=z8<ΜsدG=ԬzSZdIN,=~aIu fɞKjm?Uoe+$^5 âǓX kU˖zoz9vpd{lH5l뾒$f͝Ͽbcc~]<|?޳W 7v|r͚Fh򔩊w%$$hTc(]ݛSзJHHз84I}dG\+Cٲ<_Yn{"13j!ܙ|OzkD dh,&Ye9ғqg5Y,}u7mCt>+)ΦEN9G9{ztPM7֜3`B0Qͦ:uj٧?a-zm=v\E V1m5y4`?Ur%=zi?t`7AϟW͖[jh yWҥأ4mƬTI}dG\+)"GM~~>ئN-v=dɢsmzI3a[5#lUg7lHs:vQRRO}vکfeF%0|4c1ڪM%jhc @6=Lԋ/JCd&9}> 5GjcϼJR@~V:vMw ȞxbvCmH3jOw.)nVG٤]ӱM7:}wo/gm磝8Q㚾yG?v㲉6;ͮTi(yʆ?qu}z;X={RjZv&SݯKJIIw|;7.W]:Oi"-r1}]cycMm'G䴘SҴI }iΜ=ҥKGzy;XcGv G6dֆd[(U<}gu L ɐ02dU,w^cq<"$2( d:1g̉ '1 J>13&]~={Vqqq=&C ,[nUِ2ؑ3(կgϪp[հqV@tQ9{VeCB2u}s\\:vȷZnիVdzטsF; uɓIaLdəd8GZΙDÓؠ߹v*o%ͿKƍS͚5UP!~j߾֬YgscΆծ];EEEiʕ?/hȐ!Z` RqE)44T Tʕ{eu[3fPPP/^5j`*V:uue Y]$=&M￯p}Zr4if 9(ss=Q\w5 ֘1c4f̘̄ aG¼pcZc?gxLKfS(?YɓNηݪoȯvlۦ~E3}}*RFgΞU+{L ? ,~ER:ud9!!o²R HޭK 0d]ȏRy9 B!9`29e$_ϞU\\wzϭ )fuRz%"+"U7(Wۓql ׳gUHs9{6,=-["Zҿ, K`1UE=Z/8SJ, 3NwaؼJҼe }g)&^fCIDO-*:1-gBLLl6GfbR\aG1Vt˒gzGrS?tfŒ~?as(Ã5%ǾTF(ͰAY'97lqS%g???eOR02Ȩ>ldr0fWB|&Mpdɒڵ֭[-gWvll6Wbcc5zpխYMnjzz[oCwZسˌ y!#KouMZTo~-ZHwu쐍f,NFOY ]N -[VgΜY3uoN*T|wlߦ/ל7TVs=~Kfs+3|ðV^Ν?oV o-zlwV\*wzT|.^Ǹv-_B͚P` U\E}~F11f:hJ%TFM7h\%tG:z)]%el ZxYGfϙRJkyP|| BJ>{Kjܹ)~Wҫ/Ԋ՟yV^?+H ðekU0p@ =)}SR믹KҴi4~XGzl6l 5x 1\Q_~v}{4~xM:E?GOWiݚ5{}=iy{K_|x?sv7ZZUXk;c,&7b駟Trt׮ EFRӈ.\ڵkK .&iӦ2ӦMɓաBZ`I5gի[u~95x`5'9괪xЪUsissgОݻG+1;eI*3|Ȇڞq~ݳG1.I|||ܮY]|uرcj޼y:~:taZndf<\-oiӆs\1EY_X*|nTTINRÆ ,ׯ5hI'DJLLTnXRI6(CiA .)G~k:Qv&{ԩSG},O\89W.ݴ`^oΟ.᳨V]˖ҔIѲe^SfYܳŋ4xN<[ڲe~aWʕ+iҥ#5t0әС/jQڴy:}'uaC5aD}]|IqqwW^:!LLsvNÇVTi?:Æ 3P>\JoΛ%*3!q,P@WTRɧTRe… ?q1}VZЪaIZ,ɏ7mDǍӤV詈M]7k%ᆪ˗~xUQS3gҳ>ޙ|KBZ|nգ=TXUKT]e%YeB`܏?ٙ-ݗ3^h(OYIҽ߯Doիբy߻ fD_uQ?YklOs^rL˱ xDOvOWVlFFٕ @c3I2ٱ͆EH0<[I kasͨ~^$gGs)yy3,+$gBbtZ$ CVU׮%xbU%k׮bty%V2_G6^s[Ѣ:vjQK>>, ͦcG鶢'%hzUUXJLOZ LH6Zs}{uJ/EoSreS-xz9򨎟_.Fw*UTaA"f_I1$"UP!KiX!,HE6:*&Ð1A*IVdr{ õcքZxՒsxjqs9[L ΐ %s6l2x I>x5lmYo2 Ywk_ 3^cH[KB< TE9=Yѥ ivF$Z7[6MTa_kyڃ5V̪E*ZkpS8g|Mgm*cѠ ,R s>~tsJhvFnFWyIENDB`mathgl-2.4.4/website/udav/udav_sch.png0000644000175000017500000014322213513030041020054 0ustar alastairalastairPNG  IHDRh\)sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxw|SONV'mY2* Z@@T_?dv=d 2EDEPٲwKe#j t7MrMgҦIJu_C!IʼnLDI ~~d7γ~9xդ{J&jf+BT*'j'"+x;w@CJIT55AEQPJJ* B!,!]%^hҰn j3+TT*}.2 ddd7Jh33IMMA1PP !)}wERHt?dL*PyJENC@IM"v".B1a0(.XHgffB`{^JޠQPh.^@Upvv(l=d/~y3#t7*}wE€2U8 \UEe@NC㔀Fs&iո)ףƷCKtz/: w@mj$$&qLV JֱL /BVCxyzbQ/k9WTA ޭ[?P`;wʀt:xxx0|.^̙3hڤI}4cǎ#AϟWX;?{~޹̙3|R-J,U:Cq-Zs,..qu9vo7aa$^=?\9:ͬ뉹Cf( @7edJADDŹ8rK?/oo>#/^R`mw\2:;v_{o_YKV,)yG흊@AQ  -_Z}wY ?Wtcc-P*&']r'[T4Z%tPi((E$%'ٙ"fj8MRr2=*FFRZٝ)SHKM-[h|_cXNQn݊Jb'0[SOR Օ;w1h@Tb|orr2v͍N:fXs,'LϏ?nҥKҤI 66oVpR !} ϒw *UD ^~ϟgw8wТE4*-jM M"x ϰi 3g 89FZZEIJLŅt2Z=n:?##7W7dhKL=\ݧOyϳ=\my'ؚaO<׋¦QWTԙ3g_p!;_/#51Nn*cUנ23}aÇn8 /\:0).oOO|:=afdddSN_W'f̚z=$`}Y]=;qiz_caG+!T*ΟPAad{W1%,Gwx]PQ#Gr'!XτqXlYcgjli-bOXv=߭*yWrwUk8 `_x{yZ۩ÀJJZNQn}ɓ0q Ο_L7i.**T *PmF:;v4)5NNLN.2ҳv*ػw/ &5%-Z޽{y A}֭!22 Nԭ[{듚Rhݹod'?y{z= diPGaذaRV-5 ϳ sxſqFyժ, sr*HzZ*×˖w>zt΅ u:t]ff9w/?fԭSԜ #׮/n,.\]t%fF W'K?/W|EfA4nܘ"wޥMRrZiÆx#U qqf-5SE͍[׌_kN<ع6III P(jPT69zƙ23.^Fm2O$##m)YI_y9y(/ 54۶};:(tOK.DGEe=Ϛsz<ۧȆZv6}:y5jKشgfWs}#G9әs tCTEQx'PT޽#G㱞6`;~} nhߝ7vbB///^Z^-IXWԫ_.˃_ Uck325k{vb?qy>x=㈰U(3nva`<<lꅢQThIĉ4~}=ޜբh8y$̋}Ѓp ndbg.wx{fh]X; \:e_~WIJ gʥ &^ g##JEY̌4x֬]Gǎ,]d7`pAI$<<__*Wv{މ ̪5=?ȖߏBcjj Q8puRr.=3T:1бD1{7fʤS ԏ=Zv`0p "#ƣZ55oFf]AZ'N8PN]VkWI,`CIuHJÍYǫTF{\ ;nk?T2>TTF^#%91Q&? {ʨjz))$ő}RauxxzSpXQ#T\?wdܹx{{vZSF<|+;vfc.?W77|ejފ1C~_.̝gN,2pYǷ.g7m@]` Y7#QQkѨSQ~)JUs{2FjUn~<߸ɥHLLA` dgJ͛\t jhx/j֐ .ZΝ;6|j¼5x:JY [+}wEmqEɾ*J((}7RZͥ؆9N#>!(nĐ j5 TR~~ie/({}'O<ˠAIu)HIo؈Tn^f,徻".a㜗Bii}Wjj*ƇQR%䑑BXzT z; ܊*uY]r]QcnKNRpqvB85eб͹B!lO ],B;n,B85!B؟"ǜB$B`qB!Fָ4B!j> !¾,B8MHB!T*T*9,B8$iB#Ivp^Jrr2qNEX7UTNNEဤqv`^+= *JnzP~z{ԱwJB*N?**Դ4SWJ*L:c흖&vͲ@6/˻=ޝTd]sTT4E&MQUIkQ ˗.c6읕6ZMll^\?/&˻<=ތ@g)q㜚f\u:5s𜜜 .ɽab9m d;*c9ԩp'˻Ϝީ7ɲNSW( l;em*==]w9=VCJʎ,ۊCkYβ˷ 9Vsw!%rFJR*G(j$&8ՎS !D!akb,9g0c,ڴkOuԪSz?͖-[흚ErmW_}ŵW<ΐ!Cbrb1~K5IY##nSjt_B_)ϝ9mSΰKE q#\VGkLʮr-ZޏouZ4^+KhҴ^>w%^zemDu:?~`RfxAP`fIN֭#Cކx7S E+f͚.3$˗Ғ~tЉCzZ5q\lQ\:wtIĤ$>oCHg jUP֑g/ghB3v &ٶ};O=4͂Ch7|)"uWd6lh|}3r(&?OٻwIٳ2yޅ``t//ȑ|,cĈnǎ[ʓ jڔ6l-[a<<K~jR/%s(*W& S}cighڶm;g|w&q RreF Ɲ;wd\y(-ӥ}! Yd w0)W6VPMc={ruΞ=kwn޼IϞ=Lʾ=|/ԗ=vkv=wIo0,39gsr 3왳h׮*UϏWԂE6%VZF{a0~aC1/_BϞ=V gggYpA_}u˿& ?~/lI򱧳ѱcy:uLOI7lذz_5B;?QYz Q&GDйsh15kf} S8/`ȐզџHmqssjժ9={2)ceoN=E #4h@JxILL?4wQ3w]`~5ڶ3W${)}56ɰgx.$h)oCн[7ZlIǎ^z۴nM%wwA.]z* w_%,lȹshӺsg;.E٧ٶ}&2vh~fuc <@Jr2 (޻ާ gi\sa.^H6m8iɼ1smz?7^x{+w MΑG?5Ik,{s)J{TV$3g]Xh{cͪ\QJX2T;8y3Grߜ;s3GѣFW+:l߱_}]d=IJ_ƍԷ1ä>4,,\Fػoɼqk[ZiPo=;1},kAAM_E7?E 6odKeFsXœZڶi-e믛4.qOd?nHBBiii }k}HKKUgu5^fMo UпƎOhN$Xxi ?oHZ5ԥY/_d,1jp N >wFGn%,_Ɯ9siؐ-ٹs+/7ީcfLaa4lJ![I,B8Y} !KY!p0ٍ&BؓXzB!cB!B`qB!L aB=?Q>z%DaӞsFFs̥Shgjվ y~[!* V˼ ڙ{֧a?{Ö4BTlY`Zý|2ׯOZZ*GeѲOBTX#GF˩W.III^̙KP{g[1QNAQO"YyɧK˂hܸ..xxxеkVޤ_C6Y۴co]\~,]!-Z_êqVZRVڴm_/-[y#Ԫ}nܹ,Oܦf4j|||x^Gc/2pk4j| 2` zSy_kY_a]>JФi3J\||f` 6lo)ܯ73O;g6Ξf̞3[/UίBLMٱcfay?wOa&:Ĵ31}*Οe8pE[(???Ν;WdAΫ~'F>ke,-m]殯̛LJ?' -]aCOT=үu=q`>?okש˩p<==,O2t`8͛Yd) -kv6mZzsTo L݌o@c~}<ϻNEc7ng8tpo9N:Үm[ZlA-h jRRB;sqtQм~-u?h޼۷1gOj ׮%SGߓ+TvdQ~t4?[n5=~<=w7 doIKKp3$FZؽ{I'**Tk/cIZ±c'[UƍXp ʕ+=cܺu#Gq5j׮ͨ#MN)I]0zH=(j׮͈ygXcΡ|bffܸ x~FaQ~t=˿1cHOϠf͚z FoX{9cL8Θq\~^ϭ(M{Cw%))F3r|kpܬ !Sug)ӳBgkCʃ/BG !⮓)B`qB!!L!,B8RIY!?%09 !Fg!"O'&*VU /o/oɳB 6i#OEJ͓zۢ:Qٵ##iذld%(au0T'ax:vꈢdSΡǗ[6)={/98NTT1 rJ(;rDq7qPlt%5[nnJ/=}B/e9#3b0kS<Ǖ$Ǩ_rp]`٠(Vo r\09Wȕž {X9[Tj777jнG&MUB"OEVkt];wJ!J"gwfamźKJc;==l'/J#̓F\\,O~^_lP6n4mYlWS tO&61K>(΁QThZ~3UTAQUAHH0~~6v'Y7f^^լY[K {%¦L}Ƹ{v6uqqeҤIA^૯g;w3h@5z4}5^L:]b 9Rkm۶R2Z4ͺ䮖ǗW`ڤxDoЛ84 ã.""ؤ.vAbo6j 2% :}}|3λz*vl,EQֽ;y7nPF nܸS֭...TT-[УG._b0䫯"0`Q\zd~:uׯ_ÜeB *HY-WQ2A K1U#.θuzIS|!+jvǰ5OҾCBn:LqVLT2t(c<Įݻ9rd-,,QF.rYq%հGXG'Z)CQSxzysݚ<$ǜ+8O//BZY}6kC933>+uܲ6`ʕߏsΘ1&jE1tR@1@Q3dP^xy4u93g6Pr7Ro {@k%ʱ8vn߁Ao0qF:4D'>e%q.qmcB뎉6αrˋ[_ 0)Ϳ++0Fe{ +z1GXG'Z)CQSxzy} Cr̹"$0-جqF= &PJeB9y$'MbYۜ9?C{|{TVǏ3~D2cǼk+}WWW=ҥwߖ*׻Ŝ93F[*ir,..w`jQ@D'.EŦ`X&{{PFɵkשY&=X͉԰yt4nԈÇ1xPcN;b2fϝ0 +F .73 /?www}T@jke7eΠ(niݸ~ ~^.̉{5=<=?^8{6yOvXvmr^Nw;,/a&www|}|9zZU?;v5jJ,lBRu=gQHYXYDmvbo.4m&gʸ,*&B̓il,(nߩdf1+ƓNaV\%Z89ػ~Gɡ\-^ !2Y7!1RA*._LjNSBҳ a>>>DӬy34y@Dx _ʛg\={/98NQؤqnܜ'9r0cmQ ||}%Y_vBa`cCBlUBQB`\**BWΕsB!Lv,f!¾{,Bc#OEOLT_?^4 jjTj*QUe4y*Tjջl*ڞ];2A?=hF!~A}0 kӱSGk$5NCŪ\&&KwNJ '#K]VvO"뱑*^zFF/*U>E!lfb0kSJ8;fKw9 5EzlrIYXʜGJaOs k DD{Gv,BgźrJ%IKK#..z?A/|hh(7@ZZ6P!L1(L7˯ h4rL~ĔOH8,}z ;;FRjeTR GU!!qM>!J1s={ӧOۣW>K,)UE2dFo߾3_iSb0(ٽŕI&ѾC|.]Jpp02WWX#G |m۶߿W_VKƵYW L zg&AAxzxuzEDԕ8g /""N:YbvЁJ*ez+WP PW{q`~nhLbC\\՗Uy1`z:uЯ_9*.1UZe: Y'YG\]quu)􄃻p+ޟ0 k[Tou۷b).!Yp!ݻwcU zu쐡Cy6u իWGSvX*U'UƍiO IDATĉHLJZj;eb_Ϫ뜩jߢAi^Y8"sEi|ac%0tc״I'x¬D^XP~|'9xvfȑ8Ǐە+\2WOaˤk cԨQƿ\f\I5 l+VPG`^sk1 ˋ-lVni;f!Ҿ];bbb3w..,qhԼ :Fm+0+W~;wƌɗws1gle:woHVHKcqqqܾ`V㌒u(^O] ͆RM֎پ];>iS&< th߾̉͝/r-^~snz6jJZ.ɹ"NBo_otz= JP)(%8 TF5(oYP={ҳgbY{g bL7p@cׯ[aET#jTjTTdgpqj֨)ѶrzLL:oW~TDܾSXYDmvbo.4m&})UWdP {.SJ*dbOE.,<8Br;df1+Ƴ˜o>NE!&4k F'`0S)g\={/98NQT26nNɓ9r۱eWp||}%Y_vB_PTCBlUBQB0NY!p08 !F 2>B! 9 !fw<I|B<1Qe^8iPS{"VcK"OEJ͓zۢ:Qٵ##idӃ6AuBpBְvrc(זI&kN:_+qr;{/98NrksLt4sMc4lx/!!!Y~^6ٳmNƜ9 ͛3f *ѣF1߿ 3gbKhժǎͷW=zPf <==|P RjgTb Z̓`lRdqqZ1s 2QGӷo_V3m[\iӦ`Zh@zY0zb䈑1c:ЩS(ӧOy֭;?0;v믛QTt宼v|Ŋ9rڶmK xdi\u%]m MAٍ3@ <=<:=""HWT128[;w:PR%lB=| @PPP-.ީS֭1IVWΝC&uЁaÆ=,_7;afRId7s%5SK$.fKn-*.+ [*f B3zù8s~!1aW8~8USLA~Arsse0qDYPZ^ wθFm0 Mʟ 5q>⬭vqZެA1|x v܉OaB+SEM4WǏ~ kyAPP p5l  i GDD$+ff?/\UoaSˆ)DG=W+Qs}X ahHsGgaх8= 2|.\3g"44Ta7+\}b1ydcݫW/$'`ĈmIIptt12'ggDG'!bJxxxȨS<]/** auJI<N!i$Օ+Qsf뮁\p9wp],, `䬧i0s,7oU7/|.NNF6 FFF|26l؈.7A3f`aDLM;C,#==X\A/aٲX`YC'~E"J܂ƶ;PGX +--铧H:gFKKKHH>S040i o"UMCMؽ{7@'gLy^1g#4, /FhXBC`С2m z%0 /[/0xi@Q1,Hm*,aaiA8ԟtNu/)9P-5W7~سGa\} '#sӧOܿ'֣gOI- $cccB\NKC~}<9Yw߸r*lRL8j4ˣ}Vfpq懴.'QR\Zkk8ҝ{N١s/Ʀm>9<MQ97qןU֥]쿟{iuۧt'm+1pjj$BFRpqu=ޏ0ȄP(v(Lۧt!mO1N n_Wp2rvusEfz:.&I! jWOsqy鋀Ҙ.|/p6!U,)B!MJ-ML!b1]&Bt u΄BΙB1uלyL!TY({X$prvv(6tY1cq`Ν9߲Ӄta ]BnхN9lڔ(3 @iYeؿwCz nbНݾd\XPD4.B}X/F6dԩSUG !Dwsf&:$5whŠS וU{pV211AeehhLT#t'ъnFh+qYtZ ;+|љӧNBZyΚ`]8,-tGSUU:n<}1kp2,FgjfϿX{y&ەM9x(~Z&ʕ?2mݶnbX ʍzKw%UUUFt*.,FUUC' wIUw>|ǎ}kXOJj 0N>\-9p&:y%t#TW"WQn ӧOqܹ3]ejf "k'q9kܸƖ/[[[VհXnw֮رc Êh|}'=*HHH@ZZm^^^4i--/O^89Itӊ2@rFt }\!C9iÑgk˫gϞjia=YYY Y|-Ӷ8|SLA~Arsse0qDR[Z^ wθFm0 DMʟ 5q>⬭EH8hͶ#=%Q\T(\z?~kVCm-FU1^8"""Q^Q035y 2vFJ'S~5P %:g~݇9wt]4SViV)(,QQb1yd)^7db"MEEE!z~TTTP.:c݉WY"$mc|0uw\p9wp],, Ʌ[8Y]m4g^\L6F8lpelذ0{,̟;@tDDF5&66Ǐmwޯ롎HVZZ'O0Ju`===;:.B8է6燄͛ a!sH 4!s<`og91oZDXZ(BKH$lQU] K Ǚpڬڗl\{yjiC^=^aϞfcx7olw2m/Q1!._s,xo\r]ms&W#gș8q$JY`mm'Zpی aDx1 *rus D1dkYlrUq}:hjiS㧜bhS ו89C p9[ )w!J@ h;BQyPng$W0 ̌LBmƿs{ nbНݾN dt]BIq MB @ /BHc5gW!61B!:sE !m-@#gB!DPL!ΙۄB6ffkggea jt"kXZXIۡB>9;+1f85B:sgl89{=ݡ \s.++غ)QRgҲ2.> k;mO1N n_WԞ‚0 ]&CK!BEgJF6ݩS[X]ݪIZ.D!mH]/7atꨓsu%A7ڧt'mx<3òj >I4n&Rhg3#ΦFFFǍ `sjm:MT >_|'!,&l[]*î; k}F1% &ZB( %#P\R*mN:ΖdLZo޽qPb&S3s|&A RS/`ǎp"5;ws o3v0mb>03aypR  52fؽ{ =1ut8bbN*AHNŅ9{Z[o-7}eXR[VZÇq_jjlKW\3 YaĈXbbbjJXx ñi7>F%.W'R%D,O/йsg"$bD"|BFˍTSܾ},_VKk֠g_5qq2y}uY龆FL,˗-źϿʕ++&~-Re`Æ pss?e'$$ --M6///L4IΖӗ'e| \(9@ggt17txDeff`PNڪ9欁d~sv=Gm#ϹXx1RSRP\RӓgϞҟsrr#*gggJKK;P)S 28qyOp7k+i{j10J݊^324#:G"$\..*0gNK܏>RXJ4E}rZ4ͫkY`eeD;{ e~n|_ZS?/((ap+)j `gaTy>=W+Qs}X ahHsGgaх8YiVimCزe i^3*,QQ͵'/իؾmLLL.\lO׽zBrr̵㤤d8::J)SF&}lJI<N!i$Օ+Qs҅t͹ba;gq|&u??۷&Mx{ zx۶mäIs憇7٧30"!H^.-LEq5bcc(3r<_ Ca6O#a^=v ,--5 !\?ϙUu*ly4&6'"죹,* "A3>D24|=rp"4, yy`ooА96t2e\~["$DIưZF"f;h>jXXZؘ( pBòj_nq}mc8p`ڗWwKy8zw}W]'ߑS(D4BЯ__O W\mW[ șt<4r&pquEfFN8bD"X[Ʌ$vB=h>DEnnpuv(<.6]f?l]md1,쟃{iuۧt'm6=[}!>`jj$xݾ@|>jj$-&Jd,Wq ,0 ̌LBm̴} ObvĠuE5g vuusEfz:.DmE @ /BHcZ^Tb1WMB!mc&BtLmL B!WșB19B!::gB!DpTl=,Ca~"prvv(:, Vlǘht0ΜoprVA/!D]D(++غ)QRgҲ2}~5m}A1h}AwbvsaAz \BiO{*jPNZU_uuu'탦%=JZatw,'gs6rfevyojfG2uȫSu.xz8r;Z:D9UUU(--ƃHZ,~ڇ*s!!8VcL@G̼I9S3s #FP  Gaarm>|ǎxI\_}z*>$sLZaY7id^7nӧO K?Yup5 IDATk6{,Ӥm-ex_rn"D,#Lc<O>_sDHt9b7E݄#{oذnnncl|||e}V\ VX5k8\zW`ݺuy[cǎEhHxm{eSc":>>__?DGGcĉ*װsgJ_!22>2e](S^I&r_#!p6sZ-QO+Hҝ3qvFssMGt\ffX夭[8bn?Hsmsvv (--G/eZ'++ 2eY|1+vϞ=}ׯ_L_cl| _bHMIAqI @OOOaQ )S 28q3}qqJ0 $Hʟ 5qʟ^\OS6D(.*Bke7>*oRüy12үZTi@:Q6gΚ^ VVVH$whv4 GDD$+ff?/S-)bYq(MO@J$nsuCCRYXt-ΞJŰOq6Y[,YXPMGT4y^z!99EoRR2U:}+x'O[Nֶ]O>HNIq}=_ö^۶pE2(,,P(٤5_bcc:`[zi_JKKq)0FlcRR !=ׁ߃MW߿d_y)9b8 {Ch :TfߖCM 0 9sڶ 4!s<`og91ok:.6agQQD!"-Y| Eyy9^ttDȜ`͜%%aw$NXZ(BKH$lQU] K Ǚpzv-lهC7;w> }݇qC[;{ܿ'Wϲi:&/}Yx|\c?Oʕ073 FTa=Sz x7klkg{w^>^]K$FD.'QR\ZkkꘉVp (|PCgG"W77i; BnNvņ*5RM#m}jS m}AwbvgRAlmBZ>WvV*K5555mB!jI,W0 ̌LQ]e>Š;1h}mzp/)Ιi̶+2ӑv %%kt8..ϴG" ȧk/OP+fk\5E!9/= ;gBіRV*B!(v%V^i%B!D^6v{TBQCtZB k{i2!M OkșBCNaΙ΄Bvx[;AF΄B} \tO._CB!çR=|XVi#}+ V_{cBǚBZ=BUJxƍ7e<+ srnaFQ+C 92N8){{;$%%=wCL#9B!mJ뜇 SeRRR2gN2dJd 6B"#GCag ^[fcٲe+<xmvj\&c0q)- {~^޾pcƾwRwwg;`a駟eطo?;n䂠Y(-S<7Jd-[bl]v?1XlBH\W^EUUѣG&Lx <@ii)a\r~~M8z<‚/"zJ\ߺBj|zqJLDܚ5A눋ALl,=l[#v܁70lؾ{l߶7gc'FDJ+iԔd^ ?Lkҏs:N<epa8`u_[976~ VZSO?1?QT/Mұmnlll~}"99z  Drr9++_|MX?Zk0`G|عKaGΝ˗a_4ۖM !k/舿7pnt݇cˣV8|J1刔d8:R=Bx0kfݼ '1n;5)ݻܲ#}}}H$VE!I][{XbxzJGzzz0 (]X<vAiY"!// ﴩc͚x\|&&&Mߴ91'$yyyEܹ /(s.]q=H$M!x'\`yڡ+S =(?z9w> S'~=53 g1dP!EKsBr|=ݳ~J#!__R;WyB!#5{ѹoBiXS"lmtJBA3!c NE!+u}1 !JE!_4!BI|@ B!hQChL! !h:!m 6T*Be(/v(-XNN{lǘ !D;segYcmhș0zXR%_p/Si 0/_Ρ3!-`Y !^iLH,PLẸk풕F.RV>ϲkq&ò9Bp;YGm5>Zŋ"ӵVhoF΄)Ok|tή{z6lZΙL'm`i6!OËjǴ|ʂ |xTWWcaؾ{;w°ᨮFmT8/)SCiiqܹ ^s/lٲUf{öD6ذa#}! 8r(^<v酸5ȑ:,vз_|D6ԸMزe+<xm&1۷ }7qrAP,)u X(c=JziQ\\"Sno&v@7;{zJ?V"r*<}O(Q2 dkJE蔝vw~{v ԩncb ظ5ضu :u$S{Okkv2vgQ˔ԩSXukq+"~f9z<‚x"Wa.^_>Ñs:ۋ 󥩱C[q1ȹyq1ѣdʭ'K?F8u8…Je$Agۿ3`$K8 V^kpX+VÉ*Փ(^ $#~m(Q ]a<o$`x 2 Ǐ CC<|^~.^ 55?MlDؼnN[QQHvŲc_AA> 'ڥ^{ ,Z wwt`xԨј1C3Zn k715+Fn?/܀C?yWJ/7o^n{oMp)I󊊋o9g+FIw|=ݳ~JT> ]҃kJK41|pv] ?.턼c^Ŧov̍a⏑Rqܸq^2y>ӳg/̬,Y1u3Yϗ)T<ܺ$&?_?97ZjO(*Z[lmggg|@Ri^NN|}|d"88X&z(Kqj<)S 28q_\ofk];w#=\JfX\T ===ܾ}[a]gã,_+++H$;G8CXTVV"X[[+,olI6uj 7a^}_7kǏ##)6Bڣr W˿iB)))ARr2}KZo!)9Y:=q$v؉cGۄp)]z !ڵ+qUcӧRS/%$+X,#G-䄤 C"Q|٤W/G4El âɤi^^z!99Ef{RR2UG,#1'P^STTs9= tj[ݻ`jj*ojjaػwFYuwpuuŷn»マCЭ[7zm۶cIɹJ2'8b]KGd"??SNCN NFFH|_};w6;3fS'cx11qXsΞ=^zIwWDG+ge]4cFDԴ3b1厦3/|.NNF6 FFF|26l؈.w_Bjbcc(q6b4svڍO>X7/;vœxzx`HLgm|BBYTD"faaDR 2b`!s`n<:&/0i??_,_eˣs6QtҥK07|>ݻDdr+F!a˃=BCe&0`9#G Gaa!Bwv aCR=~~Hؼ 1qqX`!A2g} !rxg ]aM >?S널COO?߯x@g Qe !8mhLH3Ιn,GV"?sϺo[і# !R֦R=K[ljX4[Rݺ]B9r/ ;nB\Ԡ ˔߹sȭD6ҤȖ-[9vm۶l`߾Ñs:ۋ=*[2;C`BjJ2VZV^Ee$Agۿ3`$K8 V^kpX+VÉ*Փ(^ wrcDfWx'\`{}==;x #`xmCگ-XxKMMf`74s66ob[̚Q#GJ%&/7_<+\]]e7˯wh̘!ƌvGewl[lpI89/Ds*})> `N:777i^Qq1|||[#Gbxe(ia8t=?K,A_wwicرHKKSB&M$cX?{ O$C W S̬,YeY|')c^Ŧovʺu+>2y~~ snĜP(lvfV9oWѳg/]>2e|},R=YYY DyvSLA~Arsse0qD8?W7&Yee%ү]i˿zzz}bi2;ih<CC-Sq1,Z?h~EjWm0TǏ~MSlG#""3S3̟5g58|HeN8;v6;:uJM__I zrDJjL^rJ2_|899!)ە2ej f͛pX~ &By{IIpttTXZCR{MQQQӇ>/Os5~8/Ʈ{PZV'Osxk fco݄!{.gϞa3g ""IIɨDRR2"#!xV>w.""ĝ;w0sl+=*Sa%Ǔ'Op|fl9Ϝ'OPYY'OW.XBM4cFD )<?@RyDDFb*3/|.-_]wqL0Ac(Qj/)661-*:f]BV]a IDAT``*L.φGbx.]q=H$^5 EEE C^^[//²ɹ kk(L{-/"4$jiSǚ5| LLL͛Q*VaCI^^#aa˻{{;Cem??$lބ8,X à~3Gᾄ`9\[zCOMHCø[@]7ņK4r&9F΄ˑsS8kak~A!< hLH3X%!:s]P " I!.`Q QR @M[!GMs&D@̌ @O #c G3! "3=iiPR\p!Z$ I{9 WBf|'mB!Y1]H#Bt u΄BΙB1|B.!!EY({XmB"5,-,I{9@vV6cqΝ9߲JERXYYFKkkBp/mV*9@aAz"!.qu4#ETYƍXIX1ViB!J`Fq\U?8rޛD.@cR y_ԘOߕ !jM36|d`%AQa…J#Ucm^<^ *kn]W!bG Ǐq3xdRa NȺFV"xÇ>r+H|YkԒ%K雯驕u-hnlPqPiBs=sgb@'LMb4)>(> bYפ|̑G叐__dWsJJł3[?'¨<7V|s_߾7n^{5K bTq%..t#&>s?H&xp|7^ SR;w`wѻ30d0 N|.b$|]mV"0 uWXl[lo9s7md 6B" ޲e+x^صkwz[N;;{ |e\JKÞ~/uǘݻJ?+MqsQ ;nۯ?~G1wlT= GV"۷ }7qrAP,Գu6 [; -[eQeX0ҍo5}2nH$?y;vwuxsL7 >HM;v½o?D>|SON-DtOwc„QTT,S{/艩ӦDLXuPpwkk*oI󲳳q=X? .2үE-n:m:;իVx0*6|%ޝ2XQaDĭYܼc2=v Da{u_[976~ VZSOG?bȹyÆ[oۿm[qz6xzbaDOq yȹyErrtL-5dȹyN2X0Bر_v|n@8]Nle&<[##CmXء >" _W=܍mk6Hn}޽=m ^[nΝ;0k͛'gɘ6}\-Yڵ+~TΘD});Ν=F"AxxLEҎ:(Qj+.xXÆ-7||^{ 0DRg>r7|xe(fVTT?` ү] ''˹Yl}V (K<|7~I򎁕IѫWOÇ&yrh|QFcƌ1fhە̔y)Iߺ%-SZR"7yQT]4ۼ0iҤ&|>w|=ݳ~J$<3lH+Vc ~:)؜[ظaLryyXc?tk1A/kkk:Vgx:wRnW&!!2y={j.oo/}}|Ӓ={H_wb.7ѣGҟ[:~WfVnWZch)=P(sZƍ SK+ʙwBMQDy?1C}ܽ{'mÝ_.⥷ ZlGv=zHsnn.-^Ԕ76Yg@R-9t`cLL)ܐi2V3gͪ:q//D,4u{Ih4#%JϚ )j_bafj›݇+1cFZz:31z+r\z !ڵ+q&e0kfݼ '12|s Ï?Rz9"%5E&/9%/T&$$wr뷺;~襤 zyӻwo\pQ&ŋ JbX'/33P#qa=z`۶Bzz憇lߛp{E5 Fawa]903}w;wXYam7Z[$BR֖$Kl<>#o ={<.7-gޕдIlg߿moiZ|*#-Z`HP{&<ѻW/6x\(~LCbx$%!" Ws1Uܺ?۔}*rSNGDOL;lˆ,j&I(cpquEzz)ϷQ&ɐW7Wg ~QQ[VViMTrDGEͭ@Q]f˙H:pg>܁8sus|j6IygFDDdnc^H#""0,d,r洂DDDs1q=sBDfT\^wA-Z&)O1 JEE@}N,#Gp)&|| ՓrcvЬEs}IRTB*"A'I%x͙(&K&ʙ(B.gLD L^ ܿk4Rr5$?_\VD4uT.cϞp(TTn*T4H-gQ=z'ND&?~<6SVZ7D nRb7}g_`eY/]A_|ڵk?`UUѯ$%%߸q}G>(w[;}6"}:._=֮]o6B^hf#_A+^U[1*ٕmx(Y5kg GRro4֭G Q|1֮]%M{CwZg4h.\t\@iq.6mڌ͚ͽ4+WHHHԊ[󇋫#,\gWn4i n[sCZ,yq¥`!7]CU;~x\tI-&&ݾ>;`` Q"y>e˖Y_F©'pu̟7;vn=8pBCV~z۷?w{w{7.Z.@X,[۷wՋP*/Ɨ3#e:?ȅ&M Ɯs?xR,_WcE dRe9ss?W`8u4/_MBȳ,`̚_ǎ<#ƍSN̛?K/װd"|3w.ٝmڴV۷zQZv)S硫;ة3Μ>m~۶\ ÇN:mиqcs*Lj#Av]Xbmy:uiӦFC8{l~aaazz-'vLM]`nUTUj,4ni=zL0!Ɩi ;77l9o֛Z1o2/^{+*Hy-Lf\3ZGk+bccѤqcM`ȑZ ŋhӦ9P(뇻!..Nkz˔sŮ[P3vhX˗c輹|Ĉ\wG|Mdd)2%mۊ+b߾hּBC:G&Mp :uڨlmm;[$ӐT\yRRRu!{w=$<{ ¾L?%!S3&1O@}y.D]~3H3e˖5Ν;%VZgaj[M6/?c߶(ǪU)'OZukk,ursØӐ5j3ZΜ9'Þ{s\\ ˠ ۫V'Nj?~Ua=fÅKQ]f͚k+kX[Yc֬YǛJ9 $a=T\o@߾}{AiqO 6o6l!<oJY_nA?Ǐѷok|0L% oQǔ/_GE@@i(o]01F IQ3ԩ(L7~„q4h0ЦMklDBBB?.PVml0L<NÅ 098̙uAago6[ ?AD3~G5Q9K(Ԓ 1zX̜5 K}U 4-FD98::IXzsU^ ܁.]9b?h<1cOOO3m۶Q̘1 A&w 똜2F6q|pܽw8_~͛ǰ0_&L\.G1fhr9\Gckcر O3zZju4kakVc…8qr9ׯѣF= 0$$ l8FoK/#(hn0}Dd5r&ʎm$"g¿pquEzz $E&!==n&)3Bmڰ*\h#*^ [5?auر7TXQonƞ/'Oaʕuy`ETT /BN V+^]w 4&$8 yѕ3A^+»LR5HSlu,ŭ[W]h,qq6u:N:DzwѾhذ9_Ç`wV1,6*ƏM6Y=E~;BdDǩ _2@.C%ghg( IDATk;;ۂNG|!-bN&aXb%;F#FA={ݑO7L FΝpa۷SLcb!꘦M ,G:uZm^ƜOӽ{0p \ʕڗ VrFr ʿn#rGi@dd@nD,S~(6eLK,V΄?Ċ+ss|$~ڰ:%VZk׷nBwZiWMB}0/ѩSl2t>ӦMo~~~سw/myl僥~d^TdTd%b֭Ri"r&""0Yӄ.$$DD_M_vZ]حMDDd!T}ج IIgD\2$)p\w@`Dtp\kn0I46| 8bD%dI=#N%If滘49Iz=qM3WLϼ8ٙ{+%W@%q+W 7pRz=2m'vg* M>حMDd!$i!I4鉋$X; X'p@:~[w/'뽰Ago^ޖ+-p=Ց0@c_ q/% -8=C}6ꉛe.o,S Ij-ֳ$RƵ$WY(ZRweKp,E(+_9l^)n(+P8!Ek@kJ*)^Ku?n(TץʸʸBѭ T@<O!` MYz k4@kilR},鈛RgՌl9YE˙,BkBkzf49goXfkvEלQ^shkd\"6 I:0JDGqV"Dge!qʸ[[m[YW4q8fVu[TvW†,]ڪ/[[m]_Y1ktikvkʸzfx~]Y\>Tm& /)BWPtn?TlGlZ )hhņڥ_#- R+㎾ܭm$$iP .e&VlllPJ̚%:ܽ>DVFf-W!{GIvնZuKZukt1fo Csm+Zu5{-[budвu[5YDDdhgϞ?w>KĔIpϣXs&,L3vxԯW߁N``ݿ?WeZ"Ջ.߭ZAcqal۲ B.s>rVY3qϣ9c_&۲{un-b.7YDd8CXq!|٭ݴɫ9SW`3PۧB/r A7o{m۠dɒڵdNF5%JaW7ǯ &a #xD|>bsuL?e˖1iDd8CgTל%)=ۙN]]]-O>U\B@&{it֭[4j ww%dժiGjԯYn_w%?+YI$mī؊B)%FcC1Z[,ՑOxۊH2Er4B/lם7/|Uם5V^CV t_w)uYJ$|(SFIyy$YhmUw/p?2}6mيaCO=?g[I5OġG1g| *zC(g r%"8C Pfk`ْEXOHMU<̧VM<{XMիUÀ~}غ yRkHJJҊYYY!#w*UqNGQg:#̕,:IH<=f7{w Ø񰳷-]8su Ǐ7*ٴq|3o> g''DE_Ĭ9sPlYETcء0JaʕSJ%h:nrΉHTRDER{"խTbr}HTR=wR+ΉHTR-@1]n!LD$[*MtOD W$nl$n7OL25j6g+3)oDDB1 Lm玐8H=ZR;z #u"qRK9Hf K-W43H T9̏}HOcF=qL06,g a*RpOx+Q>ɭTTV*nm"""K# TDDDd6PżLDTrҭIx*5>5g""" ʙ(q,Yif˙T㑚 Q'G'xy8׷R݊C '4|qnOADDT$EGE!.>^:>וsjj*ھAn'""*~۶nk9fW6~'U8 (*gNFDDd^uY[΅ak׮EJ`cccTHC^~~ Ϟʗ/5k֘;"21SJ$IZ*W#G")))ef^R &NTL4 +Vs]斣$I8v?~cǎkꫯ0gΜۘ͑Kpp0ڷo(<|Crr2:ws_)>o+++iw WUDdGQQRTw+WMt~)11Q(QB+.44TTREooo;v ;;;QBzjqeQ\9s'Owww(  OOO!In߾-<<|}o}᫯?$Z g.הYn?̬u^Rپ};]q)O"@rŘ,uVΝ;D@@zqb˖-:9|Qm"22R} .dMŋ"::ZmVt9ĪUD͚5u, bbbD ijgϴjJ_ZD*UO< 4z/4h RRRt#[L=:GgϞwu։rʉ;v{.}W-5jZ hBgf^άf͚bժU"--M֭[7=Dd:yn9ĸqŋ?L׼ysDGG###;,# ׯ_~~~5jd9N5PDHHH8[[[⫯YubСXnܹM'^k{dd$5jkkkXYYA& ׯ_W111x.^RJ!((Hoyܼy]tAҥ!I^{5w؁͛ݻ7~u~I4DGG Goŋ:c4kҔ;/Uoݻ7/_fDd|naňp)!_Moٲ%5jÇpppŋU;wzx܆~~\\\p,1...5Æ Ӫ]nDd:߇DfMC$&>g!DϪ*GAڵuCk׮É'p海GÆ }v,YO}[[[cԨQӧڶmwVvѲeKY9::"==]q>"%%{EժUbN8XW9KcڵHLLDjj*85s0`.]ϟҥK߿o+VVZO"""C߾}{:txv܉}b„ ϵSN8v>}Q^=Dzzz" @ 777ѹsgqu-[u<ÇE˖-ppp-[SSSEJT?~|[t2_sDzPXtVLxxxpww"<<\7|S^Zk??W+V{+U~5 ++lϧY #uy]s6]vaXn]7VZx"1tPܼyQ}9[&Mž={ C ۷+H ʔ)ܩYT$6mgӫW/իOsQDž,82 Yj\JΙK= GuDDDEՑCs}˳խ?r$BFJPT3ЫGΣx*[DTȥm Z4-)~mrvI0s# \GcHHHH\#7$L*2.B6gdpV7rurNDE%3dZ0}ER>-g"*2\J$DB9yVDTdȅ(V#RSStcdSQYp""#Ŝ9sP~}L2{|9~. rYbʤ nߧNGiŹΡvX}r?3j7Q!& 4ZŋZ*֯[ ooo<{ Ϝwὶm16b@G?{ }|B\\-^:^3#äXo<)u+-g"*2\([y[-[w77XժU Kջeu\lU|ګ7*Q{gOAzsװif4mn]  DBBVywyFZ>q,4m7ㇹs!-z?<^\@k]V,]eaXV6X.Y2Xlb֭6y6oێf̖^r&"Cy-[b䨑\Fٲe1`̚_ǎ<#ƍSݷcFĉp?عc;zS'1k,̟?޸mnʼn'xbriyKQ: 1;^W*4lXm;QrW[FDEF^[,׮]CU ѣmmMh:uJ`_q 7|6]+Vʕ+K.E]KC3zk#Z"{!MIDATMn{:Tժ׵-['Oڟ7,9N*5VDTd|m90eT:y +++|||\]f͚-ŋhӦVNBd2cdQ>6}MU}{^LNy|dDTMOeooƢa}>|849;222PKlI=XK!|SRRu!Yf<&ŒCTMJh[Y]|oTo?e}O>E]LyΊלȐ ^ةj 2ҷ?GGdV8{6BQZkլc[vcpQ.]9~iA{\Y彨V&6lڊys6-wUNʙ<:$1cpHK{Oq+{cx4"4nx4}) % _χ?~\=7mDRR"RSSp3_a[L ;Ƅ1q:^ƍ8n,ݽձyV6oE[ [hd66ضu ʕ-weԫ_߯:nb֭Z:~}h/5¬31gTQݺ@ƍ5m5i&ԫ5k`2$vM[^=vݣ~ڪcQ=ذv-V.[bsY9c[i1\D d:qtNPmмYS;pǶt9acmv cF#$&*XzDDclK^1Ir!2CXa&j̧RQ#ӓrȘi&cR↓) at~kNbLDEGs.x[9+H(U3HH$ɐ_/7vYgg@fetfWxY[[<˕91"")( ++N` \ht_Ts/ưjC Hñ(+gj|Jȴx_9} ͝N\*xӠ~6f;OL]U3vBerxIyK5X SQaWbEsP$kX) skKȜ'Gs&zV"""2r}DDDf%$05g s( yY!xYYi^sDDD'-!4=CEg"""$n{Y>hm"""s4JH-t;]DDDv;U%=ޔd`#(0"""sk%fgE^Jr%dp1[~DDDT;O*G + 5DDDP%=ԪYb7IENDB`mathgl-2.4.4/website/udav/udav_opt.png0000644000175000017500000005133213513030041020101 0ustar alastairalastairPNG  IHDR#^2sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwXSo,j-EۺuV[VDԢWnUkն(nqT8D"ad@|?ϓs=Y/'#[FrVP*EDDDDT*؊wcQmKJ9bo!QdX ]ׯ!KbǍD@Ft9lE_*B:LZ"""""" hc" (U ޷M2դ  @$A$}QW9m!PJ!s_ V@Ey{ )!)2T?)R4Bla R#99 R Xdo̵nH6(ײGT&+rK^D2) $' kXUAi`]t$$&Fps+ HRD, x nߺG{XZZT7u}F)WR[o̹n A k! S B"y$ORzx\yApB^Je)|=L4%d2@PMeʠ#.; gҰ""-y{_cH+++.]իWGv㭵W^A!aaa[BPtip,YvŴiQ:vO6m*ΘoX7` 9JAmo*@,NsXY=Xyx+뻰s)z" O㟢{!@jJ diidoniiHMIH'O@D(۰..3w.~ֲ \.r9k=To֦杻y箩AT,io?z}dTuK_T՟T|<_ug0"kXXD"l8z  {{{8vlllТE eiFi{^mHX~Wǣbѣ:[N/m۷!j֨}K]&gu  =+6m4d[;u=o@t޽w܁5֭Ç\rϟǟ~¥KѐJGt^_ H[~M`ɒe eto 2wʭWo=7(b3g΂D" Xr%߻~UO%Xg|#a >.)&Sae}V| xH$!r}"J/^>ꕽ~z[ w?$e_:U97IGh_~J*U'?6m2t WcocG(~iQm[7o Ap }\WwFkW\)!C$JX OX"#"1qn\k@$NH()r ].@ Y,-,, I22~ ]n"*|iE7G*"""ʗg'ʕ/H_ԨV{wի+W޽{Z*jx'swU㖛 U`:vDzz:\![-͛ͱ.N?l3ɳ޽{:a-T(J$%P]^0qơ{=f,-[ unQQW~v: &Ns~Yg fΚ Y ,5ڵkCk~۾;v0n%RӸ1=|  xNu9e 5v?;pxn厄;1 B^VU`}B"ئ#-- 4k#"Ū_ř3&&&Pv-\.ǓǏѶܥ+ڶm'.:rϺkfvII<= m@*1Xm&j+'ȢU-'\h * -- w}c񒥺7-ޣZjǏoޮT 7C Ez [چؼe Swo_!eiiXt);{qM|=k2h.ۈ  ͭ&XacWǡ#g uZZX =~Rm+QHMMئT(#ؔEםQP"ɓ'?~ XRudݳgOJ "GÏd޼sGÏC$Сd6m Hpq=xǏC"m6y;kݹԵMܻO]&޽7}GrԩUC#G#aaaM?Ncx,[իO85zLu=o^ƍ'"0zXt˖-C0o|"*Jo JA+ɭWҗ8~ϟnC2muh 0.2 O?'Ц:-rFи+BW{%$`\Y+ EiyK' `sRGq5vtD#=My bVVV¥Kޫ*kG''89bJii|R\WJ @*V GGh^rۣ[YؔyS33=~8˸ ru p-W?e;}ږWqڶɥ lm HˑgO"S(ur]X@X$q2DbUBi Iĸ `C>5T?)>xwnׯQF /_iiGp89:zT.KdZߘ{YX u  Ei(P!) %mZơ?hg pTvvx1>ŽwP*aooZ5k|pvrRU߰nD=C}e=9U넯%cdB.666E%"2w9OD s[.,~:{OԀ0F rU@Q ߘsݙS(""""*VT з0d0QQ@4DDDDD&W""""*2r֌1y`3z`KDDDDEF,Q1&DDDDT,Ȳkqq-""""*ffDDDDDESV,H.>)MU\Kg\!)) R˨+)%G%_~G,|ƈIa)]| -.drGgO߫r1qq(ekߦ@*tnJ{ς04z`|3-$p1usHLŘΘOeоDž*2~~(=2y}Y0zTŷę).ƼL`Z¹@&W:L?qyg~8 AJf3Q8F,/B"""""Oc%.4꼏$0i ,^u_0iJ!dɚ=vft{:vޣ]q ̜1݀&/p|K8x0feDD%j=FX[[ce5uz6=kw>&L-[q7q^J?'Oh3!Rv:tGCot;vFGѭWoxz7FNnF( _" eʔ)1;h:rӦL29˘HDO,T"a䩈)Ӱ x.*T(G/?nK'OE>asʕ-oV8fƍ6eNŮ!(pq:ñqf,' 7ky1 V̀>Bd$6Rk(W,6ll!*UDykɘHDc`!R_ե͚On=Уgh7_M6U#}`cm {{+8fm(Ӧ"I![0>ލ`kk F ڵ^A*<'e4{~?53_1&-sX  V&A, ===T>epB$^| 5;ԮR+㛷nQC/24_~}A MD(_3~ٳPeƘHD̜Њǡݻx-5S{յ(ffLk25F@MNIຈٽgn1&.c-=xyXb*T(+av\<|H]Zt-'\ňaCQlYH$lWG5q!ƶȋ|^] ӹn"-2&/3{ZZ&L'V͚ڵjaⸯ0~dd2V*v zܦ/‚Eq!2)))k;zV~{T>s#nj|DD1HQz' QÆԡ.?F`N͛-1n$K6nCF |D1p@?b7+w>|о#0:0&L5ͬ6oNPf}nm?}]nUc[~}s=F^={WQQ]w#lژk eL$"Y n!55ї/cN穸MUu\m-rqqHLJ³g2*lnps{ES7Oߘ*17l=1 鬿W{UM2=u꘶!DG1MDDDDTdf95cS(o3g8!k,QqQ!|hnGeJggQǘJS9bP>MM*`fZ`>,=2I*@}ś-_IIIhcS7 Ak?? ݑ~~G^G12SE"z-0/,yaLLߪi%""""=DDDDTX%"""L0E\<re⛕4Yq#MGkvJ%/\plܴ paڹj ظn-.DFbsH^"2Ws#nj5 "YAspr$$$DDF=0&ig;3vPiڧu!ys09X[/m^ZӧO?#Oƣb 8X.Y5!xJ%4aCu:QV&l!'MFl\} _0`CVvlwE_57󽽽WճqԥhTvw(!6n"X[c̨3jN1&_X-dP[˗1'x}EDdDTr=Ҕ1M`ʴ鈍CŊг{w ""2 D"*)Dh0vOv1u3D"*9L%1͕}o~ ռ0R&CoUX#QS7 089丟g`LLT!cQϐ3`wTV>$]Ub␘gL* nps%3P@cLLT9ĈAȹyWaPϡX'%t<@d8~(? cUC%"""MB X""""*D"zXBDDDD1.""""JȺQqq,&.IDsus=*W2uSJ<Ԓ1 &8bP>MM*`fZ"2:TJbp!Y]%%%}ǏM *+tAT1T24ZnE1ß oyM9+/""""b%VfT,QThh,DD1QR]㶟lFG<?LkBՆ͛'<'׬ASeo܈iS&dQڹR O<}F߇C(W,YЧBDdᣇm7nǏCve#/Fa5'±qZ\7 ШaC}/Ο>g3m8p֬ƩЪe =vʼncalt(7+qC@;\.n[[[4 lشI̒ ۸1lmmQ ӧMEĩCwl`o_}z> ""=b6m~nFXk<' ѽgo|чlfMUb6;ժ;::jݖDd\@1b6 ![BQÇ*9%G:-!jqԱ"NBp,\F hO6JTfۦyiFDd B ^|s۩'&&vK8;g;|d$ڴn~|ԪYSs_rk[[[[Ũ(=QhчaVeޫWGлW\S4t[#-NN ]EDDI5 u ?uV+ۡuV__@rr2Ξ;c!:Zժ.k DDM$a/۰m9H= +[=~T*EJJ N9cƪ 5'OFJJ q""UV)7o ,xsX%"]y`{^|'Z}'9 ;l:[b1fHh\sϛ-1n$KZ__fۇwDV~Xq}>P]f@Xq#G:3Xli-0bzBx26KD!g!+]!&ck'"0|hS7 ɆkвndQ1Tҗb<`oV2p1.""""EusOQZȠ<) ȴC1C8.\stJD1%4ZՅ=5u3 AT1T27+q1ͷ];,Cvpwhh1!󺭌٫*ԩcچD?c`8y`KDDDDE]Xg! """".3g%"""N[H+qMc}CRR|)\\aogL1cL%HY-r/Eš=||)T.GG#6.?Ddt1!)) ;~lfP!h];L 1|0A"7e^~,~ o2U+TZDDDDTi2y%"""McآQUoǰ?B6hl׶gxm?:Ddz[C_|ء#ƎBc+5q-:*mDD1 ٷgmhWЉ(ʌMx9.E_Ɩž=zJXYYicԫ[7mDDMc7`[}"ׯ_۱:~|i}G] A܃7w{e7GѭWoxz7FNnF( ӻ1Z@HR˗Gva(%zS R#cʺ=&&_M۠A#xIDTte]Jր{o^}-?ĺ5q1j#FAoqX<`lؼAA8}"szD< j ظn-.DFbsHF7bڔI8~vnTbBy3{CEGoDD H0vhkih԰!O׳qaK"̠1rϜA?trrs[[[ 2 =ScۅȋLw#ڢ7fcæMZڵ^A*<'(d6n [[[usiSq!/Q[6bbb hF]jnKHHШۻaC>ލ0 ~~& @Śyڵ5@*}$"2 QOYدOot}!<YpssUo$"*D"^9{q$hєV%hkۦFֆL7Pj׫T*5O?:v@S;bԈb*io$"*2灵xI ˗8w<Ξz{bb>h/^ <6[;jZzuq$, {|jB.BuqǎT/^z7SнgoukxIDT=VnJ#y{{;n 8`P#/\s/ 99gϝǂŋ1|eǎ߭ƞ}C*"%%Ϝ1cu:g pl=DDx)7]N3ؼi3,ZO㑒3gFFHIIArr2NDDh+^ c`w݋i'k'`aC`Ax!*/1#GEZ6ŪoV`ͺuR <0bP9eD GATr&"YVpqqƻuE>ѩCNce֣QFu6 Ӧ 7nD+-U ލbR~cK"pVz!gaQAx OD`Ѧn kנe <S c*+#(+Ǫ! g s!BڅH_m>jJ.7hX""""KS 919l={ J%_0s,'W'*@1!ĭ(\x0|d0 &:J[s`KT(Sc*,RH=OS7|JT~}Y ĺ˜j>7"cP !0/4e+<8XYY1nzyxZtTۊ ]{ e/N>[nE__o`zK4 ;f+T3JҘ@O2 C Gjհr2TRt ~N l~`-@Y]ޏAco_>^Ob#QE%vUf1ĠOҖ ϝ5h٢֯Y.Oa۳D^}-F Ryv:tGCot;vrmxߣ\ʸ6o45oWxߣ/^,JP*p,q_DQj5T~#>ro߲nlciciM۱n&#y;'.rcySXT cRy_lp#2{&EGiަ1m$ ?];CP*1b±qf,' 7fAPfXx1_ݽU߮IJ5ʟ:} ҥKp-'OoWB||%> %vW\F 4'H]gNɺ=goDƖ߸[|o,.SFd핸p?&ߩfi[[[L6?LsLw#w#LǘtެgZb-\M5k b .ªU-Vvv튉&jԟxx5ѴY32oE/BBBpy|}}kc~ƥ[I˜Z0)ԮR+㛷nQC/24C}&Mhloִ<\rڵӨCbޏYp)<{ Hr,v;o. O 66Vc{ʕ1p@9NTo% cjØJM2/4h l*Up=UJP4µ4"Sbb"/EGx1>xĘcQFuG . "򂠄B!؞}sO GdGGO1Dbf ƘJ"2WNcsHH圜Jŋۮ߸X"@VRmjլ 5E^4|R@uS5EDTxܠA8gܳW*\xO@r!Kp2x4^e޷@zMu7o,$X`޼yggc%cȢ1S0e&AYAspr$$$DDF.׼i3,ZO㑒3gFF]+TӧgV6]}9x,Z HIIH,X8ʯ3f dq3U3̴S0os$%%"<_5jTO?$D]”S5aYx!qq3FL*U±cǠPM׻n˗/,P0V\2F,2S1 Kf*|kkklaʗ+&oSm[~ V X"AФE+,^ # Өkʤ< zѶMW~[a-8k z՗IP*a7n<.&M(ߢyslބ۷a#oԭY#F Wy˗cgh(jծ`kY0/m?뼋ٳƄ4d?{LL{*(Wۛ.ޞP[2V\2F,*SFdU*rF])$fru`ԥh̜5ݭODnݠP(2*j$ څ-)T3TJP@'"G?X5 C` :d0*㿛71'x}Au/I pC* 3TJlqѴIL6qqXzvTR-Rq8cL5d,XS}ڵ >Ũu 31Kcy`L%C`Z+Q{LT8Sc2ؒk\NNND%cJ,C.WM!*Sc*N@klׇDb>+Rїhh1I5uRjܻwgϜ˗RS7 QJeS7DcL5d 9+{`TZ5S7`L%"]""""*V@BDDDDDE(#i1]DDDDTiBmzUF,6b␔gL* nGeJn QǘZ11q-=š=||)T.GG#6.M1|0˥du?6u3înQƘj>S  gˡ:O\7Qw̼&dQX""""*Vb l=B?'1O皱z8y =ӷmDDŒL&ÆMnhظ h'3nQ'MΪ4ZztG]h,'ލ=[5Q4{\^ II8{֮߀&kQ&n%Q7+qNqYJ5KR>sÄISдek4n&NV6SN?=QtލѾSg۰ BÇBЬ^XYYڷ6dk<<޲b#"*,zG|={il߷C̜}z#!+[߬\ws#/Fa5'±qZ\$"2&WWWܺ}'EGiV,]͛3iqH^={ݻ5K5|`w651p<"B~v-'lllPJe ®={ȘNq1qTlD]Bױ/\[b%m{DD  իkD^BC/OD_ +++W>|˖…Hx oo A 6N""cm4jcǏʕؽwl"x~ݹss-uk`ooθGD]Rգ;B <ۛf̚1e@.7*HNIՀ,'''|ҥ >ǟb k ǏsWbİ(W,$ ._cNN mox^8w;Lexu_RRƌ'fϸGDK١_kL<~[PjUmRSSq5˱Maђx9{35ʌ= +[=~T*EJJ N9cv""cbȗ8x0?\11mZk-?qT|hݪ{DDoɺz쁋Q4~77[bI۫WC,[^hҢ/[ÆiiU߬}Ah7n )l8p >34n#GEJ1{f'ND9NŸGD6U+rF]eW0?FTH6]-]˜j^SI_ L5矼YJ+ejy`*A}'$"""b%c(/" D1 bi̍=5u3 AT1T2 @G+!6.BwY3S7 +^M!*Sc*EFjd,$V'Uw1mCJT"ʏ˶TCQ11DDDDTdL%@$\ZDDDDTq!""""*TKr ,uYg!`8$%%qz""""+|lfjm iC)[{65uSJш{3^~Pȵ !)) ;~lf+tǫrqcD"uʅ X2r֌y`M""""|\{`yx DDDD#1zfLrV%"""b$XQLCv( Ohߩ3mBQfGoC'x4F]cgh^ݼD^}-F RF=EN5EDDDDŇ(<U`V ԫ.>GE>t(plܴ zuqڿ9Sz`ƍ0ׯĤ$,[. 'NĚurZsQ&dB`׮E 4򄍍 T9Aصg- Fw#L׹Xp|7-ʺa8uR͘>Wco7s&"""%T9kJ\{ ?M͂A en޺F 4k8?@ڵ5@*}q. 5x7{=3h  hnd |?L^ݺ"h! =̰E2g> ]J+|0g?gd43 ZGksok?e+ |k'<==lr{{ UjDDDD.{pgΝԡw"8(9F9nuغ4$& {g(++CEE9gL7˖xn.***p<7˖}SL0 q,8qX/D""""rwUT'*axYFXX7Ltr,DIxcXXj)EEaIXh1.S&NkK,DDDDdS҈GOx?'ǢWϷnk`0ʺH&s~#S[97o"/c 982Zٻ72EƈgQv0(%I]rؘaC3loLDDDD`T""""r|U[Fu&Vn@DDDD$U!S:w7w۳a9wC妲L9AP3?6(*.FV&^)w8DDDDTn*rդ72h|}/BBQuׁ8$ ΁%""""'F`9JDDDDpŽqM_FȑIUeU9 P, i"m'wy`^-Gޅ6~Ѷ<\۽y' QCrM^ٿw/ԼGz^ ƮX?/+z Ih2bceeu\ñDDD7xh!;z%?lRcr?qȲ_hHޘr'."""VZZ Y?(RZfF'C|QH@ޅkڙu.gՎJWs kj35Bh˄DK2d>W3Y7}#DDD ,DJ`ܠV)i,g%"""g'd꣢ G˖-Ѻuk 2۷oQW6, ˲]2,T]eM[EEEHN| 1CvD&M cܻg7f8IkעmdaVDDD EheGrr <=<&%!pqi|Il޼Y_0jm6+WJf##cFg+&>b;V9l>} ]a7p};>, F ǚ$x{`BX:^^\ī MYو7n[Cr,B؜/ͬs?I'' ^M+V@ܒ߷FsjfϚlۚз:|qqqx7p\!"qu}̦kg[̗mLlޢZ;iktdmv]?$*]#_gϞEj}7~ .Dd>F祥[nM]t)"##}VXe˖!)!)) =w׷'N°a0{llF` uΟ+Dj ڒWpqqK:WѪ*DDD *\/CPz*@Tj#ڵk UN0OFϞ7} DD#!~)<==hޒT+{M6}`7n@'U5}m Sr$][kӧN!cOh`WnaH$cGŢ1ßeFd `uߏE\`,[pH2XTӑY/͂Wk(J޿Uw aaaؾZ YǠCRc :g 32FR|qbd.ɰ,5V.f:e2._YgO[(++7|g}V߯}@\ߟseqs -Įwƍ?PXxgL׷2wӌOqU7o^".&ү1ol;WwnܹB̟2.Mk`>ڔ)IX:oϰ/&DDD 7jƸ#-- Ǝ[r%6gf"(8ƍ3Mٻ7,AB|B:vˆDH}{T߾X޻9o%&bʔɶ@gCM =#nn=cF;36qq6~hS&6n؀նʩ҈Gċ=AKY 9Ch4^Q*BնǼ/GN%9(1hNda92$\ܑSZU@XYˀ#t0a,]vda$:DDDdMtlyjya-U'#´Q.y \>/Y)u 9.+6H& 5FH$I¡jd MHINX|Bڵ-7'X`!QFu=޽{Ï?r$In:ytL}Xz5Ԍɐ!3W%C$y}fZ&Mp}߾4McҥH;>ҥ˸e`$I{L&V^è'((Ƚl^^k֬ϏnݺجcUAUenYVUmIu2/:MӘ>}:'O`e}?.卷|G,|7X{ݻ~۷N?dͺ4lؘIʕ+˵u}{DE|7,Y\.MӰZ,;s`ٲͳg^Ξ=˵]Gƍ8s {@u(ƪի-j*l6GugaAJ)[X[Xh Ş!CCn`YXZ8z|C)dgea㹉{[.u1{yws[=?h|<#Gd0wajuQMYжm:bҤ%}2` CrRs[z{33>D$ WeNVfAxx8cFnws(:,ٶbS믩W.?TmV+ӦMcݚ5,X+ǎ啗^r_~ )ʺD_B a[=> }֜ק)O?XpΝ G4=e z=~~KJġ*opn,sTJҹsa_A?GUzq"+Uj{{' 6kZZ`> tr_ϩS'+q{y,J%fM=@Z.u{СC$I^X_V]$I,]̽=Ncݺu9{u֡ӧw+. \<99Y<Yб_} OUn#FPv,Ofx4!A} =gmsU:8'N0sg^}ħ35j׮Nbgѹs$Y?qp},YLJeА0އ^g ~6NǞ{ CJ 4qp;mc Hk=O&$++_JZZcƔ:#<`/#(Bjj*+Vg&Vzx`la_!--k*Y(}#F0k9{ƙgl,>v%$ضmw F=ؽ{7Y Zϵ^ٳgٽgza٘2e*6^{c]ASZnE|>#Sr2!XzIW۶m [?vΛO׮yvUՈa޽T^@?Ncٲ}DD<~) R5j :dɲ]x_md0%}NZnEnvV󇄆}L~&Е>Ae7GODDCÏC^}5 }ob |W.>{#66{GW^AWE7LDD5~O=4иI]ۅb 4@xx8[`_ҶM/4h6 ƍkEQ4h+WӅ1(b|AQYfcHMnYyuAAn)HN:]Qݧ/)n[s$0}nOg?2$ڵU^pv4#4;`DN#8ځ$KвUKV݆Cu :F#z={OͩS\ -ET# Yá(呖Nތ&5cGQ2Rq^6:ܤEbu^:FEQHKM!'+̶V#@dYP('+#sA~Us!aTBcر}#qq|8czUTHXaL~:Áj!+3MO@q8defVv]CB8w49BBÈMnN6PN]t&{aoҺE=AAJUWCErXizPT5dG4wPNp=` VMHJJ"5%Ǐ,D &<, \OA*ŭ O?%!8F-Zh٢y+AjPUv:_z e^9[), # ^!AAUU)8$50i4q pUJnێr$stK` Ҧ  \JWKbMnN  T- z1b    _AAAdMAAA^AAA   Uy _$   /L5\ 5odWc}Qu7i AA+ ^iAY9wm'/˯qQ ""h׮-w5;WZfo?DF#;gr5nWٯVVuAAb$yLTFj㟘Ą'ӴIF#))ܵOf~vE$Wkaۙ"/?[gJJXgAAA_H$U=eI_z5q'm;vM9k6PEJк}Gȼ Mw迮ǟ|tڷkG@@z5cpM|ws}C?Zi'yb\۽'''Uly@ZH?;mtՇϿ@VvZz5CFێۯ? ^vi{IMrdie3h$"*ׯW^?8<0jT_f ?| ɧwɪXl)Q?b &Ok$>6lTlf晧'qj~?MU[f:&M~GƵjl>С}{Wo+/eʽ^:ʜbׯŶ5kL}}s[OĬ/j۔/?   \_mцwG#?^{ދxwС}pp~MC4d."X2~4>{S,PAUq/1o;v$#3X x\_T칒E=Сe 0;}pkۆ\KKMXn`ѯ坷ߤuVUtmt4>C⏫j@y}ɗSGAA+sJͬ{Y%9дKW.Gq'.EϠe0=~hӺ5?;ժ( :y?7 ϯO>>?6nb굼4zp,#uJ c 8?_E ݟ*HPۦ<   sKv~Xjե QFؾsgmQܠpjpMK?!*2NǾ/Ӻ5jM7b˶m1F`X0G>tҽkWRRSݏ˳?yz*5m԰!;v*]UT_o  pi]чbl6y=oŶ;(((`L}s5cbشy3j%$ <=([m'//AFF˖/eŸX,8xI_`)oySJzx8xm֮[OAAN^tO#lܴLAA7ln:>s1j4K.#==EQ8yA^/t#[ع̎;fMy~GAAKB{5̙L2MUiӦ5>0bv2ݺ1n0j/2Dbyd8us;wNdrX5jЃcӇffӱc{g\ &j%**~7)״W0HIIf>wޛMy~GAAK9~zĩލ/\Y*s{ŗ__]D?  puR$ǥv]/&X,ǫ_[oAA?]/&v<3gY3ν AA?L\/   W /ї.o   Ir+AAA=9ߧ^   P^ wA4ݻu-x '  •ht!wq{$ \`yӂ  ?^t݃gTU/p9ɲsZAdOAAA '')hZn=бc.vqo^C5 =)lϥ` ׸K -NM\Kn"zg)܁$[[B[P݄( Mܒ\6'md_~F⺨bbHODd+%nbb"QVbϟ9sYYfm{7##-[]$Ik!""Rdڷl ((70p2Tѡ+4 IDATmf4bhT j{[򶟫Vf˖-^[ӴirD]l6XApp$j*hs,DQF#sƧ94ï~-!=׌- cq;}I.^S6L=vIÚ4wRO[<|{Z1h [.+VϏAa0lڴ=q9Mvm]`…|͕w֭ر-[0enVBBB֭/\sMĭ,]{4?'t*΀yBP^, $i2Rد)xZ߂:T\46mJ@@@+X4 IXf ))) :UUϷ.̗7neq7jPIJL*u.rTh=MU_pYFfdYFU`6&Mmj:TѡL^rzkVh2I0̦;3.h>7p}|pqݵ9p QC7cZChqmOҎnbݜt{q쪝~cJ?VCǸVer }̇E9vmřn߶]lٲwd/IMKCedIBe$Ir.\>DEEGͩS<?0۷m%}̚5ߟ_|_,aر*[%_q~M\$ NGhhhFn^="K2yRR6cVhO>P=Zxj4´ +o=H޽4۸vt:,Ν; ;L&vލh,$ѱcGwrm܌ Yd 7ڢE0`~~~E%%%1m4ϼ}t:odڴip DGG_lE_ߢ~s?ޱX;▧SUU9R,/ֶ$w~zns)} n$IWO;w2%[^~+iҶ$j~enBԃ+ţ!K6dMA'pjAp hhHJ]?u[)ڌ$%6&%֎$I AӼ.Ur=k=zv~xCNRR'>U D=1HبA]I1_pǠ/̲qO$2 ՜0D@?= c.,3 NGR 9_$ h[N.GF_oٲ{ Ͼ ?bwKNf_ ~{Gq)S':vl>fO??_cZ!ߟ@hڤ[(8pIIIKVhWv]0k܀@Ǝ/uzeUvׯ}V`09e-x=0~Ʌ Rۥᜌ$`$_$tzRp>|q wLv7\N4^rŒqMzꑙIXP挵3> =s,E ca"^а[H(rmǜN̈́fϲ5Դ^\}'b ,Oqw=ѭ}GSрr ~?!t6nIA͎k׮Xq] ,#tڵ{\_~/Zާ( :tI&+R$ '==[weqӷ-| ^z%Xn999{Ea͚5p-0yd۷x|}Z&CJ^"q~٤@%=jպ /ފCףjde_vmvn0r9-X,>3OVAX ULqV'Ȼظ]od|F*-~G׷# ׯ YǠf$A=*HzZ>栖ȭP @! z,h2ҩ~!: MS 0HyfϠc]{o B:c nUԹ#͙=܃nxϗ{iݮ3&VIv&ҁzV=8=.\@(SsevQO:toWkE[=if꣌؎"a_?O}j*JR( ÁjPU|=ws.H³˻}) ,.uJFz9yȒFcT lΣi1nkWP\pcۉ^zdddpi̤sΥ_9S(EAA>-7wϞq4>ſF^hۺUUuaޗl„ OvU8J.t: X+9AmO&<NbTvWMSLLy\ɚ B cww+ج6wr9NJŵj8T/|u[gbW33 Sw68lVk5$*ŝsx!Ady`3X壘5־G7jAg ?||[ߒ:uʕ+=z ֭g^|ݻ弍[@UJKOw&'mp(>pgnʭ^b\[oE} O߯_?~'N=sh~n=2`T}4hKA>?|&Qw3nQ5c+,߲Ķuhӧ$0WcH;E`"f%h8Jr,MGig} BiBޒ}N:&ϏD65 >m%u庅DSUN:Ů]ٹc7ue4nMU% s=^&9W!nQ2 !X,[ؘ3xT߇]4,8Tz76O˿aSܖa{c6(~q}0$@Ap LHX<cw'WI!!x^bCB Bq(tj߁6-ZAjzi鄇a28| 8oMV{2zuҾ];߱Ytd\ө#1EBS6۵?/BUU:kSPyoJStb0l8$Ir^9*ลYp!/ǎADES}>;fɼ @Kl1W| .JE9@Ӑ% Y|ofҥ(v;V^Ofa6^Ȼh\p]y׭>q%`Z]: 6oƽ}:5jXN C2"n:M,:&ZNc嗝2edF[I 1g7##^NJTTGGlٲky摑8{,=zȑ#DEE1uTfϞ} %}6ƛylS ONĉY+6f̨P?̙C=DƍO?4n˼)(,Zjeܹi ,h4bX*2-ե [{?wȺ_!װ۝ػgPHbkzU0+I$M$A;m >l2$(ah35%f›"tɂir>еwdŒv¹e P5Bg,lڴ3gN3tPڵoǗ_~uyLjb!Ǝ}IP{6nNN&,[n=·[g6̊@%%-> ,vLF=#ojU*`#hߨKaܴ| hL8߉*&yzSFTBGzν9ˎyqM͛|^Ux.0UhB!QPEHH~F? 22F|ss{Zlf+ bK=p ={|zz:Qzu㎡,_;wCճG{g܀~W#4m T}aޛt_j \^Nn( }E]FF&ؽCO*#jaXX,Hq=ٴiƍok׮lذ#FPfRx\~ל:uNd3zt3>v)[WU FVxI2gSETGơ*8BZV>9))q nǻc<"Fu+GOK஝ p%ݢrLuױz*5 I/իWZh\׿rDhJ‹.⺪.%6\ht&>]r%׬o'&fl1 _QBCCQs),\˗ӧO8òy39G cgj Oƍ+B|Ah41Ne퇙L:~p@8='ʠ(BO?qw*_5 ?JUJHA]hٛ`UCk}htza: .cm}+@b21@N b"Mz@B9)Bq$ƿFf9 ~ɂʞ ƂA}t#!ϏTC)V+kX #)9s爎$?N5TUWӡc{}9~/͛7@XP`Ʈ9f;f[6;?} X0d bNX<@(IftoQ~z`ҹ;TN3+EgQγ_T PG̈́UG2fC_6|j4i҄}jjΜ9K?盦i4n}ߡGػw/9ePZjI o_֭@Dx^)KaqYfi?h\YGc۱l]04 Y"+O"J p NXbVy馛馛x>}us}#q߈'Xۥl_uW$ ,f2SRHNN%19Y8svhܽ ο4X}+O6뒗|w <"siyV z]$//Nn˗mn;fvr%zu!bjUɾ4Dh &X͐REUph< #s}/zBqKg$I*(so>I+֕H\]|(y4Y|c*s`Ɲ>cztgȪ0x-XHX477; ?q U6ЫGwϘA޽|[%7z*bU''9h4ԩԩS}b$ƒK}/yGY~zp`z=|iC[Sذm Z ec0{Mxp"/V  MPr Ё>I<@B%J2*~x{ Yu@&Lmj0) i]K on۶?w }$9Yر0ڶm|x \׭ ]] y}+9Hhɷ_FddUŨJ=E̵ }~]KnE\!E{ߝ= $g[Xsf{\AAl@p15ŸCOծ&edUxj("QU gekۆ\ӹzhԎŦ-[ٿoaa^>z\:ĉ''<<ANN#=#͚ѳG֬YCXVl۱͛7Ilh+٤Ҧu+wʺ|J0M܌_ryx7)Fv pz/ZVOaUG|{+IR@VD2 dӦML)e_ʀ?1.eH>ރpMy:UIBV4awBὀL2^N(|kT4J~'"##yr|v5ceRCvݙ75g"$sdW$(hC3VU1NnuxvDbcc ~X{IO>'phUZ?p82d~-{/_0|p;ۯl $!!H;ĆG 4>ENP %w GVB IDATCNU$I:YyF]#KT} j8ϰQwH=M-1OH!J2Quؾ*^,+x3 o0c٬(`Jhpg"I΃eMU @Cj 7gL~~V Sity<@8d 󱄳+mTZ0]ІáUhVa DWZzN(w%Zz}/W,ժ =-EBlm;EχvyZo6@ݺueW\2nܗ╯*X=zfQ,_р{(pbB_L]h.`IqT4T *d]?gxj[ɳ!Zf*J5s :wdCs}j(xxóZC ''T- V:t]uڕCұcG5n.Mf] INNW(l0/-XxIFS!߬oMKK#3ÑI;B '{'ջ5q;Մl h̴YU;[|p } nތMeٲ/(BBZ{zwހs/777mF&MgYw}ghg+Wh4`-+H1]к'INR~pl6h՟jl|( *N}:gWCPA3Q3}9#c6J*|Ӊcs=*9e0߀o A਑@C]o={}|<'b`;9qy+ )))WԮ]:с~ZŋektY׮a4>~?9l}5+恣o9o?[20]WHsÌ:U=n&]ԫdծM9)1QpiU F|ٚ~~$%&*b︣/ h&Ñ:p-[NMiXgiF 6/?'OᅣҴiS5jΝ;T]R_+pYO?ȥvs@8GBߤ o̗_+mZY\ⶬkʱ*R>^oMz\hlШ祒|b&]U0*z, Z *|[?s;39Z"5 F# Y:e ^dlSKry'nw j*WwF.S!+XLŅIi+h:Ml.8jp%^ > }pt/ cLUECd%dddnzy|F?Awߍ Ǐ3I5^iBOɦii|t)a}vpp0]W~^> DM*ָqc]e{e&:t@5lκջ>ԭ[^zeӣ{rW'%'WZ\ˈeIN(ҧ>=w77Z.s/K܂_*o1zf-}Nmk4ٱ}7YYYdeeNG2yL 5pqW1r>SCp0|q-Sqqq4mԴ/..Φ PY-r_/n.~oTnW|y#Gspr|lb_:%_PӠO8AZMpqq̙3lْGҲeKL-nwв3skhc a6ǭRaFfp28##r'_N fY7&&Gzz:[lfyL~Y=ѣGiڴ)ϖ.!00ڵc᧟[Is1XPgt |C:kTin:S7RNN~t Ā;9/O#-=_6oagcqG~2}WOgWo|嗧l =, w oMG8n1k/)[l) f|k,+UUYt)YYYʧ~8;;`˸;{)n̯;]̱jB~j 5z)V+{L6w#=JF74NڔLTe N;c]Q @nà7FKETNN-Z $$-[3ydXGx?DyR on]{uu߿/iF<pZָyS5]E9hcq0X4)qv2^Kz`jxdP?)8ǯpK󭪊ԭG|ܿe}Sy; 8;;4Gtwx ]|[hhRRR0 tЁp:4l/_ՕzѾ}{c~-֪UaÆ۲u)RFT>#թKhhh~~~oqpp=z wR'# s;oiU3s_1x"k)pfOkpiYUU\Pz7֦beWĪ[f!+3b[֩S,t ?]cǒ@X˄>+*qrT5%KX?=z+6#nfMy\(\xL W^e䈑LS{9N:E&MXh ;T3bΟ7{?0 QR-x|vU4܌tq0jnZùbț@wk߶)1 ޵|`Swas2Rsmϸpok֭Ø3 ޘ5MWӦMxz$z郪9^oXX+/ZDvN Bm  _ָ/=;\Ǐ׊:u*-w\{%n@woHmC=?\M܉Ν;x^t9[.,^>>>fF#̤6ŰT4_FΤƜ` cR1cPq%(P5J 4MspEW}ruP9 J^k īZjIM(>Y_7.W1Ϻ;~;k力Fh2|z~ǧV _{by>Ī:n=>I6mRdG[?[.ƭVArVI\+7N\&q+"͢pKtI 6O^T}cs ~X0GD>.$_53>>ja+q%n[R7J>-iӶ ?~)v텯/a^ij$7kĕR{ŕo)AYz> rgs/6ej;5Ȟ;qjNg !0VWfwUӇ#"b Va+H"ùp+Hڴ.^+qcܒҿQyŕoqDACm%fUX'=xpRUx*1r_,ߗ9/+:'|!٫/BߑhRR._Y|%$,Rl/B!BBKW})[cB!B!&[5f0B!B!nV҂/B!Bʸ4~yB[€wVuB!DG;'FK^V͗+: B!&%]B!B@ZBآIII!1!.MHhcdB!DmHFRBTtT4(>c6DG6 B!ĭVrנAhjh}*~[7m9(vvHC!=0!jt{ź5M!B ^7+iFb(dOÆiB4Miۧ˿B!(2L'71MUʴ]r_BNj}[VB!O tÇ7ӳ-m> 11N:LЀZڢ(E\!Dv +v蟃<;B4 !B[ϵkmNi={gӾ}5'-亓ѣf׮"Qsxf[K^_=;,%cB!m=δo8uaR_y&󣣣U\!D7kkǠHNe_'T%BaЀWfʬY5}?)sx(7(kޏ`ҤxxJP&^z99o7:7G.+" m=䓑m:wށ:5>;gիټ5LYWڵO"fMMƌPd1XVVUWQhZv3d%kw%kq\uZ_O!f;r+W' 3qawiףN:tE\\lٳyW tŁ,Y҆sOw9q"ru8uѷѪEu5Fs5&1NVuk~Gݸ|y OA,XPRU7 IDAThWڴI/utq)*+~4U9pt#4Sˈ#>3ttЬ+B!Jo/9_dYWvS!]>,XƬY'xzq{1'627iR.eś=oMkjOε;7n`dbcoo3xיb;~l.^UWQj7s#)-l-M%LtB!l3ѣև@iٿP!-Cֱ?#Ce֬h5֣(kg[}4ȹݺyq5MMzȼba 1O>DDw q(rr.]_qAO?I$+]B!nLzsϾ=ԯoiG9v*+Wysw܌dd3;Q#"zy9ezIݺEԭl:&&79`_9o;0eJ4MnQt}aȐ:W/:e-RUqOz0ϸ :]7cv!B!Bs;:Z矽/:Z丂ok|} (f==c2 OPP ~ׯ;v?La>BCӉpevd+!! ! j{6lxb=4sHvLB!Di yDPдvEA44EArW?*gCJnMVb^_,Ʀeժ:+c^~/W' KL@6iuib _f  b  T)+~rź 7Oa=j1h1Jq]B!iilٜۛ\-kM gdzJx( `+sLMiZ0{Ӂq=zq/y..FMNn]z 6_q&99 NӻOy7.6mZ[ux$>ď{XMUUWQh[K\ҨY^Ũ[B!nu>>>v4|${-[7b^Z2ɞ5 -9reڔVn[W~1F6Ѳ""0wn+/+4ԃwڵg쿙2YZm 굋+6o>}n4lFÆa_MNV$TYz}BT?yyKFd{B!(}!l&'Og'׽/ۑ*Zh.xNq~m[O6njo$Zp/r]{m>%ʪQL~MjΫʸBꥬwݞzcdpxH B! %R[cE\&99c{qUgM!n*ir63Ь+ !Bܐ w¤j6ztӦ+hj[o:kBqcPU4{w.B!7dކk`O!9o_sr@Q6n`0mÚB!Dűs_&iBEWZ$oGD*F}Fd%=!Ba?պ_!ua8|.iKhVvIO!BOj8_!Dڴ,!Bej=~eP[aoÇCLLCfvQ8dVUa h Kbb{,P6Ԭ ]?WL-O>_e[{{? prz;ε5粰]B!ZN_4Vеkз/og[Я-#YE߳Wr'4aDF/+|(^{ 7?ק$%8bLXʲYf|_sҽ~h~MEEK/oy}ׄB!"%zoӧCe+CΝ \ mzM-:=^_geGY0k עFR|~#k i Vwޱ ^i֨/|%\hy &N` ?7߅n4g[X !BQA^DQv5o"Ǟv%˛k4 >" v! 撓S HJX&MAAAKdddJYc?f ^]4@P{(wBäI%X` Aު۬^Yk(ZQ 'GonysV7]6-:,|+'஻ ЬcԩEK/Ko_WkWXr"" ז%% ]B!|[Zn:ҳ^=Ka=D}e:&x2Fs]y1EFɎ;8 uÙ3Θ{äsb gO ZYS=Сqqqlٲgz)֩օQ1`{=y2̛g 'ʁ}٬Yzq ?O@ΩSJo-bɓB̙zJJG/OP_ >Wս.\_G7^%^ ?}*|maVɢIII!1!.MHh]Ba[&22!bRoh"pD:1c=1 {7dD}Z6MGV˚7$U9s<z.8:O譲/OV~b[78Q7GRC*NB 4|ޅQW/J=?-̚wya@b(75 0{6j &xɒc._?s5 {Ϯض#ф,BQ^yN> `fB[LWQ"\\IOI7s0Si~qWpBe޷ww {(C BFh5?ӦMcݬ\$4M#==cKc0ع3 Jn{yqİ[B>>[~G\V/ 6m>^QPF[IK+6VoI6Mu`z,KJ-<Cј?_o/Uu]^W$'srW,Y־k(%%=z]zqіσBr駟?~<(ٳw 7777|SYBT}Cmb(9=gOgyfj3Ͷr릯fD"!;Caj\z=K.]vpq%(\6 *,2Ro@-ɓzyCyc-Y*HO?Kz[7u?uQ~~/_~B–|ci_ڶ ]狶6~UkK:v"^YW[Hz[sZϖ,nLkߵJ%ۧ˿B?aÆ 6e˖ѡC,Yi35wG}-[2j(V倅WenFdgyfjƣ>g}OxuVܝ0Vt\\\-[漯Zg`CWpR١1̔'C.:!IƏ'+8-ڵ&PPb^no'5=Cp}%6YVuٽZ([ד'çK-X`>$ [sA־kL@U5nvU!D!|gtԉ`vqobƍJe}TT=z`ܸq̵g@!D;~ZFp.ɩMzצcEc.SolyY3(p[зoӯ{}zxbՇ[  hJhx5=|\Y%־kLS لB׾}xw {8q>s?+@ddgg;Ν;4hSLar k72}1j(f~|ޯ>;f۔nfǵ}-NNf iV,Jpp0G)U zaVpzK ᡯo4lo덀#n1ʓ^a6z@,^ns 5Kum[=?zKZw$>WTld! E^ݮ[ƍ7nǸb}&M˴M`~Á_ *^OW_N{˗uɓʆq >[bVTM+ӁY !(nʳ>(1'''V^˗ywիK9In:uh_uڵ 8?;vTe!n0PVx oi:-M_Oq(:K8yCzɢ>&ڗm_Ӵ[9Č_%ېѸ{f!E:u(+{z_Xxu2j׮ݺ7l۶޽{oqw+ƥ(<̙x:'5q":e|U%x]37}.'MSQ.\%Gܙy۱]+M.BQZ֭cܹу&M_3zhN<Ν;3fL ӧ'8BطS*%W,[o7vE6p܈4UCS-4 "95|K=ݻE!e>cΟ?={6M6% Bb^|$+KvܙӧO^#͢Eҥ 4'88={p9NZi{BBB=EDEEcfDфd B,c~*_!yJ6YY8Rx}mlB܊;7|C߾}iܸ1?}_;Ъf4i?ݻyg:;B;B44.2Y՛,5,6doM%>5μ_ !n!,X-Zжm[v9{,7nߦiypd 4`Æ \pz##)A|<4kfyHùs0|8xzStU,P}VCqkrm nlߵCQ$]L"Z:kAT/|2kSKƹ#E,Bnݼ+ .]?_~4hРi&222_Svm:vȞ={*(gB n܀)L4mf[MGYpEkз/qwq&L}bÇa xBܚ4MC+0!/q=zpvp6KCE',BܼΞ=˱cXj+V 44zիWs=TuJ%((VZӷo_q֮]K&M* wBʒ[̝ E K@׮0}zQ0^-[ 6֬ס_oB[YNeJp%"3 !nIIIDEEoq]wc1m45kV+3ݼy3~!}~e˖v̙)Bv(3IO>2ޚ5u)nnqsM׮KYٹym^aҤxxEP<^zi#٥:w۶3t7ih}v?k1EW0iRy(O !ĭKS ل:d…nݚSGp֯_ȑ#eyf͚E׮]!lT!c'N\O3.{Ggp̳>,&ufط/t4m9:%.lyg/[K*1T y\w }BׇP"me0. !=?DFF|r~wNYt)Ş;f<<<ر#;wK.k EvIk,]?ԯ_. !*PnBfѯ_h_T܊w#>ZiNǎ%rp7͉l\],ܘ4o~矇Mh,>}//| [ xiBܚ|}8IV 鰥*#kVQQQݻEqAFOnv^رc:KBTHߒf &Ld_Ӿ}]k23spr2$HO<˖2{mobL>}nXXvbРA^KÆhpeٲ9K՜9x饍8;iz74cpH˖gڹ~_?ヒ&(h>k;2]6o}aC}ۿ__R//ذ7Xn>1B!ndGaу>}xbFɓ'ٱccƌ} KZ7&::DkmBpr[~_xW6ĉv嫯ڹma1k~ɶօ*B!Yj̝;>}HF)))WJ/F1j(Μ9S)1cPPP◌B!,N>ͺux 7ߤAٳs1uT:v,$²d._\i̙CvhժͫB|͢/EGEBbB]ۛPYSaٱc8pK.e֭w}33gҴiӪMYfWxpv'|©SP^{"k7 Q夀/7hP s}%\;mHt4!vMWQ}}vMFvv6ƍW^a4hР'i|'8::2a tBΝ+U !J`i^Z&Y.ܫJzz:F|_/7 ߯%o.Bcٲe8qD/_NVxꩧضm[.JСCDFFҧO{mQqC aÆ tޝM6ѷo_CQ:RBVhmy/Ftnߞ<8w<Zޝz/{$ q8q|(œ9s8z(͚5-W~k.z|s=WV|& !MLSU-=-~Kn=֥ <7b مNˆ$''9&yEFF駟ҺukBCCٸq#SLa 23fpڵΦ(௿"**7VzO?Ν;^wޝӧrJϏ:) !ML4Ӗ9MA19*wh(Fn4iՋc2;&ݻK\\-"++%K0`|}} ocǎٳ}ˊa<Ӹٳپ}{CE :}sϱhѢJ͏.L Bq4~%ӌ8:9T779d9xP3~;ޙIQ9ga6AAD7@PPpW% J~ݮ&ޫFшFJF4^ hDET)QنٺqN-3, StUuUC}|n |/rP\\YgE˖-3gWfɛlv'2wܨڱxg;v,{'O栃weŊtܙ믿;^xСҷo_͛ǝwmVpS/p4=V(hoÆ|[UfLp>{Z)7!=>|_9tuZה Qd~afΜGge]O?y76lO?4Gn!O>$'N;{9ϯ]wߝzaÆ裏r)(Z^{?OS/_C=TxwM F+++Uߔ3cTRZS5q.sr} %TWG\Ӎ;K`j֭[9뮻֭{Aiii=tP~m֭[WQ;G={dbРA,\#FP^^ĉc֭?8f̘1<h-IB٦xKRߐ۵E%LVuU5| %Wb!{F:… y:u*\pL:C=Ν7=CƖ6lX}h  9޽;#F(h<]t᫯bҤItIL:.]4&ɡ] p4yVѲk]i  ZQSAR *kk>_^{s~rq8;VGK/Yf7fΜ[7n6{Gwެ\>ɴig}̧~Zp&фQJG9T}7\64AV7YF}xι(,| 3gSOe=ꫯdѢE|\~pӱYh/.t[dʔ)|{챬X8MpMI9{WycF>=;wkE|A3jVzM:6qq8ۗe˖pBM9Ә0av=z(tx*' VqUWѺukf̘ 'P&kp8M9d0ڷgg$ZbҜt },~)bѢE|,^oI&q-гgOWüS5th-ZBʃL6Sn{:cҤI|ǜr)xh ,|hjh뜷Wko2V;ubYjU-QG_駟2k,>w}y'8p`sM֭)+kC2ZjEiE^#P**w)t[ůk;0 ļy8C h 9p80?T*sL6m??g}c޼ТE Zj=|~OYl?8= c۷9 oNlEQ:MIq TWVdkXf-R A@ϒffd3<~QoM/a5j/Æ cܹy䑅hi p8tso=vߝ/gĈÙ=N5:pi8Yh?/9䓙0a7p{gs[*B PZQYTgٸTKDHlF@+9/i9r$gذa/O.tHG#_p8MFizG+V0䠡TTSTTp8?{W_}Ss9[n#FpQ42P @hahOR@4*Шt{H/m**W4)M oɓk (߹1$Q +$Fن9;]wJ)b."y:B( {PBċHO G4 D$&J |~ŝgq٣ rۏ_| &ЦM.Bp4"wp4Qڶo )%~Ю}z裏1cZs5:;~R\{2k,&NȚ5ko[ap8MżB[]\]vkמʒ%K[yY|9gy&W\q?]vW_C+ >ٳgsG8rGCp>CF.=SqÓBs=dӠAE^cOb |7҉Ovӹ+8裙3qLpF-yf9\_|o(l@ñ} dX`g{%MСC7{aƂ 6lO<cƌN;j+ %H!B"e,hm6;Ҧ[qE,q#W?H,?e|1K}ӹsgf̘8Ø>}kHpl&P啳1T>xBp8石b z)|AzɅ^Ȝ9s{tAz衔3a„P["Lʼ%Li'<<)f?3^nU?6.ŻұXO"저Ao,Y믿c2c zQi9#}C: p8M?ŋsײ|r8>l.2zUVVS{`@K"jl6.Qf>t*E*&JJyHVZTh=PtO|\} > >" X?i}}]ƏUW]E>}~9 rӇ>}lkȎƽ%"#ڤQo|QJJJ(-)"j>UTUWP̀9n}OP/T:PG"qy9\~nݚC)M`~M=Cnevۭ%xcf$]GՃ_Z*k}f 9C/ɭի΍7Ȕ)SwLp87O=+V`ԩlܸ?;3ݻӹsBܸDd"+{$DT*E:]DIQ1hѼ[u[QZZFWTl\HzP*@) _k{r{MH1I&1`nBpPԻ?w'|啑o۶N=@0nܶ}gz-8ppZ?gyiӦp-0k,G(7ia{'$7o֌V-[ѦMڷkOhު4oŠTWo`͚5R)4?>R)͢m(^GNǺ> 4zǛKsن Ƈ~… kƩJ-2e wÇ/tC }~ܹ6_o̘mOc׿5=9UUf.Ppp4n>Xk׮囯ұ#m۶eO>aҥO/ Çswi;1KҗH%$o&]W\u8k2( γYt8E/3uT[8.rcbA2V+>x <~;+WrUWm#j㹍wNo'ƎC׮wFWv̟+|-jp8; |5ZoZ ,|g tm;vBp V\ɬYiӦ ]tO>$,tx1y ֩B"x2el}Q14oւ-ZвEKZnMmښ֭U+h(U6ӤitTKIDX.@&m|N,/DcIqHa̟?zjnBplwCbҤ1:`JM=kt?y|܍x5k;;8.2<#9M5:qk+_]7yHyf9w-[kb~~\z>{&ee2rÔQs}w,[9c@+Uk(籙op ]&U&]"]&]&]d]yOP] + Ҥgkπ>J>“&^RDf~$!W\>%`/Z}$}HϞ=y駙?>\rIr8 h#1bD-wŃ'[z>m۶OIp8~J:2wb:H*2)@(jvԖv=^οw4$7t[fԩsG c`&]AJL:a٦uK/0іN i\|/0~*ekJaSL d: Eiظ*6BU%5(Oyxi<$2%NQ{j/۩'-}:!ERG5q]&k=9h7̞=3n8:w\F;hs뾣kCug%5ERR$ؕ܋n>4߈tڤWUBF3H/2%|Ddk8/еD>ivB 6B ?.c9x!C:$A Up8I|jV7mNY IG,?VѭkĿ:}}3fG<補uYA֧m6~`DcL)bNt"Oh#ȗCJizӀOȸBfPISU:)iQ^ʤKi\LW>Z(/z|3 ȩ72?l>yYx'5ZH%:55N=X:,f͚EϞ= 8p8M XIuЂU_W_u&:"?$kv8+V0uT}]͛ĉkk/3βe(**b… 6ӧsꩧ8rGC_%7n|#zbcUTWUSS]C& (R@϶3NYW>ϟ3/<6e]EiET1)“@@ 2B_+1iOfZ<#g ')an:} E7Towp s=9ٳgӧOBp4()p492_C)P֗gvYJa&yҘ/TI}9]s}Xd :{/}x \pӧOk׮y*A\k֢׬a횵[ 7P]UE&!ɒW?@'}!P[k\G(JZ Wl 4Cg4 o~X>J&?vD2=v>^CEEEߦ_i!P6\r [fȐ!ナWsp8M:a]i駤EW@CJ"M(籡§MQs=$ ,`L:]tӦMcС:7`ԨQ_+"vl>ZbQߕr=\ m4H!)J*r ٌ{/Q~ TAkȇ\G?lJ#v(aKl/ ()賂:TS!du`R=;e^_*?@ S0.~H!y;C/lFh &вeKkAT |h(Q6m2bjV_LQ|hX'97)|GΊ+wzͅ^ܹsKVRR޽{3g{мw't;Bh`Th(6u쥥֭he D+e-ap׶|&>/?֏0ґFP"& 7U MB(a\i$!uȰ4Yׯ:F?7MCr83̍7`ƌq# 3{稣z5̙ ?̞=A:s」o7? w?K\;G}a0jԉ0g6ejp~SO>dѢE̞=Çsrwb~FgݓH)#Az$v3Tgkj!anyd 7t8?:n[WͭSOvq」8ܙ,X`f=w1tplF(okw\;؉6-[[oŴiX`pg}6{/=z(txq;"@HB qH]O 'gIL5ƒb(3T<t$kLLɘ&!'Ds{-L:z+u'X;Şu=C$}P:eWB#)Tv<%NҤ?6{Qij;xNvBF]+Ϛܓd;Xtޝe˖qr;h|H4ןy_}q=7wF}≽;\ЩS Ə}}pԁRHݻvsE/3uT[;\ CMCԘ9況OOMV },LLwf1+a:P mbVm}u뭸PǟoqIٗhHYo+UvW@ aﵴ"ߦkI vwߝYf1qDƎ]w>E/n-_W.kױcs9nH8֯wU:ж}; 0i$ʥA@zos^cҥtԉ.'|:V  b?dztܬTxfF@0)<I6 `?ee}i(E_یdw|ԙOb]u+l=^5fz!*8 ~a7K W_G}:Ăc|M:oS_j74ի+瞷tÑKx'ǙQJi߾}\Q̘1̜9 ~/O,txq6QJ7QWk9Vԋ8=ߦ e;ۋHiY Si1YAA?Vgf}|?Kψd}25O[6 gͫ z{ Du L}y#u.@()*ObAdʈ|M뺻(F9+Z}+2?%ld~L2O0bĈBpl5)?{k=־#8`WfZ9n̏8]_\'Cka_\s-pԦx1oVW/l׾ڵo~r=Ƕs#W^!JJJ83f Ǐ/tx?'0~IsO.^FXf Rqgyi;uϕ(Y7lC\>`=aO lpʼ'W0U/6K@Q~XKm;'73Q=D66ږ>;s7kO7n/OCr86C40~=i'>`ԅY1W]u'ee%us_k81{Bp}'p h$ڴ)m} 7n/2EEEs9=a9 \ ЩO:9o 'Á %4BZ䧇f7ZY^rR< 0 d;gA@>^NzsM͗uV^Kx܈Ze,%$ؓZ"]4P&=_K}]^hg]йŃHDKJ|EM9)P+]| \ um nj|h_ܘ0.~~{F iFk+3BQƯVhK!ʤk%:L=baZF B{ȏ:D#O?-Z0p@^{5ZR_x]߹XjBƎG^ԩS Q'^8p81rgҼysƍGYY֭+tHmRòAq<ƊwQq2y+I|BoHP9_u[Z`D8QfƊ{kWiD|}OBܫ\ו If#uUqgB lM}oz=?"^T B4$D焋 Bx-ReE}8}^np?'|’%K>}:O?4#Fs硇CO/tGD8)p8G#>Syg}>@Q9~(SONk=3N:3ɹ9K9_\_j'p<+Oo>U%9}K~2!F{a2/\3伞ı}¬R;]m,h^"H^]eJ S汎EB HOF|ƱW:l}GG4/A^{SO=gʕ+y93(..fƌ\yw}ᨅKw8&K?`ڵ|r]:vm۶Mr 'qF&MI'~;v}B娃ik=vuu4d=6D.|-vsSuzMTNFM$HI4\dDR'I7NN{ 9~^#wN>w[DY:qWDc|#G_Y`G(_x\8AD ϼ~i2N{"x6)D;cS|a}R;EgߡCnvzA.]QppC(]?ϙ/hk"?9qS>`HG"_Z!/ʻ/V^Zxg9tnh Q#DD}iy8B|a&{YׯV^{s1a{=?7pda˃6mp8kr!FV2|8k֮-slSLa̘1{챮^q><:i/>{N8UPDy4d~2:y9)u[+?>#^)g=oDztd^Ld$RЉrH׶A3@i/E"S^ !op"J7ash\?Yݬ={y&á[n Ggv۪~_J4hZ|m? )//@ko ٨VI IDATK # Pyoc #sS4j{*BҔtsEN6Kn  {ZBψ`uTN.q+&H+iE|nSu{nC1Р7I.>"?E`z+e\D^`0 YKu^n~f{JUr<aHkJ S&&o3AZ$;KM Kw[-17zU;!) p8 :[Q.q흼o5^zaÆ1g:B_ ~Ka=7RQUIuڈ|?K6Ȓ rSӥrMϯ˹uzrB?rE~;S_;hƬ7"/^H|%2ׯPГo~uDHl+Ꮽ3=ߌh ye!Hۋ8fQB BGM cw_h4ړ¸9|Ž*xC~h_{ }㪫׿c=!9vL/;G#''&Ȋ,TPSUPk /]h]S!mw _cfȑ̟?aÆqs:Fj`c9] kX~=Xʪ kO6XT}G9~~nG2خS'k;] O{mEicdM~xz0M F'PG3D#M?a܇1soo-?) dH[]"N,ʈ| |!ZVϋ%¾PW~bHЗ[ѻcE~tl|d{|3ƕE9;N;G#kJ4ڻcͿ*ſ[-_믡^C { ;h5_s 钾=C a֬Yp oߞi"3)*k ͚A*e`6 UP^Ny7SYUEuuՙj25d2~?3}NwI~S¾.1OЯўa~Ig [v ~uB?7EkrhSD>,XhPʾ[c":q--΍d(.rRs2،Ȓu#RHvh9z9˛'~x~R܇ T}^Ik/"#jS lD8L?dV AjLP<"r?| {6k7u }uvmA$Fx B/uO>$7`5"zqڂHp\$<^3b,X!½ˤI ?[ٖ}k  }.߭]C*BVKRSdj2i֖rɁyn}7w=ܓYf1qD֬YoBUD^X()gˍ,bH!l'sIJyx)/KIƁMthSt識ݶp"T\~ө8=_ƫJu|5q ~ APg8[}7nh r*-{_ 2 N}:W\qcҥrdQr&}TLH1" kQvAk= 4j '%%DJ*9s]:D|['y][!/b xM8?7}8!B}^!*iL'tQ9BH3Lb~RWB);GjrI-B6$e,D}^*#㢛¸B6RGuugyo\|;'|e1Ϳ RKNG"_!]Niҹ~Dze8)--/.tH&&p8;2?u7C< }vZ,[AT}amZ;wfƌs1wqvyR.lLX.qǙ)#R -_VZ 1Ĥ ,2%}?rRO\[9Jqz{:x-EI_$N(ң6vbVoƱim =*[*1::  H7و|)tv‘p5:'zٚ>O'(U_Q~⇃S2%JH{B?K܌43?rM=3 YQoEL w/1۱Ӈ_~cDzvZBh8p8?8E$K[-Q}=Gٳgs3vXf̘A=ϿBJ*1E 9Fn4&ԧi~&^ٚŏ*]SvCIZM Ƕ{2sL:,֬Y:$G/kñ#{/pxw4~&OL6m8#yݻw˥y\c\1*yCRR)EEPZZJfH!Jd2(+QFe@kVkHiH D :Ni[n#VKM'vRF'|1:6z-ICŏdЛ;|ѡ։(>a,"g$0H`Du̴z晰!_.G%c% `&lbx[ S㭸WB"Æ{ Oif)k#Qh}VGo։wˈ|)4R^q}JP(B}ѵkWyJ kVM_sP]~Eo \~唕1tP^y 0?GJ#Qp(R!Wma'=I|XVZoժU@g\;0?7-[grr^O~OSoߎ\X`PUe?5tit 8xu F*;}sߙ 2}|]{" _Ԝc>uG:MǾJ0½e'`?OE4({iWP_1"w.w4X1 Sɷ~]|_#BBX7^LgBAlHїRBYb(ƾ&c  \TN|I=%@M?l{/YzVZoժU@>J{"[ 't_8P|MUF!'|KIIffgټy3[ne~~(عs'[lazzN)]YY=ؼ|w^3!'.:4׆c{8{AO{s}D<0/bh~n~\3$zUHgL nl?|8je@t?paF"\j{BoHcE8?>['}#A.D(a'(.yGVdEsD?adRHzR1#&GQ9? HڴBQ#j{K.9'sUW?|O~,[E_[N[jժ>{TLk}V^rGpsW=m]wg9c8s@ LJS8m0{&3RR9̰efmlڴNQBtc aWư|kЍ5^!T1;D(8$DߌXqh[… _χgG]q i#y7-.dLW-b=kaf{d.\H)lT1Xtɻ]YߪUVITJYGi\JIl^tկ~SO=+__G?w?{^=P?|?2IiǞzen|d? 4!a/NiظtxXU譬PhM_ks83>Alpα=!٤I,4Dߐ2?p}_5#ޕ!u 176޻ZbsLeЯC@߀FX7ny9W;2l{ Iא6!!n^|_)Fv]al/yNy^31Aw:'0oQQڄ2@~N% ' ? ?VX/~񋙙N8|3ZjUVPm7oy\z5߼lٲeM[o_?ﱏ},_83xζm۸+y_r~c9ՠL=~Ti$l`I^Y ,-LOq1q ,// 5~1%эG3X׹…D0}<:bk\ p4ѧԱ{OA>t:y󎪒?~d8ՂsoG[4o43.Bt"Sn;͝Fdҏ^XNBv0(I R"(v(eIgr%ȼ@d92+YE.5Zioo)LINEAɀ 6|m}__~7s^{-~zRL-jժGHy |kq;䘛lf-{qkrVN۶m?K.Uz/}KZQK]%ob7wu$KmĈua}c엇Ag~ {=URĄ=<۶n۹kNzD+rӴ}J7atYi\~`w#b1pEjx/}Egޘ:נ>k ~ʽO%5nim 4\t!~{wQ`X\:׽3yd cBz TF Hm w:ENeL2a4I&&fbjE,---#{YBY|XƦH) g@*@2muɹsQHȳ|lz^x{,gqW]uOZKI)7]04EEmժUVw_<>V:,.z>p%pɬ , k%صR>Y?.[4iz,/-{7 LMYrfgg<;w`qqAscwXW`6|2TzHKzh]Xա~ցϗ1LɹgDwyta>|-<zWO"'\;>?CWO8>?O5 sӄ @>^ -ʐ)Me>'dESP99LAbgqiݻٵn:E2ׇ~ ʾq B&ce\[_;ȁFC{S՟KΕR m`YQSl?y7n|jOyjw՟^o|DRjժUV|Goz= iJUm!ʲdiq]vsڱ-9LLazYfggu],-ٜ|0^ \ۢg P6u'Ȱ/ ҋ>L.oDAfG9{]dwר_/\B7Ct3='HWmҸm[*#[4vd'};ɔ6drK:Hىݵw]L"/v!w/" Җ]Th|QB`eIl}e _\P @*IGHQts:Eɉ 6qv6n|۶ΏܳF>-O|"W^y%W\qzR GՏnǟ~VZju>ַЇ>ĉ'ȫ^5=;Pt FGÕ^M8foP6S:R].| |c׮]NvgYMvd4,NN\j a|dPI IDAT'2!H%.^Z.skDuqy 5?GA?FИek:c}as`[x&1..4_ NQ*.~ȕP!(p?L!r̎LoIwrΝdKˈ>}QBdKPRp}QRA][-Z t$34ss62ga!mLm6}w]}+_ꫯCN||VuY7{;ܪUVZڧoo|\ve|xɣ5K.[0Q %ךbx103^MIsinh7&t]wŝwО[gEQZobbN nCB>duQopVmȱjA0ν6rU _wasCOs]HԛN}qM'ا l#zみn: [ Ϻv^#Ʀ_Hc?D9~@cEJEQYjPHO)l5 Xdwqaw[og䮻vJ,+d \?:o) :zt)! o_Lwa'=a 39H2!:9EtbvfMm㠃b֭pC{꧰ws5]r-|9y+^??q'o|/K.w#ZBvu[jժU\s xK^E]_΃59%':%kɳggOhï.|pcΫ1{F)v/,svl>ϡ,Ȳ4y7U_}lEK;'}J8$Qg rP( M7|$'}po28hb'=xC~p뭷;knW}2RWdZE.*:fpK~8`@ >q_2 Pii!B&LMN3;3˦-[زu+<0800``!CKľ]v/{xSyk^:ꨰ^^F^Wwk϶վ|+zJVZj}(ַx<^"XpI32aFGLr21<#Cúdڰ*&}CR6̾\i2:yN ) eu?ݦ]+' r\.<$p,LGOuH C>>x{*?}i70{lؽ4 ;Ko\ob]2&5ᝃ K-bN HRc%2/ɊSRtJnńwBco.`ۦa-lܸtoùKz=AEҔJiCf4JYf,quY\z<Gxi6zotU q&po>F 4%0 ` νUY[YaLOMqHC(܁D@szs&u}7_0zw:~޻?T71þ1Hއi[s¿'FXQ~Ј>Y% ŀ<:힝 `>G9~fяk%>RQVJ* f8OٙC^5zҞz$BZRH2bv~ɮ1;M7y~3|0C![a!,w0#uEݻaav/0Xc:ݼ~W՜vi?#~}xf7VZju` g7#=vM[oK/嵯}-{.W\q~~1${)oVS7x)6m G݅} .D_W ]w1YFY` RJۿo<2R6/k.Ѐ|,ӓ@o=72@ Fz:7+{ވkG?`_V OrW ɝ+νa޻вn} c} i>-"0D DZE'Ty 9dd`l$m*"sҒPV(bLߘޣIB"CS.d铹Qy˳ ]$`tSSl 6mbfl9>:cWXA-{7,-f"9[袋xCg<|##+hu lVZ:@sN~gvgtiO~bMi۶mao|#sssy|S裏Mgv\A*iC6Me#>lrywhO6<':LC&l(? ϯʒ,)v/,091Nà,QJYZJ2!XDJK WQXLp}k,L{_!?!_'o!_7"O`Ta߶I}<{}3<x u'?qqkyb~/ b>޻.m?> Kdwjf0.\YXН%tjL f6L43`ǸV!Rh*Q*ִhh^{q߄ У\`dFEnerb433lڴy6m 7ܼ-pk@}h]`n,..*lN|ߏxg uZ|w]&9;$ = `\,KL2)! !Ǧ @+|a Bk{=k_caı@ ygҧt\H-~ƍmMi""b/*hs[k],,SUJUz+_ƍ9=$"ߪUV9$ pWO}:XV뮗%yG0Tl-*B0{1މMp<}jӅਆ;Uخb_%s񗗖U`Ѻ/ v!u}zD'\+ Hpen! 6mx ޵(>D_5r='y O 쇰p|:铉8NQp?ڽ_kN(?}$ a\{ӘW1`FMoe>JJ++V&t+t;rX7@,Ev®]^{T _x<31ɇ"+ q2}'tL05 3βqv)W= ZCUA9^ai޽%eXU\7/`ff<1|_O^Sjr?_VZڿe W| :(^Wjm3sNv];wrC{e!10k|i,ccHXy2`9a , ۄRf5JYqoԪ?EP`ܗeQQ,PeK7uF.L2L pɗF9CTnwm| ޹!sk]捘j.t3Ṭ[bל|:aeek ( J2ePX+{}"=Ֆ3iG*-_Y>U9*j`!_W֥7Y97$za!^H2bzR~'p?91SSSLMO195IgKgT c{* ze6\,/mN9`P J۸7(Kʁv`JH+ys30ysZZoժUX?* -]xc9o;wpƒOX >zt9Y#efT c[Dw=;W9vD"m7,$o _֚Sݻ4yZ"@x(w! _{OhjZU&'o>罓Şx`0:m}eoaZ?3LjJ)_V.w=#ˤuZsAk|$zUTUJ>ƅGOHo|޵Rqs? [Te;SLLMНPtsd.{Jhi eYY鱲J*z7׺0s=< +zւJSEHwUo|] eUUJtUUi78v?"]8>FsNQttt'vt "Gfҵ+i6TU`0A ]1^RWfp[E'x"]wOzғXXXe/{zRAFRߪUV|Q҅a{uZkrr_o:?gT^ig5CΕ gHt~-hB1!_8@w*WT, !Zټ[{ uP5އstp?~ >ׁ<];Y(2P&u >ɏ0]BGB~#4_T9NC*M%/wc߄zh~j9㖻e&B`nzڴb> q;)ɝږ[o@jEes/};Gc{os+kk.Fh^z{p^IH>Rνo<ȋӡtt;tE q{RɚoӥZZk&%3َUwN.s|@f[X c̏7n†# .@mxP|2Yŧ? Ws?>/¾mpaS?4A\cmh2poFм|Mp#0&,WU`KoBkjc hi_2Ȅ@Jwo\x0McYڇbz.$_&_fat n: Sҹ.4_p;t: "#˥ ˷}eZid08XWޣS?}TȽWJO"{o=r(/O_HGuh,ZjUV`1cBunYL+XK )fY~n_8pJ(=uS>on&Y!%КߐM#ƺz ˼S_~k p㫝{jDF=B]2i_ N~t6qw7(zBL2]_xL:ZXku4=6^sG:*i@NOwƂ{J~.!?4fX'ނ>7_m- ұB0|;n kO-,߻K$ ~@Ѓ`nF?|~~^SjuVZ:A 'ȃ$]v)ZQ`<)oL2DƏ}{w(&n~ ɴI`ޤ@ݽM{8tSO2rRk%{5"8\|Rp 9{)l!PE]v`oor~9Dt|cEYdB=hD{u'_'Ɇ\|#G e\;:7֗4[Øl?ڵ[>T`/a~F!~q8aW_awVFL} RcR '6ӀwП'k·Zw޽0N/}nˋB:2, (\M _tȻ]Mƒߺ>|Yz|;9Z+ۖBnժUX֙#) )lr8mF{yi IDAT˯i1[od23-Fd]`a3<R[dUV`rFFj z_rGMP[oݫGglJ{cx ~\(~:&oJ}3 !q|r(C??!%cB)elb/ȿgu U:JXy@jx}JIn}=%p^K۳u׭מ;R" ed o?ۼ{HF- i6RTʹKs]Xq09P{s??ӟ4OxZ6DUV`߇u䭒C;?oڸ_H=r*, K7~'F~O`npw!q]`{Ot {?]Ͻ[}FP 1ʥmw64?2C2Ј"pB󥴅2y ]X~wt6Rc\Y(Te -L> _EI o̫N$!v{.g9cZr_VZjui*PGO}+s:^ݼMC?ʭ;NP\AEtJzp|RkWS(lk>C|>/7%KdHsk8iy)ǯZ:7f@VI[p"7KS:iy"|a~{%]_Qw=޷=l-Ie V4>Fp?=۸L n>޽wozMhfA㶱秀/B.{ G>ςF  I>h…YnskorȄl <WJ.JUY^UTںU 7}ʙfi=&z;I'I'EG)L:Zjuh8J>YϚ=SvMO 7z{=nqaiw{s x!8S3r0|ѽ 6Pfb4D߷gIq|M &-DwMQdGN{Y}=c%IHWI?g~ icRhq:~+ B"dp!%Y|[OtB e**(UIݠ TiCE08dHiiFmoo>tgs5p)p鴺NJ]~VZJZcO6QFmZ:$ɮ5dAC sU<jtVaB2KK ٮ]oBo/͙ .f#A(,/߁GPur,VO|BMfD~wh#ǫ觹&bK1;KjI!}ɪG4n71&]ttܧ!vq!Oܛzw&a\"$<&{(l}t-c>{o\(p󥫜/˽r~s:޺(ut+m_e|eZh- 5{'G1CD:?3r _'?ާ^Zjui~f*@]nHJIl^Z_?ySvc=O!<߇c}|/ 0/\YU`6 _t88Bhp C9ɴN}O>Fk.kxHjdJU%:MmIe{& ! T)׮NJx7qEqgr5׬)r~VZozjg47BOkBB Gae\ 3;7obo܏| n9N>K 8&:S@;aEb~Sv7SXP7s=<m7RbcmO݂Uf^mÐG)ps *c".|4[ 9{|Y{" ' :߫ykH~OidR}w;Zg}5 Rƿ2BJoȹpٰ~ ƺQTl8~pψ`J*!YQw ;/\5}oih2+*P?cx^A7Z 9?'N4w{wާn~RUVZ8z ')u뭷se{Cka7ǣ>/zsR}YrvQu7$߇mSBvit{_PϺ";'~Tt޵7|Hn7Dj,WnO~xE-飬npt[!\=.4?@>uwzwI(j37-Eb 6Xu0t&ÄcC]kM:xF.r篑&zi5X!>-໮m|\*{2 εo"k1!4?{؃}8½_frH~ni \4VK61ZjժU]۶m[cJ #&omjcitٞ-q-%.Kvj]OIx iwyÐv dHk yDZŽ^@c-v ]7P!q,r}{|z٨7*7_YQ\(~Z m!&hwlGha4i=豽Ǟ|#)^?8P Yo첡&MfAwmqBcJqDzwog!CYᾈC"[(˻`_ASO`?8|{<2PU}o;lozϳ6}lOP ZjժU^!Ԑl?Gs9I{}4ȸ7z`߄涌0u~59s^GX.!/C[`M9‡AA?fyn"֗k7y݀n7ݴv;hWq~]cPC}#]τipEmZ|W{#3[it7FctsuOmblH@Rq B}t;qvgt]&Wc2:-Л¤1$2{2qH8T&ۻ?~׼; !]t+++ IZ_js[jժUVCzJ3a߁*DEE I8?y}^L 91E1ΛП@ވƀ.ŇFǡQwnc>+ VEkPsCBoC'fln7F_#nP-P{<{w ~§PK7 \wRy o.|Q?!b|$['vEj86!x3<}޽f8SH$:yvV3eXh/>E W9?w}y!6^.ƅ:@n~>ކK=ݻ||XNB']t_=BN>d.B^W鵺rr3ZjժU^Aj }2#7#C^Ƅn~O* 沌x ?yZ`)o۬x:X+,8?/k, >nB~*nt Xa߸||r="yp=s]ꑿ4S}ϋq vx"?+#8AsF=K>W ?\1{w⻭Dn}-M(/h2³1`|οϱP.+)K[TO߱pZ/ W5]1\ @4*c(SpoNn ;m"rS~ z~ͣosk:o3Xkuo[hVZjժ*ېk{$ 9NL^ tN26)\܍Y?~å](0!V@0,gSHAƇvV/(yKj.gKGc<k ..|6@ݹsƻ)'G$`#:p[utꝫ?|ѡO½SѮK a:>>wpߝ v) y2S{FP 7&q}!> 썈ν+>)Gm?w/ꪫ{^z)7|3/~ xЃٱc}xZ9UVZnعs'w~Ca~~G59^V?8#qߛ ɾ('&P}Bx~]z7o=G me\r-|\y\~uQ^{-z^uPzVZ:sN~gyv'nF/woE\xᅼ_Q?K`!$ &zV˼l;1E9/.1N۰!Np$ i~pmOA'9x5"@"]~/,<ѱC=zژ/UmMO܆$Vj߉LA.;W8'ޏm4VrZ.<_c(a}pѸ ҲBABz&{ oWZk.:!ڴn  %"K/yARt'LXNLPt:EN3ԶCeTJeC`kJ h8z|)'!¤O)mIC¾{Gwo}O}Sy晜wy\puQznSmVZ:@ucx߹s'7z?Ce۶m{#&ս?y8 ~w;Y\ҦM{,g?,e ~Z7- 7}xM¯vpU;~ƮYV2"t"k?Ԉ`غ~CN|NW!U k4Ƶ7#xnw IDAT{"J{cF .??<bÆ7Do>tۯU{}"F_=ߞp6)ԇM }hȗ^` B {{i,/(F48" #6 ]u,u ctU{T j L~Z!{&MS:TN5m}aSX^) m={bz6Dߍep/rz_q~>AڰavǹyS6N*upRJ:5]ս?&H)i6yq|͜uYr)YnUu3<Y.N9'98,, K/kZ8\(fh/LM .ϙťG^}0}] ۥ.P>?y4a&s;i.V}?>kC-Gn(H|~_OB]NȇgiOAIK ks"p{@}νйNxM݉£ٳ`>,ޭk\LJ7QD\q j>zZJ%6i"҄'vuM^~l>UWMq==9wW&ë4魷o|(sss o#~ԓ[sRJzK+|5ϳa:w/h jenF:6ny/WUN=Tp?!\,_/!lr *oLlUd {rC֓]+:a~Xi ,A8.uC~N;36A+ 7!I>T_Y- `8ېt:t"ؠ;:w>vW8k!]c~ydùt.0/[X$*`x*^3!̩9܋`{7b"ɷoPG٤נ^QT}a=jRzm|S9 <_iz:^>#9^0 se`NvrJ/=lܸ[n;.x≏yJr)K_TR\mYf s-Va/f͚5|+_az衹ciCK %wC>&@iV臘Gǖ*ep^1{ek:WABϝuN~]l;h lT/|WP]pϕ;\/kP.>~ߝ7"6,_g!z3' ýHJ5>>}M&}&}} :)Љ{/>tR)H-Csaݹ_(To ly)pWs饗.>6mĆ g:w<[7Ww)UTROVRܱuQ9sY|9l6Odxxq."֭c8ŐR8 q/} =o%Ed {M,z4-M{1^H-[Su>C W &}}4fhd1Q Sg d\0m۩saͷE'u ػ-.zq\2ȷ-=K~;WŊ+x=W_<>9.V^c/BtI!J*uK+Vf͛T* STVzLMMqgg>O1==h4XlZ7o)V=uqDZqrJEh.n=ɓvP}ҁ&8|Jw{/9e|,y򞫋AVOeq.9 #ؚ@Hm+c;{E?f:[D :x<̉>b "] 1M`|ݰR˷k~E6w=t6͢*5~`_K&s3!n,D=V%E.ߕ067=@|uJ5B mZZ3}٤QFGGO*U3,!Y|_5'Aq{aUs0b}{{S>nzl_f _Wyk_˛f>Ci&O|q.2qI'dwJ*TRb)P8ؼ~~3n:<|R𒗼jؼT}iM/z.':|QXvm\X ֢1Ѽ?A@{˱ugm[^`_ps0`\wn4-[0 MZԈUTFhv MsھoYWh8:/Y!^WS{o:*PK;gER)=K>Raal^{+0Z0`fb*WMF_́AFh"F(C  ۟y %DNY&kiJn{l3or텇lZw}6 Z{!Zo|E/NkxGA.Uq?pƔ*U(ԧi֚J!?뮻 O~V\Rʸ6v?Ye?Q'XL&Pk}Oт`B ^ h@ej {3ISbաU6^Huͼb[yYwu!٠"WXM{ 2(l\@GWs0؁`=;MDL"z6|_7R2D!#("_թ7 0h1,a ch%w4Eh%)$([`5,8d59w(:vO|!;ƍYf J=q2On*UA,LH#+ظq#Ne5 s饗O~p)J)mիqAGr^d4Gaȸtϑ;i22(}6c܀oHu[? %B_9s?6ϞVjMڑ*3˲%jiJE'e%HOZIo^{.*@6?ݛ\C֦9FB8*5އP4\}{]po:'7G 鿚/ H䋮=^Au6>"+D jF_#c,Z%KX 5Z8OvJm`(BS|w96tAw@.@{s.u9N|Ѽ]SNu{] b 7+UTR4;+9׳m6-[R??/9CCC]u{`wV.B+tE3\? !uCߺ4wI#|ywY#ƥB*3y8 s^p{_ .OڊdpeiO Jhjf\Ϲ ^w]zw `"!s v@tq݇wx,p_Gd>:-y.5Fw3 {slsOn=[=T3@FͽT5e|b,[  `ǙÅ(-R-s턹v|'Ii9?]BC_ ]A6ws#Tyg2jÔ*utK*U rO8/sGPyK^?C:MS?NZ]_*ޔpY{Gh!Ra=uaGsA_v לr"o.\2W2v\2\:*P;@~nvӟB1-LsQ d C]bW[: 8({g @V@>dGj>pm<.Zgҝ\wRd0AsW|'"/sڂny{.|~aHFT*5~G_ĒX!X ,8N5`0Ci晙k1;ff0jo'$5p+e?{t=3 @: n,3Lv/f,9)}.?Eܿo_OaRE%*UA,~8^p~ \{\r%4 /asss\{lڴ߽beRUki!h^P|GoǜIjrα҂} ?aiKLa:EMBAؗ0܇!?b0 R#ҟL4Ɣ 1U$b{.l+sW->\OwQq&oU_g`]u>b_۝|.tva1L}/vʽg ɉ|m"#:Bxw.M5I;0iV#&Bkb]UWBp_k?0-ai&ˁ@40O2 SӳL3;fajtsha T.,_rs)}R7=bgae,9y5+:WBrK*U VXE{w}{<1˖-Z;wkaӦMp~oQ:~yȇ<*T>/G36^ c VN^<ߝz

Gm,4M^8_Pm1' Lr"tϳy!I > ֭W]D0^H *E*IJњpzd$+jF~n0`b'I&ef|;Ɋ%½ͽY,4 Yn_ȵ/BԖLlCw#fXGRe賟lY1~UYETRbiNrwÿpW288ȲeːRuV&&&\3ΰ?cpK_Q9ȇn b.~%zaDƶE7",r+2n"UHIx`í|>5Cls,Bk6wedw-̹}ow"z < Ê~6@ }\蛖_~:d}εlQ<zv<[-NswBrR1JZJVQ09u5 lg;;#;w355,mIMqTI5ImQ=O.<_@?|! 㺯0|l&@9d`բ\>^}=O?ǵyrfժUE.٧tK*U >=gQG<>+yI'ĢE"}yΥJZ̈́.{Y |K"/ qU$2R/nָ{#.aOOy ;;)qXW0G voߊ2ԎW{Y,a2HTQɺsuU\|cU; 0q/n0~,ǿp LH_]yju ߇ .WH ˱wNedMGknv$a| 05K&>[qLQhPNv`4ӳ3?fա6:O6k {Do>̲ٺ1>?:a 7);rjŊ ~ *dRJ*uH)|Q}9 ~tϱRޘ,Pa@= yD3 ¸YbII^0vT Sa흛{?F D.ב$M{\W7[n=Lp/ ~XMIX+Vs-Wi"oDd ^f _~p'϶9eXEth$(P`?;y"p#v"j̰2w렾o+\=\{9UO?qdo ${iЙCߵrCp/4=;80o>&p IDATCG QQqCCC^QݱF5i0t3%j_{M Kf&LO}p>bY!ՊVYg瘙efv9fg癛$t$ 8j{ڃϩ{I>̶,:Pv$dj#3Xg|yo)U֝g-J/UTVcclnvӈdդb\WӖ-[w~m)=||M"9HJDd]|)#*@hKu0/-^6O *z}}@LaOㄎAEHLGNBG\|:it8s':gn ovpzW޾@?|~{zCw/Yu=!PI ϗHJ ZFNVodT<ӚM$aբnZkǯ :\@k~Iv^oPՈ INǻv. D*E*5֛&ݣVp-@ wMa<^t2|,'y&ʹ0?RX=sYtpOC TRJ=tqDzᮻc1661O{rR/_"`OLWea6tv~:,/+Qմ862H-A]|s3P4=Aץ7ȹC 5y&RIRA%`ele/C쬎SMk˹.!~v nP¢?Vu p\OV ]y=U/G_g,g}/^PpDMtK]- ӏZJѠQp1R};l$vVvJZ#N 5?R!T Q#d8 $U$JowYE5Jf{s/ cv ;yǭ)/;Υ+BA_֞ݻ~RJ:wJzLrptst;߄ݸ҆[w, J"!t#x>R?%qHG/(½ /ߡҸZWd"tԚh4KVv5F-H-ЖBjP=?k_{{|]r|m{ u .BkUޓ>yj5a5|^_#/m .J "l(8Jb=,[PvL'.s{B;vك k^С;a߄jO}c ܯ\qD]ئrp,![[{0t@`M߳P8`v<\}?,_Ί+x;1Ak~4I2wV؜x wg;1P/c|-$ p+f>ǩ뿸ۿx7Ǿxv I>n93[&Xt*U<@=WO-E7硞`K䛇C>+_ 7pgwWJZ DTRJ*Ujovxٕ<܇`s͏js>N'bp/+ƽq5RPTl T25W չY+$?Y'Oy :ȣ9R4 rp$EVH"̳Xlgo4DmV()3w & Fo/Y.tExB!?Z{̥^^]/`}0opt1w \!MMKHSt`nh06:(۷ogffӡnf54٭O`[ -R"B ZF-+DTgwzѱTZ0{6[7̶Y5 5}| ,t7t~(Xr6ϴZ(I/| o+W]*eB'bRJ*U~7v "_[s! zjJ^5_}辴"hkmP[3?=,daYX]C+-BI U3Òh;`XE9WR t5R[7ͽ'}9HtZ DjTfi)eq/m,#X7ۃT{K玣n[v+qTɖ { >I_jicp`fzF%Rcsk$3?NڨCI$HL (DQDiODF>t3VuWѿ|W=g\rV4W/%'ՒĶ4l:")~2n\]%B `ԓC8餓x^}]vy 9J*UTP}gWZԜ?aþ@z֨RՈ)JOHRLb>9uSD a?Z 2޼~giJu*FFF8s/UTRJ`;[ ̑No= GR=5j/5JIϊX@NLβˎɥT3s Y=@Zq $%&N*L%sty>Y%OBgau?A~7GRkV.rKRln6w v7*$ wQZ鬈^uegu?kY½΍!}(ۭY&';1ĄJPIBEԪUj*Jv"83⃛y-ڱ7ZY0&o_hSB#S}x~iXrJVs4?ݬ8-}C_0L_.G>k-|m0ʕT@?=ywYpk|.Z…*W8] inezjk5e~n~B%TJSQdk]|7 |~0a!X+;fi޽X~!v֑7IB/.p_Vȹ{,ZܻTKFY $jaw3lȟ5?OB+E$%Q&Mrچ.n׭FidbϦG*ˎ[‘ҧ "2NkH+ʗvg@o_2|! !7=!=0ⳟ,G}4oxͱ W\{X<_TR /|JGгO?c4{!Mx}T1pb**zzFNYV#BHAd'*=9ɽ{UÅGE 5ģ;';ߴ.JYఔ)&<#3~+f-],#\X&Of?Ҹ~ m]:K4 D)e<"w:{]67]|뇐NY{`mza-}>;eo=( t?3${vlu:0?Oo$"("e]|S r?gt)68|!{s|$'OMMqy#8bwJTR.=};Z/ {{~֭[|r-[1*9>a{G8ֹ*Tm5,כ}h@APNZf:( ͷ.y:~`;eŬiN/-?^/}Ep3C0[BeodfAB?_p@rʊ i]y7y_+-Z!-yiܩEkk_/^/ [@)m].tm昞bbbfP2o^ŗ)%=O{ϫaַ6kkpg֐<ssC߂a%| T_;ށ n]\n0}yr)2f<?V8$x"e/UTXJvm_5kp9h"jؘ/f͚5|+_az衜viϕlmذ[nk\z饼կiAUS9Z7!ASM\)%tZD Q%3n|Lm{1)|+ug,[{A|A`'z|HXwa\J6BiENl0523P(ޙo{WxgyJ!ۓ#"} R)N >v % ~*FS7ɽpz0@"pma`ԯ]m>ߙ⠁ Kp` s~\ sE\[Z1;3C^G)INӜ?$ltjqwCx\,tJB d< }̒D]w n.{%, }~Xp+T?:/C2rEYh~J>4 j]tYnG~8cccOAIꪫG?J ox\s zֳwٿO򡗌x(Dz~V1p?tAOnpA5'©&6m ҐPcf ]|W- :{Mºڋ|)U%40J60%~Rfw stuvO;Kw hB>|_ϝ2X/* ՟a^IӔ4M2=ݻws֭xv5 1F [Q>D t}}+V UH<~{{=`#(>]K7X`di\{k0vʷh ,>loYTߨOjgtK*U )Le;`bbWU,Yăƍя~ ^N8" p%}︃> .u]wprs '˻wNWVk10f_XmP T#mT(R*yڌ :Q$'rg=k_o\^G O|8>;0RhVĤhӌfHF#glU6i 4v.t&UiSlڐ;,Npg3 :":&':C}>ﮊbD.}xD|_#{ۖ^y }`WDHKhRЩ׷s/K:*TRbi6/͛T* S,S IDATTVH)`x}khl2jofіڿ:wM7 ovp顈HRv:>64l+7 9 ]*Mgi-8uf忭 {dz~=X&T_O7WEkYGϿ}2UԸ̵ /#( $Zr@:_nMmBpf,s|!X#ܰe ֜z59\={`zzv" jMYL5:*v`j R.>؊nʼY Ze^n=񅴇gmk+Щi&Iu"hkwZRGjJ*uPJ): oΎ;سg_WY~=ozӛ8V͛s)u`Moo|Wٳj?j5/*zfT0#8P đw5Yx~jY=eC:ޜX<. 8H\ 3sA:N*ɏt6u^kFki-ýsQ~3Fo "PEgEBڗK[",rF&"D݁+\}nDRJ:N5J`1Szvm<̘[[Ja?8/u@E>)OK_~;o|s.=ĕFMƀaa-5aiD%&<_O}B,\_K:~V/Mg!m[X/Dũ"sJHR$JG("l $"{̇-7kGieR\)Z~/J%ZPHjj+ı` 0S/ u9{:.iД69u#lw!~]Elm0 .GH)t84{⧝ۻj5֮^˖Ѡnv:ȞdP< d hH{`/޻:DH]p+_I߃}@VŒ Sa^?oשyIm%ݟѩ0}Ee),װ^@&Bk*tLJY?@J*U*o+V`t:T0}^R.B>Os'"WJm6VX;VO+WdݺupWuw4y &T]<{ZsКG[6I!)]aheA>D:ޢqk_ ܮA žH["/\~!g$i!JJC} ݮ}qmA'ւK`u")/ء5w)jy~$AHӯF"c$dy9bu@)}wt|BP+!PH;/}A^Lb qS*UA,Cal۶e˖""o}+g}R;w211+q@Pg>>nws]h)AIbvn\\kY$R!eue~jekL 7u&촇|0Q}P4"3p`+Kp gKwfMr[[VasN$g1QpEQA KJ;wNR{`>ZhSEV&_&؞6'Re{K1޵0},rVsP ,~Gy×D]e"%)ϕp~Ɣ*U(p \ |_#^#Uzsi277?q*ǟp?!.uꕯ|_I_wC:Iffi$m4Ap}]1Y|{ B>¸Â ωfuק cBJ"7]\`'!<!_yo0HV?%#qy_gN8 P`!(+[U߽+ q#1K6~2qu0QŇz?l+RYX~Q{^^8J;&;:<\TYfG ?ιMGw >uFyƅ^zz F;4Kγ '"GJ*.l#:L`C_hojE?w/'@/4"F 13%|~/UTX~iY4>΅\۹kٻw/333ult:pײi&.;8)ݽ~+pAP *6bXkԨ?#%XbK%Qb#`BT҅qmwgSvvoqkٙg)7;} 4rk2} J7i&+ʩ&%f%''K{}ݻS^z3Cѵ9 ๗l*8tzo}Yfq6mIΧpy#I D:>1"fpQ z BΤ}ئwm7x\|Glr]|/> !9+-w<fR>vH CE~< sC= 7b"ٞ _G}S{ ǯ=Ϫxry:ZpG:[vQtdŽU9Hdї5A]`}ѣd…|g,_.)uw/~j44!Ǐe ĉׄܬ$D~\9hu֝Po`Yq,oP/a8JҶm(v:a;9Ý>N:E&^m*iſ3;JĈ:- ɡ5'L\FhX,|V 6 YnDDX?q{`eaE]{M}Z'6jޫ6ȭe?P؎T:|U^^m~#L}}Is#}"NC⠧sӜ@a9iF1#;&p^9 ^BWaǽ .:nj?)S[ϧ0Xf 7o&33O:ƌI8\^iQa'%築PU]EUU%Uj(-7ȑ#y{8vyvkv+A!?r* .DOHņ ,: :^/ygVat$e Ik 8q#F4?5*מ@p[ ӷ,5bȷM(dI^^&;eEa"v/;4-W>ޤk'#R㮝B1ȠC; 츉r3ϣ?ĝGoєn?—(F)\Q\ %7|~"d"!|:dޥl8ǵoCn=ypȮ^Oh7 ~bD߱wcO# t>i^DW.WwQ$'&V?lWQQ \ߢv|D t,, nYTR`qˢEG׮]ۺ -λa/_ŋy饗xիW^y% YO-㡓 ι|{pk9ϔ=n'UrZ) >*>@IÉyw*74mcX! p*$f:=uќ7\%G]|ÀX W.eY~e?Lvڐ$O3}ltpwSlж[2@}}ifFmo )9FrҶzPWVI3BDLxqo o0@' Hs_ +.l*Eh ?; ^tC-p臔R]I4Z&޶m_@aaa'Ak:,֮]ۨ,Yyg2e z(wr cǎmp^$ƛ`Wb55TUUQUUEuuX7 Fo`YyD5TWW{O'u &=uȦq*\*9CGͷif {á{{< [f/Tb]-/(+}'k1^l;(wFL7 E9C֝Q H $ԁstr6TЮ` [u@`ʹv mchS>>a_GC>вLxw̴hp| ;y:N|bhC>5La% 7R ;'҄& ƬYxyGؼy3ƍ`won MŽDXj8oE'ߧ&K!'3&+r2K}QLE!^@na{ n,yKӵNz|3T6!eA; }] G'\_i7s~4ZCUU%[Jee%x.ky_]ݎ *++u!^B`%j'{y q~c3P_>8:24^wqy!V@4M7lqޱ-ah`w* J; b6齑=?%m [ٝHG*U\}1!pwϹ?E0&tŠLT~A~BkoͤWksFM,{j]AabŊ|L<'|nݺq饗2e]yû1n;4<zS a'?5lUbO{ZAǒ0 G|-板(әR>J/_'}wv< TPX]9@N|vԗd1Ln͠l ee[غhyy A<8TW֭as)//'3s+H[\{/^l"B !, eꎵyʥ|I e[4(F |1s_Sϻ'@xS$g[#z/PĽb)B"d* u5RGH1QExKvPNQ,'kPe<#M6uwR 0pδW@R5Ap-"7D~,l6T{mXz5[)l?>  K.'`ݺun3?/޻Upqn;Sd jL:`*ϨT~z/?x@l 0WQ]Ɩ)o&{edO'vo2y^\_Pe IDAT娲*DžM|vĽeʼnŜp}4غ͛3ͥ}Q\rWW;~v6dff! SZ:kgQXx:Z;#x!"_ksB('Bl +*Xy9~P};H1W;:io{"ϩb4(WwW_MDV^Dd>U*`ƊCU@i9"R!Bl'L?}߽o%KJ ů=J1C0B%y:n^yNIۉp#VEbj ;lI -ʍFteT(/ʒ%KnS6, &|̚5>SN9vۍ믷Inzb!]:ljpC%E>8V9{Ob;j tSNLFN^E[xT:\tb{NnNцLlp]. 'Z"8qgWoٲ ϣ]L!3 ?1~r.]Ʋ~Xrmbۆ-&*"0Ŗel\J-Mr3>vS&i[Xq{,T  Zv[:q58%}>~dI`TĨsN|\Mr쒒jeշ@@C&'#NC-iz>Vsů/95~Z><[s5 @"j$ }F|MWBƅ"=Nb=+dA F?1w0r{~K[k\6ysɺm6]  gΜ9L6GyR.B.zEn+7nO=Tă]Q%jS8A<9*;}UP`ru aƜӇЫ)=J3 y$,DȾ᎟8Mqg QhUgM/WB!"&2ǡ}{rFXV˲mF~v;W;I ]O>-ٺq#YYjBƞэN%/5DdVg9 :!Mg]tQ"+繁)M0}qo L:׹@^>WmV৶\Xj´L7{"*lB8aW!W:mH8򞘷Tůu0ާJ~N6*'5HgYh7U0N"@96eabC 4812CvLlwJOk>5,u%  줬^ +Wdٲew}tܙ+_~C]`ĉ{챼Kիk 7Os x#pQ}Q l^^vʛ gOg}]>&}`z]| &0FCkrß]y|TjWn=gxu7Bj? -X`UdUtՎ8aBV3S ?tP$OJ+CsSIҫ^äC}?PD GMtZG1Q6q LBD[Wz/Uж$ ;=_+6mĺl;ucǎ߯Eǎ/㫯^`\xᅼz衍*oC;wyתTG!pe:RĕS*Sv[q$d0}HQ_{~Omp-G_g*;2z}(2`2\@?u<˲bTUUQVVƺu%a@ee5[ 6RVVFEEBgdO,fuؼ5݀(ҝ^I^bDdʃDMBk61M˔;AG|:I]Ao{]N$3~>{'Y{>ӟ*4eWFB1Zc&UP68&21о՞3|G'[$BSV~1 WW BTϏ(j_ *}ݽQ 3BfG]w~̙3>|xZ7D|A](=E|W߿Evn}]͛o͌3883۶فh׮cǎeڵ-\s۞w]IK9ȾdTO\qY>JfQ^ @|o|O; Qv_РMaTp Uh /GnT_ǩb+7n`dggc&x*ٲe zl=55K̆k: !J(A>չ(,yvsp{4'ԒDBkP7D}.̨Ғem^|*h6m{򹎾ζ.Q&V"+TE&6X*D8#fA9''ť{O\Yj I>O5@' @=>A04Ž5phǽC<yi.'x"o?3f`̘1.SH32{\Jra Nk8_Av66mq͛S&c1o<>Cy~F7L޽޽{l㬳bر-RVsm[2dhGHRhGi7 %uOQudOTFs'KJ.4ۭNr#$D-[Vp|Mx'֖s:+mh lܸ "Qn]GejPY93Q?†,"B]J(lmnfcoΐ~pu탯Ľ%OuSOp=f7t"9`n9k9*?]'~ `* :do YoQ"cZFԄ{)5l^=C9k5%S ~tZ޼چA4#Bei*m~|ᇌ3~sfڵ,_ܕ[nӱ H 좬G[oڴ5k}tBII CueB>7|G},.RlpΖj,h.|?9 s;_KOO\:~|T柟ƒVP粍$'Rw| w.14P(S>Tkt90 ,&ċ.~UU p4M 6QS& 5vQ܎&Ft DFtuNV+Q﫸xz҉T? ~=?٦E6Ap hR)߻'I{k !3N12FK1'DŽrҺ^H~ڄ{)ӺΝMıR[ȣ"o 3ҜzpGBiF{޼4l;Gf֬Yx-Z&\˄ SVv5w5͘d_aO4O3{l>n݊a_0w\f̘!°aÜ߈]3gr]wpBE]ć~Ȁںz-o:H fzn:~5Oa"? /-w9/Y]:3}A V UO/bS>wV*7c!FLNFGK+Ƕ5ea6b_b+a~{Ծbw YUrrXX8Q% mSO)ж1r)+*`4N;?_8$IYuBuU7Ulܑ"jy'?(~Io4ӰF#щYgQP:ϊL|GN4秎 zxνJ)tbx'DWWo_'> =AMwqcQV8Vr٢q*$~/^̿o}Y%\4h|p!$s}4"Ava1U=>͛G^7nEEEddd`&J)lۦ^zꫯ2oI=ںz;LhO`B"s=G$,N71~VNya,t=@r^kTUwZ3'mO92ΫrrTWLَmlvm.ۈB/fBFƠQ#NFtu6oXQ&$nS#\܁vs!i Q(eqEжrS89{n}J/uT)}-q=9`)Jcznw6\K4-0}ۍ PJcbɪuZ(ƌZw$Kw0{pžI &<=I>4X/:HRTUW]Ÿq8?rMƵA ::az-2339ܹ3YYYa>8dee'̃>[oE=Mc0(|L:;3l |ɤnnyc _+ Fvm{[Dt.֑`O7:?[1=/J5t:{>Kw $6'E K~MI=^\Eg-ֲٳe m爃/ >͙;͛7sgҩS'_Ǽ[=p;;83x3w.zN-yYh/< }/^#Nܵu[5\ l0Vq⼥\@)c?`ߴ_넋wνvՎrRP&a2Cp^áPe(<ʾ~(Ըc:lj[qlmaiˆ 7#PυVж-^uPN7oӽYǙK'ӑn~PZ${^H~o?QO~'mxa'VL6hH%ŬgS30k4{I.~`9#Q )Wjsty_ܻ]O7ў-?׉{ rGi a&C\|A]톽aڷoO8&0gx 6l8駟#$++222r`0tرef̘y2e ƍs媫o߾P][^xR!! 9!ثlμDwCMt)w:_x<_|xUCGh5 aae`b`&2DdfdIVfkM7+~p}v&˖-QQY55 ̀JAd]7܈;e}L;g:^JKMJF}s_{>I{U_,b=kh(FV4,!B\Qz,# ~?0wFD=jG}T)' wub&9:I'U{rB;ΐa{Zyבns^^|TVV%<Ahq֭[G^^n[Wc|NqmvC{0 ۶>}:Xj[laڴigŀcD(((i :DL)ʛVr؝{E>ߟ|hOΙUh<#zq#Rt@ k(;>S^{_cZe{ISonzJ7yLۜ PSz}~CW6K,aM*k Zh7D߲,քa à 2|VX\5kXh8uֵ2ޮ> #Ӕgm}{7߯_כŗM^ǣY_k$Gp35u=A!Zm&k׮,YX,mی?-ZD8)//gҥ@b֮]Ә>]  Žʶ< } mXvc=̳{˃Avgt+^׿_ufݫFjmS{nݘ7ok׮۶9䓩ODz, /--eֽ{g> grmjuݬXUnU^駟j*&LZ@}waݛL &##3IJ,xLjD" w_jD> goZNuHYy}w#z 48B ^,_ wޞf??~^s^׿x93mgUUU,]S~ rt#~AA&?$}}zW^u5X,Zˣk'B WG{l *u} .>c\tED<,]} bh/  4Ycgy}_ktAh)5u |uDG9ᇼ1e r `k֬adffrI'qИ1Nup?U!  4YcgxOoTJ{#7t3eeC0Q{I$ۅmL)le4??o8?FcƌffΜ9,_+V[0jCohDVX}AaGd;s[O7q{Yre$Q튒V#ݽLݺu:=MO=#6Uڍ  ŽJSv>\k8Js( $-~7 IDAT^6d`::o}~:,PƖ7 eQPXPr  ŽJv>f:8viiAv5Zh!8Zt,`g>F#m,AAvPL3 g)0Uq|ŗm]r/}AaG)2˷Yv-YAaA~AA@)ŶAAAPnI,   Bb6'AAA$8    |AAAa   .|AAAAؙqE   .@(4MPmE)JZR}  ; !Hp2xpiMRcOP4L @)Zc7♡"]A)O8˩b; G"~k}Nnnۨ2IX|99 .8ƌiQСM ۓܧ>w{a UCɫkjx衇y|wD" 2.?yh}}]4i]{"bUV1x}[݇3Y6o i }ƢAAxO+|'=s s}9Z^N4%++jP˲hOYYzwW\y%hzIyy9_tϽtAMSMKҶK ۓ&ާ2]>f)>7w_55Q=zޓ>4;UUU̞=ǟ qxЊul\p]{SO?ͷ.%//8g/z߽. /_zիWӥK.8|~񋓷4B1IM~^J_(~|N'Ĩjm~0m>K.SNx\xYk>{[SO=ͪի)))K.o: BKaTAWt҅}2x`k/w zAо}w=ӇqLy~{*c>%]0p_uXȤG>XP ~̳e~(T!Cy瓾^IaWeڒ%yV@ϤI(**o߾D"ڵkǡʿܷK_z[9_a y饗9gc\҅>}‹.fƍnמ}NvUUCi_;8,zK]؃yefE<oegr[yx$?ͮ˶YM~E3?o7)>_ᇙΝ˟x[nٳ>ɿu v>wq;>3?j: BKRKm~aVZŢŋ` .oa|p!?[ŋN:hѢzyꪫp,v :?8>SûSbӆgz_-? nͮۿyc?m1A4^rZ~ʅ?+^2̉._/kp>_||I&N=>yqĉ,v 1m\{ >|ST)o2|0 ,c|>3V.W_}m~s_/D}A*Sql+N<kTO1l ϧ~o#FÈ#xɺۅ߰߅KzFL2kt]_QekS~?q;C !+3Ɲw/Rg7t#Ç #;;no~ I7N>D{s=Q/];n!C_m~nneWߤlޜ>k?8C&>,is 7l5J9Y]:3x {!3GsǰƉy|BN>T9Ekaи>>x BC8mj|w|N:R\ʶla=p5w}s/e˓~ 0f̘zٻO>52o."y/ŽH6"q nyIS蛜Mo5+VnO>ԉ2M3i}7Rq\u5YV^͂#8j_>1Ç?sNMnh%kRSP~}tg0LP (mPYYɇCQQG Ž[,D/sN 0 Xj| 6nD)EN-cGN;ǻpM7pegee5XHּtAh܋~{*+We?fǀ&c><=}GW˒֩%[,W^,Ym_|ɥkOt6׬vH'Mè^ /^xE;XP&xm2S2b(&Mz^LA^={vҼٳfk=6-l_r ︋<ŇO55q6"%U-4`$w=k6}4" mA5?C]˗w<s1{qp 4f /E ؤ=֬]߿fO>Ix;vdQG3j"޿B<=ƌn9G~ɓ_報QP鮽x/ʫK׮w15ngEtܙkwMRCpUWrVXA׮]nµ;o++WbYe76Xa{Ҕo͚YZq;_48v] $}̣z)o??g@$aذ䢋=+o+. \;{uN=[n=]ʿ {|rQ٧ݜE?MDru%khN=N=Inh~Wcڼ/qt.^ܨhEIuAkFL_43f>9_Klٔ;s&G?ɢx ,Y }w\z H mowl`o*a‚ M3?j}o}Q,^8&+k-S1 :ڞfϦw=رCKV}ƻ;p awߟ*.imY"\yi2ſr5XpY~#}\^*\=Iۺ羻9vMb64X O' v<6{EmϢo#l2cX<4)**?eHFFEsٞa/i3SF9ޭ(+Vҽ{7ll}n.᳍ٳW/znk;p_dBp;H}ӽw50 ӷA'E?˦< wN}۶kr/#NpӖag)#;?孷9?ʝ駟ѧOo:v?T_Cǝ͡njݷ{hrApݜFBiʷlj* ??ߏiB;r\F rdo6J O>}ݶ5Px<}vPdffqiXuUA]GkE_ژ/  Ç k  윸Id%AA;*Q({b{[kT@E#`]h( 6c/hl`Q,u9ܑ̝{̾~B/? !=B!B!D7{B!B$ !B!4B!B S_Ub3%U_e !"!ךB%jgJX*vTR7.{ \p^Ѓ}uNK(AӦz[OU^[c!bJ2Yv{3U֍ '{"יBzK&ޛ7o8},5k?u o$}(\Po/_Ⱦ}~Ze*kÇ0ŋ3ˋE;/~(B!H~biP)$=@Zg5 <(|Ch۱v5iڼ%V$22R<8>#FnFT^owc8k@M:3/_jes;7J5[M [LiؒU]9ԤnïXٷmA-'kּ .j5u4'3[FR1ט֝;T˗.dRtE*U*Χcݹ}%˖j-[l)wnߌw=}]_ %eJanڌsVT@-ٶcgMiSشek^f a|뵼͛ӧQTIɑ#eŚrJf:wΡ&4ufme Oh~bN:įubB!6CQM!{͚6ᣇ\~]3ڵ<~&M;KB#\AA&PZ5xc@Ν?Qښyj:|V3;ŒSYzsƖT.+W2aX9MQTY~q,[Ώӧx=v,{ oHJꅒ2J=~V^͌S鴩,^'-{?,]8z,YÇϣ\8 u0>Z޳׏~}$YN9?2l`9ʕ>{6wBYRg+B0CQ755eAZr&~^ӦRގ,YPhfL;4eܴ 9s<~>ފo'j 9ggԈ ,_7IpNl٨P7Iz[R~E5ɖ-3i8Ybj\]&j׬ĉ 'O!LLL8z49vNN:e4ll *[R啜]}b?-4)1t1?=9?b{zzs@F{EN[dIԪYKKKjլۤgPLk^p0%KOw-_Iiؠ>ٲeh"̞c3hJ+B߿$hM4f1џE[lp D0ߵX㻎!`b|o#"\<ĥA\W. M1Ff )#jӖu7(^Nbزi#ϝDTJ_rƦ$WTlj_YX .3.]9{6P]N 296]Gc(-t=}SR/QRA?05v'-bEr$7"Ks B!ʤw M˥W| 62*V$UlYqj IDAT|l;K.S П֘q%u˔. {i+gLIRl2 nl>Yd\r,y vUɗ/ʕeUJo1*ޗ$iYZ4 %eoeJl%8s6nҥJj~733!B7krepΝϟkͻzZuB!D6Nt&&&lmo=Ch1w˗DDDx$ ה8dO۷o9@bE//^lݻw\r3Oק7flP bl#glIRb@>3gy-Na֜nPɑ[Qn]խۨ[I>2OLuX1JJ&T IIPRFIO{`ӫ3g3Z2[NjN^ޮ^=ziܺu?0hkJw8ro߾%8>&kqtbOsyBDD'Of[Kj]gJO!B(c/ w)TV-aɲe̘9 JEժU4L]Xr%.^"[֬88Tk?N4|/*}{bfby)]x4[[zt|-\Jԫ[:ٝ'Obkkàlur{|խ@u˛:zϘRJΏ>>J (,ժUO>˗.R*}1:X:ŠoԤ^()'׀}1bS n:ySClmm

?Ge"zѶ}GބQTI I.n/}w)>B8CQ7{R=FAU0E?G)ޱ-Rw\*QMޗb(>ȵ,Bcc/4'N?}u]߷E L#m|ֱ':?}.oH_ZB!1OS5yƱvmOCv5cO!B!~t=PWf^|!B!"#ĔӜ,=D !B!"}iCfoW5rM a\B!A&u]{L0Br0I]B! B!B!2IB!B!D|/=B!B!D)"gS?FzZB!B_!B!$J !B!"]2!z҃/B!Bd _:Bp)Ep.yZGľh^XeuZG"?x@xx8!VN…$1<(C1E|$R-g4y&~=u_=}E ~,Y-Awa?x@…*OUv|<$U 4Z_!uY8aɌٳuJcX<=Q8a|Ӹ j [;o3<6ij<;mM4Oz;>_ra|CԘ|jKB炟c$6-:HEyg^OaK8_PT*Î r&#|yI%DB!DʛTabbbKb<-Cec\%O$Om"}QZbB!0 jp "o_$]$/80>)j B!جY8~8wVNͩ_>&MJdKSW.OzRuzˣ6`%fiiIxxx[(s$.=B!RM|CÙ7o*>>>DDDzN:EJo!k֬-Z1cϊU4CMhirc2fjJdiiTHP~<}ʈ)[,ylٲ 6OS1L1*+wnjԨ]^>'v͗/+Ubܸq<L }G&Ox@7ɣ뻆Eq9y<]9eϑCu}2%3UocM{A^=W;2Z4BTpMڴi5T^7jTRdΜ2eʰ|r ͣH"jߵk:tHVΎ;sdʨ,˗/L2dΜRJv8eb۲e~5kFٱfΔޘSti~1:DێzdيDFFjg1mЈkоS,OG>b.06jU2[n 0P:jSTԩLJEȔɜ…0m4N>< {7n+SB,,,PK~^ oCY H9ʑ3WSj3gt2LJ`IoЭ{+mtڍP7oѥKWJ,E>ԭW͛hƘoU~k*Tu$<ȤIIҮPQH_!H:u^z\v7oްtRO}1}t֬YYr%f͊]vJҼ̙38::Y`XXXPdI:uqîSNJkdժU<իW,Y2gW_}rΝLU!Aγp&x+-lP}}5e0ժg DmbÏY`''ӓ#%N+O͙>}:{1m4Zl<k;q 9_)9s^xO8::r)ۛ۶Ż}~=I&rMvNc>2oJyB nܸAǎɓ'5kd˖-fb…4h `ڴiShDclll}w?5j+O-Xt)}->Lk]hQ1k,4ioA߾}S)={Ct)3Mr-ZӦһ_`6!gΜ|U2 | "҉J]vǙ?&]Vi;*UE3Ύ]vI˵o׎AӜ9/^w2i ?Q>yWbsӝ.k;O8lmm)Ͳ̙-pssI֭[nݚ9s`ooϺk7gϦI/%KyD||}}9sLjժEϞ=Y/ |!" 6 {{{ڵk7j_tziH|I+71ϒ% =zښcj5co8}yׯ_زe 6mwy'NLp}c{||رz]uE~`ٵs'uDboWڎoeQr?ӓQF9sfU4]awwwr/Ν;wpus//eeP]aiӦCNy!Ee9_ =|Vqs|~h_ȓ6 Ub>pMƏ3g> y:l… {<˗-y.CГu6\kʕeԩ[sce ̙32 _y!J*zWրM<*uyʆ'YDn&?Oy([ TGl88TsLOdd$ ,<ٍ6m?~~~1nX g?YfMѐp ?7ș#''qOS!HTB*QCrܹW_qQZj)$)S&"##133spp ٳg f͚_S|{+WlB6oɖ-[7T\E ѩk7zv%*V:uLʖ\ٲt-f]|OduDDD[Pi8:1< !""N3- 66 4^~NuInݺEp+% բEsFŵkWy.k׮2r(Zh|xݻw3v,=b!#=L_lٲq~p牽sUƎGKR%Y~=o߆su;w̡CRDx3~8& {۷6|X΃LIO^x{{ݤ|!"13grIgN߬Y3&OL޽(V 1|2>seȐ!Z]v;ׯSSO!C>}f+Vdҥ4o\k׮qԩWjҤI׏{QH<<l޼kt"cInp =), fJϗGK_!qʕ J *P5.?dOWj%ΎϗG%u(>6IcB7i(ƖW7ZmjSc{B㣤iԜ|!BOҿ!4 ؗ2)Ze/R5O޼yȑ#'ENLz;>_ra|ԡ8>_!Гn>T,MsQ/^<#hIwy{< ` ʾR!B!Ot^nB!B!2 |B!B!K !B!4B!B @/Bua`vU\ᄆ0oEv)\(r:Va’Gd<(C`b܃/BP=:0Ț-;5j90x}$[~FIҥٻwVF*hׯ_LJAaooɓ')UwdɒM'O J&_hH(+PT*9<'#':-!"x1666xzz2i$VX-[?>jJk|?~///͛ٳ+V ++$+;FvPմmۖ6m`mmMHH֜? 40o\?\KII㣴EJ҃/BJ//^$W\hт5kr1/5kƥK(X o4jԈ={|aFիiժ___̟??ڵcxyyaff3n8ƏO˖-5󂃃hذ!XXX0b (@)Z(ΝXbT\ Yp!Fb޽'Z2\Hkɓ8ɓ8G~\3yŅ\r?~e˗ym۶ҥK=Zk̙3m2c jժԩSpfx}Bn߾ TT nݺEpqqtҔ+W???)]f^J6\2'q'qciiIxxxB0w\ٲe mڴnݺ7.k>TQB3)[,Æ cΜ9lڴٳGYW^ܸq}0tPy5666@T_~SD f͚ڵk޽{{gggp8;;h"?f͚aÆ8тpssM64k,+;t۷'_|XZZR\9\]]yU넄0h )B,Y(R$$$Dܖ-[X"TXm>),, J*+Wfƍ:+Zyq:իWRu2)U*޼a;+U"O<888yӦ4ˣ)5DRJfyq\Xhsf̛… yn&SP|{/BՀ޽;Vqƴk׎/_Q uKKKrȡS2775kVVZŐ!CXbN*cnn7o^W3*U~YknܸOoɉ= FVp/_d߾} ҥ &&&=zׯ_k>ҥ̉' QR_B!w9UF\gĈtEsWOϞ=;={d4k KKK6lȡCOӧOe˖ >z0_r(Y>|VZ,7o+BCC4h}aΝ8:_.JE kݺ5nnn{J6m4eN8-[rqnd_Jc~޽;o3rd|+@eomMUݧ7.fy6o€Rè)yXd_70{l@VqIΝJ̨*<Ȅ jyzŀ+|"666L6Uk>>,ZwnxBf͚5ez郣#gN`|ٺmfsQ!ξkլٳg ~dJ~UB!RE~ڵ+!!!XYYiwQBCCp4lؐZ=ytܙgϞQvmp-[u~5Ξ=KtޞKV.^H"E|+BLǏ'o޼\|.]Dܹ?~Nd˖-lڴ/^}v>NRCPzxR3gye}§+Ά ]63gʊ:hBO&yT*;wwܾ H++BC*ܗħF ܹx}})P ׌)W,-o3mTfZwJyBBbff[7Βvg88TsLOdd$ *{蟣<ٍ6m?~~~1nX  @x!%JG)P@H ?7Qߌ3GN&N!k>4г/_u!ZΓ'mG'k4Hߓ9s[XXęVA_޽[k$ݻN:qzbd_Jc*aO<3Ϻ@>y|/V'>KBJz?O5Tijd}t:zsA~7ѭ{wVJFgCsαaz,--8y2Rb;~"Mh~8NT(_ +|àjgG`I+T!dر= P|LA0!D}!2iӆG[8qݺucZbk۶-}ʕ+{+WЧO[53gw^^~޽{9sV̘1 80vb~})َAaU:Wҋp[ݺwرK2|pF &y ȸqv*EpUFE6ߧI<,y޽È#Yl)+Wb5{4OR%Y~=o߆sᇨ1걋  {C@1\9bL.9tȟ0pAJxM7f]qk.4ilsN^x{{'Dz3/D ײЗ0eN֖:)ҥK3f oߦTR,_ZjiԨQaÆѥK] ݺu]})َ!U*Ԫe]0yz쉗7AA簴lٲ4{6|LSJ͠Ay ]63&MCJDDDлwF NjPTTV 7WWˮ;}FIjfG:d0nݵʍ>1c2~X5l)ӯO__@PP8֮͊4[4on޼IO߸r-Νc;g"qJP|2>>,_۷oRP n'p7o|UO>/|8p>}S&MW_}ŦM6m...Y |r~wUiIXzSIb_G'Ç aC5eZM&>D+DƠk_zF޿S|uSϩSȕ+ƍ ^l?Py!J{Ojr(؍II!㣤i/=B 1Znpɓ={Yb 6mʫWȕ+ 44k먯&$$wrz聭- .9$T^cVQ jSc.y.#y/c<(C4NOt m!2}]jo߲xbzgy=y+={ʊOwӧ|Ѽys={Ƽyׯ_IFɀOhO<_vo)=B/DƠkyѸ={vLMMy}2^>G޸qc|||2e >>>4n@]>Pyz[uر˝;7?F&R>aSSS>~$OܒG}a|ԡH_=!Bd T_J*lܸjlG?1}Ŋ={QX1V\ ٳ޽; VZlذOOOzMN(Z(n'"dΑC߰aZG1*a#9s T2ffAJ⅋̑SH#:[x|'jXczͿӵGI)D_=擷ϝW)!DbײrYbח?x@Xx8!Le[2 &ZݻT͓'OnrIE$1<(CTjτDB "ckYD…~(W.md0ŋOZ$O$O[a>ez&CZB!>3y\B!0q!2+D ײB!M}_aBd r- !>}; !B!L׮])\0jժxL«/|V cѢE̙=;UDeïר/~UNZX.#X}!B=SV7_iM@yzwbu)$o_ Uz\jg3utgѢE9wnAge;ZbǎԪU%KJ}NLvcێ"!Q |GD!Bo*5dLWJU;波JU;|}&͛ҥ+%J"U~֫[k7*5*Vb_4rŢ?S|rʭskjgO|V|U*7 G\IkW+x¹.ݻSNcymƷ|Kٰ֬.\/vޝfyG](X3L.\):y*M,]333ڵ@dKYQٳ[Np5eFabbիsf[J56oɶ;g1mЈkоS틳->mE+6mٚ`z7zm;vΡ&MdيDFF/p߀wkN ޻q׀Nu9f,/^LVf];JB!%XkN~;q-̟9sػwO"=}pttS<7[m,ǘѣ4i"od;{/? LJE pm/ZȬY8x j/sͤqMHB\Eȏ{ ɓ'X[HGOɷЪEs>x?jssD d˖5p8Vi ƹir̉9_Uoru2Z5kbiiI5q4k۰yRfLJ5{;dBѢE1m*[AZ=m vuVQ?oZ5k‚ٳ3j,}yȞB!S_v891rݿ_?4lH-Y& 6@/^nݺf+]t1]Nq2%+Y'5=Yl/_d:y7o2WW.YbUkB!L!vb9ni͍q2d`f͚d6sLq)9]I*5Yd {ύnjL(_?/^DڎOL2?~Bky@qʖ-6*СCYjs4*Vѣ?yOT|y2eW~495הyc#;v_"K={sst'=vvL<_3:u/>}Fc p&(HkgRtiyʖo^捿d2ͲR%Kplm.U2lsZ^~Е*V_x,׊;w}.ZR П֘qҥ$srO(B!ҏ<+CJ@1p W77F t! {)YW|?n}op-^7ŅZG)T&2n]Ij iZ9|׬~2[ջ'Npp)B|%wJٳ[jϞݒ =y3=gsY޾}˩g5g,8dO۷o9@bE5ٳ9u6o:Ni.OCBLtu*ckcÉ@b:}.^|IDD'O2xC*UPլ[A{ŊiV޽{+W:$sr#/Bgj ! ̹)O>eر;pK~w ~o-]ho7߭Y:YT}'$$hunWG.]|YtH;uTB#qbC+ٮ!ORgZǕΟ81!55EIIjveٮ!O3`HGK֮ <@UOa t>=yFdȈtqPeee*9S(1!qߦ-,v%y)bkS3<;(,ԿԭtkN}_X[~ە<䉧<=]C8$4}6(+-Sߜ2M'KKί,jڕ<䉧<,Tw UeVQIINFNjLԾ"Ю!O\0=*\JXAz ]纖t=X>̆]y<=Aw]i^~}qf4Q6Jn<ÇWNN&MybŦM4i$EP,-t9lM\._ܹs I&2dlRY&Bٮ?@ݻwWjjw 6D4O4O.>}"~Ւ%Kt,׳ynذ:wf \#OUVҥsvs FlfʔiY W\!m۶ZzZn~Iށ32wڮ;nVxC{}SOi egg=-ls⏾axB>[a ni۶w͛7w7YB~}7z~:m}T'ԳGvDUcokTtr`YteԮ]{%&RRR֮][YNv?ܢ>}s8]:wѼy՟+/(~Hlf[hĈ̙hw)AJHʹDqՀtmIrssmSt 4tQgp˖j.Vԩ\6l({k;N%7H.~ݯ}=駴j}g=(f[WVZtuwjulU~Q.]հQ:w骕+߾!X\C\zE^;nl<3ݷWfҫ-^TY>'x\_#մiS|inݪ?ڦΆj|;p׺{#'Ǯhڵk~y~ٳ⋨i=_3^9I҅*e_kcGծOvY^ɓ'W6M?^SrڵhڴiݧW=sfVfCr\.֎JJO* ۗIImsg#45hhSNEMի*((5d@*㯼ܹ$nz5{z]Yfה\"efޡ˗Wͽne7orrIrr)//O -Z>5>>e9zmkGe^gо{URKHHM6!;&ϼՕjY`3Ͳ;ْrss=N_KT-ce:t9Q#;wrÇ~_O^e飱c#\jZ_bvfdzwnQЗ̘gUvvΙƍ\[u j%䘮gRZS;*ם>}J閏\K. aZ]tі-[?pƏ&r8_xu fkvv}׺m}mc A_A<@q:M۷_ݻu<7TwSSSU\|kݡCKLL?_ +swݥ]vW6۶mO?=]vAR1x:v ~j~0A|^ .hǎzᇽFܯ49WџΝ;R}N1̝w֚5ktr~yP'{u&eet⾞|q-\Pwlŋ?jZpFz2"y.#‘j;g(g2dp1M6mڤU笚~=h:uJ{.3k͛kΝ*/f+s}n$M>M^ұcG51yn?gԩڳgJK/iϞݚ:mcVr|Y||NL9kתuղח?>NuQVz'tW+o_@S#}095t)pgfu6Ij9͛hႚψA^vvѐg6N3bHՇ]yt<7+ X|afiʬ#oQ]SM] \WAr (ng&O^EAȐ!b|bYŤ|:W|b|FtUWfu$rq)ֵKrq)$4"Ԉ/@qyq5E?)@zFttttp `V)?2%Ut_@,٣ C'Ja:%Ӕ.^8Ӕwҹ JyN|mH;+ zD%iMT1E?b>>/ÔD'hoZ}C7Mq>ߴ|׆$G=`oZkӨ/b>eeZ&r&aVW\شSeN5/+򽞢/WY=C%4ʘ@,**sjC= $r~Z3 |\X+o5>šfJ|2S.;Ux٩z ߟmHzOo”}Uz?ӫO`/lIENDB`mathgl-2.4.4/website/udav/udav_light.png0000644000175000017500000014013013513030041020401 0ustar alastairalastairPNG  IHDRu3AsBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwx] 7Rk ` zUIM/EP @Ԁ@iv?;sry1;3qٹٙPʇߞ ҫtc'`T_;+rrdrGHDDDDDOlPP(Gzz:30PX2`#@Ѳ@!_"ÕL;?LW 2vȵh(BEAg """"2ʼ' e|Ԓ磅=#6[HqA^_;P(\HdVedggAT( H!"""JU5lAnno,΁"!II P(l!0QPP,4hrD(HJLĭC`eeeTDDD?o/,2Ikridr6A H$9 >Tq ֹ5 ΐ:B@bЎ#-=m۵ yX4ήhYϞ#:XDD릴:wA`mm GGGԯ_}zF4c 1d8::&O­۷lR7mZ&1cL4_VWx_ 8r( 憕aFWo4yOʲZB! Eq AqI.dV`m۰~!!Hk;#H$9\.GRr4(99C~~<@-3jQ}6] _..Ony aooB>rDn!?Cc/Zc-oƌy/|p!\\\LR>QU4!>#G G-0ላ-=ieԢKG-Bΐڨ B*ML+L #w mG١|h Q} W7H3mA~>m䂌L8HDTU݈AP۾B.DNv</<*(8x A+1p! |UnݺG{#G⩧Rıc`kk]0?qGDD:oؘېˍsG-kwƍhuovzt=%.#T@[)Axww7 !x:"y/\vĭ[ "6hhݺ}#'{̌tt IJe+ef, +']]e_LV @"`޼JEU .[P$aVV8|D!Cm̅]XY*2dH|;P(^^D~~OnvxAJ#(B"z\ߏň#ҥˈCΝѴqct˗ y!qQGA~~>y yIb+j;7mɓXq̞3R "NaXɧ8|0ܼ}G;5lj+)ET'}7Э{$'ė랴tiiQBAA>nێ̌ ]_M_}zŝo ˗#1ϸu&>?_dNZ E+CM=*_|Ꮠ} [ڸO}}(!Et5cd2ֲE|eo\z9jra[V2c߉L7 11QmyBBGoy|MApxMRݘ?sJ8DDD@*Wnt@Q}accJӼEQ/?V=^\+8) sG{l1%Ɣ({)m})O^5S-cɧP1{RMemزe+"--e>O"A\,˜c+\qY|s'$R).]G'HR!m8~\KajWPP[oc8{,=z.^nЩSgK+=zD~~>.\||9XIn,]Xt)}k1kLt3O{k@hL=kX*ܾu >Dnn.z)8# ֮3g'''iC wWgk[崲Rk,_ Ξ\.Gzu1NyL=DDDDDT$  dA p 9DDDDDT """"JU43WIP4n=DDDDDTdj{ģG)* ??_KBDDDOR +kJ$(8ui??KDDDDUX|WDd 33$AQSOV-dffݡaQEH$[:"""zё(٦HAD ۷QJQBa騨  #"""ёjp2&&d2o[oj璈Uco%233 !U1QU瑈 |bS*҇u㔹d6}z`3U4eBdhr\f@fcWU:f>^EDDDR5٦@Չ\4mJDDDdn2rP({'DGG#''hۦ KU٦eO iK8-de4m죹Tո1@r#r?)8v/^E^aN4BWёEW[Bmb-i|ֽ'<ŝ[7q ϘxH_GgN:ٿ{+CC租TOB.ŠKq-BO? 1#G`wk;Cq(9 OO 3(`o;' >ݴI{uOe;Gņ/%q_X0_|QhGWWeKХKۣK.XlZ ֽE#mOu6 G''XY[M6VKbر#lk35otnG2C78CDDDdFޥpN 7nlPkbilmQ駱havޣnŲ <<<0g,4sfûN?akkڵkcJp""N{ݻ%8:8 -Z5<m܈CaggcyF_\~J4.YfjݐbPGB=Q!wq7n -JYѪUK̟7nnn(,,Dt4u{D8G`E7nFnTLaˣ_IcQ0a">` 73-履,ԩY|0zBCPA#lGÖMT{tm[w@Рaca:q%c6 ~C9e.U-C3$`+W!0F(,,Ķ`޽u @ 6gΞڵpeV-[bS^Wzyyʹv:Λ7,T{L Rǎ6nĥ˗agga58C%K!>>r\׸d;w/DbR|1t;X|\68~CɬxWdgbIl HֵI%""PƘAUυ1{\WmFLJca򤉨W])x71qJ^UeFP"FpǶw;{U gѣx*uf.3ݻc1 ???;l(>`Lm2qiǕ*NAUCΝ0eTo&;aoc-8QctP0h@ 8aQ Q( UQ4JuHDDD+qPO& '>GDDDDō 77|Q$fF{:?~G$ ޤR)DQ@<<=q"w x㭷ʕjA@DT{]ʝ³W)|DDD5DRG% sL>K@DDDDD[QOK)PeOU* """""/fOUF:8̡!=DDDDDdZt9c:+w IDATw/K@5+jg̵9w/$'%V5kAbWU0?޽XXS`'>wVf剳2O Xj:~F7 uxa2fΜزy"#K9OTuaupN lllЦuk3{h+}-^|̘>Nf׿' ̐e/@rr2Ο?7;}VX[[<ؼiի 80U*[d1^~ ?oQQQu^ FGlbto:ڴiZ~9/8q̂ёiGuÆ/[f,)??^{ 63 ''Ν6nd*]Q^^݋ 0z.QVa1Vƀw |~|݋˗qF+^}u~G=TuF7 < aĈ3A<>v;",l% ˽666زy,]+W._e˗cZ]^غkt >~h׾#vY&֭_}@x}@l۶]m;w0|H<4>~xO?{ R) JQ{Nqu7ѹSg4]:wAt z=ig`]HLL)x{30䝡=kA7օ+99& mp(>Loذi'Nɞ8q͚5K+:v젶cǎe}wss+&rbU=W^E J쌷z /?949Xg'A8r?w!¥#!> $&<0x?/Dq{9R2 1o\ԫWBnݱaf6i7lPaÆm UOvv6>p,-] ???n_>n{b۷ض걶B&2,]\MyfΜEc]HIMEvv6GDSǂ?F⛂Mb99=xj98yysCIǏŜ9syR-ͤTi<GCvv6è_rYB3sl=w7:/C2vHLLDPܸ<~Jgy-D@+n܈Ɣ+/o =g.N>l>}5z a=QEqlr ݋^{#1h@~6u*6mڌiӧ#77пL >´3\ CP|7Nkӽ[7|e X3gAP]*Ϙ9 4h7xϝnj2LcI'brP0߿oooL6 zR嗑)>|}}1%8XmQcp?7ѹS'lrYBuغky"]c>T/666=Xf-F޽ kkkcƌV3伖dlzJ&7:SN1޽_D||<ƍD1ɧ3Crbo(}]! 2v*2 X$"zR=w'd KBF(Uܓx`ٻųWUtQ2n\cڴ2dT-(2 ADDDDXs.|1lPGf(aT~||X$" QնUDDDDDTADDDDDi*6:RADDDDD"""""TE*aAQWĄDKBήh3BǺ@JԅԴT$. yxy:ZTz-2F:-jzY1o\Ǒ@!*0{KDD՟(*|4-OKM껣RS +V@gqr9OJw/X|9Vĝ۷*|%,]UΩӧ˗!mN:U՘m8pԔG?tR[1wncp U;&KKMÇcqZ^A:u:yʿKCdn2<W%%%Sm'̰u֭[ŋ[nݺbѢXf-Juh޼9_!}.]Y$f""J^zyi)Ew|hZahPB.DNTiWYKkעv%K`e*r/^իWuVzU1`km/Z>Z;4, K/FN;wŋ1l0+U[[`ܹԹZC΅!ٲe Ν;q]ǎjXÞ2emrW%'%}7oFsHK.*u PǫRZf6!5 P[ꊔղhtI-MΝ1i$eʹz*zo(B"hm7lP~_~ji:wvL ߱7>N:R%iK6b$$&"66Vm V:DTH^xgTQ6<=i&=9ېyy͚;\L\tS2fVV2=ez140ڵE \_?@(EϜ1sEzF:fΘ,9Ȝ/4]tvpj۷7WZ5jNR[vI4nBQM.ss@Rb{Rb"= ʫiY5ɓGFDƍ*e˖ؿQ+풟Me16ۺp& ΝWK쌤d޽z"4tyxG+/dO)jȉIT(4N ⴾ.A< A\ӶK})Sp~|}}4/Z^}t[6mĊ0̚5 m۶AZVtJzDpdL4 I1c,+wXh(LBBqc?yUi|>^^Ͽt4iA'a h<̘9qqqjΔD,h*3U~:Xb 9>#׺^[\7(B{(k\_҃k*aÆbذe0~.My]1x`eC5* 9r*V /S5ٷo_W~AdFVF..7F!""zRhE\=+ރL"t%^e(ԺmkK@DDT_}.gO?T)V2DtUw(B,5нi(a= EskQ=DzEf$wB<ʾ|/]ufa] %]rerD HPX(,:EW윝]qQtҡP%;vΉ XjRW\]]qe4k R^E5BW5 E5k)aYMq-* ? *'\\\Կ4 5)Rh+.ܹxnhLk^jCE1``] %Rj޲C"25Qb*DDDDDdz"T/4Aǎ*̵QHKKtt՘']{::օu iHb] 򄋳 u㵨3Zd*ltXH()xҡP%r2E]zg]9XHɐA92 "õ(ZTsR{:DR-A=󏻵g]9XHI_]HMME 3FE5Eݰo/ZZTsDq3=ʚEf]YXHINJLBI^zlע\盍""*J*/77Bz>BD6:Ο=T899mi EFRNvQeղSI6:T'7--/ϨI i)+V Oqֿ8~ ӧOWٻ,[W[XK.Ł*S s6'ODpj̶8CCj#Xt)֭];zU8V}񥥦RST1z~- QWN:XǼrߥtM!2x9{[/Bn]ݺuŢE zZ[nмysEB>]tHDDT%R=omд|Æ hѢV-;,\N:Ү^K.E׮Eu K,Uݻ,^WFV=իVc ^p!}whX,^Nܹ /^aÆ_mD?sEΝr. I͖-[p9:vw}WtUFGE͛I. E0 @""J!jJ4״. @m+RRRTˢѹS'4]:wƤIԖ+իݻھD5fCݰaC}uܩ114b8}>zJZӗ-[ڈ#X~~~6lXQeEH?<=i&'\TW4//=Y`˗.ӠٶLOr 'L@vmxBC.OkzP(_с3gLǜ9sp퀙3k-m2Uw5jSO-;y$7nbSe~e{ )1Q=)1nմFSj##OqFӲeKvOӦMq2_m]pADsΫqvvFRRZ˗)L < IDAT&CAAa@&A&!$$Dwz6:\Ǐ9s"2$ysä HL/.1!::yر=g"#O 33'0g\L0ިrfLaHIyL?~ C :ع".8q̙ȓj_m5hP۶mCvv.^iӧٳ'͟ĉ7~Zرc Oh ЛHNfʬc:J6([b Gi2<߇/ "'""2'Q:2/o$<qqej*O/ARRLqApd jyӵKlٴ+0kl( mA'k[m+A1id$$'MČa2u> ƍsWY>xz=ѤqcMq'h,0cLA.;SȌTaHRÇcZk*4Q"W"}| %=/o<[z2J/6l( Z&cwҸOڔwۥ <V[6tP+Zڑ#G8:9aժ2 8Pc}E߾}5) AfUTߪUpqqo1:ѓB[O/bu_).}|Ue,!OԔͭ۶tDDDJ!jrcOF`5 *9!""*EES29m%dFxQ=DzE b׬<ʾ|/]ufa] %]rerD HPX(,:ggW?z{t(TɎ9s"օuWWW\|͚7TZ^EO0B+Mk^j}"S0/܍ĄDKC..hTkօu [4ǕKpY|k}3gÜٳ`W닱M!wQT𿹠B̵;Br3 0̙9pF=\@n (J=dgq=xF$a-(KT@HC.$i4(z'] gZk]k]!7! z{zޞuޞ g:,9sNVZ;w"iKc]v 9mYw>ُ6/p@"D >t_ýy۽f,[;']ɓq[ ];7ݍ h4(-):];wIIkےس=<F߇رhbtv9 B0H#0("_`P06.Rҡ/W;$o R#!q!a*5OoZ[gA!s5~r?ј3Y_f- 6m`6OF#txώY"x,ۇ͛QQ^gPQ^r8$J4=~(`|%"_] 1}WCe _ùoC5|rS{?MPU}()-h= iF\8PYU)޿?>= :;sAb-p*QV^.9'wu];o|pt#Oȑ#uvg.?ozHQq#:Ķmi4m@>})؆x ׿tLDDC_uvt $4Yx $$$ l[e+JKK]ZZ:JJJ ӦMwTWWcU՘9s&r豋6l@TV{WT)T#33Cwu7 "ȵp$;vرcVM2ͳ3#=2?%K[kokQO,$cTDD4 ς("J˺fkFduͦa9s-p)IIZNrnfϞٳgKΝT|NJÁO{LyCBPUUiQ߬Y9c ̘1t%. Vr2DDDw (m4t.uHw"Ѧ:8ApG:&LJ֎/nDQh. N>l~#9 Ac"C4/f[.l ddzTqerD7R˯ue_]txHh >?t(f5}fAl ރmJ ?~~R 8pjZ6"a/rA)nl\,N76ᐛh"5 S!vll@FxnDj8ۏc[șХBPDaa7f>EC}|X)T#||/< Ɇn<--x2r-9KF/"Wo08!z}~x: R=k ]]]xfL`T-~~(}Jbz-x2uZ[!m{싼Rכ""۔(JsϠU,׿Gs8.ʄb⤉nȵDAtu>bN"pA 2rș O>Se>#7ECDDz(Zt  1z`0Af㭌Q{Ųeˠ*\CA}PmmMQQQ3Ocɒ r`7DIDDt{==@oO: DoOi39'WΝ;4eKϥ.r;tnvcpCQ1O?÷4<[B ""c!d`} Z1nղn|w"&Ozm1(v{iH^ȑ#1l05 k/؎ع-L((L]ޖĞ=ǟ6>ĎE˹%DDD@5AqMY֘owux|h4E\!ɷ}HH0 cǟn>އ4#ҍ-r[n?EPpl=oz S8~o؊<  1󦦯LƜ9Ϣ$6k L7G`Piu^|2)H9L@ @ҍS%#"}Py3*t *PV^>\YW׽gB^xDD49˼!!CBt,pk878|B_/_nʳwظi*7oQU%ؿSGaa!6mڈ =C]}**ewǧ>AWgz})؆x ׿tLDDC_uvt $4Yx $$$ l[e+JKK]ZZ:JJJ ӦMwTWWcU՘9s&r豋6l@TV{WT)T#33Cwu7 "ȵp$;v1wL2ͳ3j&>p$ij ,ɓg:UϩS0m4GD@Zqw1;zѣG!"Μ9$IZJr89x"͟T.m5 " ٢GBffBt(|aÆ!?֭HJNU#w Z:<W*ّ>>2 GEÉh˙con=7sx䑉(.ڀpA=J6?:o֧+#?= \\.9HQ7G?a<`̘!&aEDDDN-~inkm:<¡njz:8UObb"Ԃ{8KB;.vI<?oBsApU7s8z(`0c_̹|XH`@mm {bc!""8jkG_P%g򗰡~0zqP ̙c`=p[d1Q[W+̏Cb׮]~݀N|/kqe 8r0eeI jQSSv ev [H9%qc{`^f&wBSOyK܌h,˓,"'""R(V_@gLҢN%u-uDDeEYkɥxr:ڐt)u"/7OL*)kTGUT`ժ' 99e{l22\A69Kb*KGv"Ac"EǙDZ|.[כm-Rƍ>>/nJ-֕}wQzs!*s<#ӡ|-x2T*N64`\8y=4 'Ve/"WCtc#>xZ[Z=&R0ba[l dH[O'pڡ`t4ԩ*Tjč'}wp/rqqnl dĶ@F񉉞"rK-UC\y@.g:ȭ|qř"""""rWqAG4j^ aH BCUgqtl C9]hc[  ,4 cǾhs/:i<_?? OBnvOvl ރmi /gR82kjpQ싼ȕn:Ciz}~x: R=k ]]]xfL`T-~~(} ps8g:<ӕf[.l ddzBx3y7HNDDtEsϠU><᎜8q]N Ik`10N5|SDࠃ<wd^߅'~Ʃ2|!""r=A: P=0  3Vs㨽{bٲetNse !)Ǔk:[_ΞmB{[-⨈nr3 Yǽ1ppÒ3dUعs'Lq4e^nǙtX( 7W੧ """DO2t_ýf|`P0zIӰ,9sNx'=5ỡII [+/KLzmΝoa$DiGa$dxD$y=!v8,Z]έ-!""r(6 kzͲ|wԴt#C /IDBxHH;tK|>ADn?h޲ui,CdykۈOHDJ}V|Y@Pp75}gf⾟܏(m4> IDATyW%Ye`1;8M2Mtۿ/\Ey#"bfTT|*ɷ{Mg೿ X:_xhEbDpH:* eee(\} ׇ˗!6nڄ8[TUnFIi)T=GQXXM6sxoPW_ʪJՙc߿]V9x JKKm\8U(+/{:N7>^xw8sNbȑX:<ټ~kЕbnq[ӡ]FIF{nGm:HOOCQToيӧmпpkHMMHDD4 %<\gGBBLa-7@BB`(ܰɦ[iiޥ+0mt)..Auu5&P]U3g"/7jhDEiewyEJHIIEqq1233o1:d|]w))<\ Gٱc;fuߔ)S0o<+{8ASlMǢ,#,,f[]X>_݄QjJ*r:8jW[2O{#틋U*tvvҚ,ɓlIzN:iӦI(c=>s $yR%~t֬]?\{܂ ڊK.IG[jCD騫_ͲH@Vr)C6ki\mojgGXO7_lm4{Wh4̱ ShG9kbc=Ѓصk_7_%y222fZ\rC/9EYY<?kZԠdm+//Cyy|BrRqp9O=v-Ess34/OHI X}1-2J:ٗԵ\A9-ue'>hkkCҥhn!:Z<1uzRScQVQUVCL3Ȗ챍@^nsrhd/or,]"""k֚˯cOEww7AnN6e-Zk`ʕt\;WoP&BTzM5nV ǂeu;FDDC |/"Ѹk˺fDFiqYl*kZ陙s9"g뙒$Vmn٘={$mܹNg~8d$s=gJf͚e3f`ƌV+pQy?/v ѝBn#J ݥv7](mN"t|^u0qC ""r+A[;[pf@?`'DDDt[Ec.^0:" ~#99A=DvEAh"-_>DCͶ]SpF\7nA_ʾȻ(u9P}9~Pj> k * '0.~{/yAp$jlE^_J7Oicbq-DAX cce-x2r-'8v t\P0:TjT*5ƍþ;8 ӓ 8Ac<&Ȉm=y1Ej@{:('"""""r%(JDDDDDn "t38ADDDDDnAͧWq'4j^ aH BCUgqtl C9]hc[  ,4 cǾhs/,ê\i<_?? OBnvOvl ރmi /gR82kjpQ싼ȕ8 o<)ь |l ރm쵅.<3s&DQP0*i?OG{?Ͼ{\twu ٺm>Ym{싼RDkDDD{gP}*OC5ǿ8˩2!!8i""""r-Q,F~ݩattYSz}||GnQ:0 >b C`0 om0Gݻ˖-Ns+cp9HY?(GDZMookmMnC ==670==tXr本^ ;wDҔ).=ƺ8AU: ""6"DO2t_ýf|`P0zIӰ,9sNx'=5ỡIylu7&MNBv&MN®]oKGDbϞO@}bǎâE"""Gl ^`|A,k̷{HMK:<>4Ͽ"^۾M$$GJرOTGCJjOHDiFÏq9{-["(8DvDH?۷iqNlySxvn&FcΜg~UXc 꿃#0(ش:/D><@AظxhGa# /ԩSynrCͨ(/C3(/CYy9Tose%^] Ξg?Azu'f-]Չ!!wu:TP5>T˗/7ٻClܴ Uqܷ܌R߿ϩz֣6mąޞUV3޿?>= :;sAb-p*QV^.9'wu];o|pt#Oȑ#u6Ϲyy֮+7")'#kBL0sbRHHH >6 99ٔzV"-߻t`seMp=%Ƅ1sLYcm؀(.@Iq1S))(..Fff j(dffR"rWxd;i$?^"__.!""ec-MmZmHY招-vf^4 ơ9avh|?g-^G G__ѣd X?؅+W,G~~{AAXbl]sR!jxx! j=`̘!&aEDDDN-~inkm:<¡njz:8UObb"Ԃ{8KB;.vI<?oBsA *đ#~:'xd/Y,牅YY _: ֡`ElDDDq`!yF֖+Z[ BYх΋.|Aoojk Kg9Uϊ/aCQ:;;`0С̙3Gv`=p[d1Q[W+̏Cb׮]~݀N|/kqe 8r0eeI jQSSv ev I!xb: Yas Ǐ71شq#N}ܭuO=v-Ess34/OHI X}1-2J:ٗԵ\A9-ue'>hkkCҥhn!:Z<1uzRScQVQUVCL3Ȗ챍@^nsrhd/or,]"""k֚˯cOEww7AnN6e-Zk`ʕt\;Wr@RHWg':Vl!ԩ;4 ̟/<$""wDQD6uVtY׌(-.Me[<=3s.23Zl=Swߵ͞=gϖ͝;ש̏}LyCBPUUiQ߬Y9c ̘1t%. |u "wֈ7,Ler3Qh.]뾑ED\?h8AJ~hr34aO@DDV(Kv}X'&̀{/$"""lj1C/\\|l}HVn"""ۊ{:by{DZ|.[כm-Rƍ>>/nJ-֕}wqgDZ{pcBCU8yFC!732`[l dd-T*lhq{|i'NBVa_=E":76.{pM4;6V6ۂw`[ #GB|BnDj8ۏc[șХBPDaa7f>EC}x>~HdCN79_Μpd tccqy{}KgpC.׿tG32{d-x2̙EA[<Pv?"a/r.$W+Ͷ]nkm 6r[/.r6%ҁ=3A/&O9踳~M9q]N Ik`10N5|SD|U)GxsqGt]xg*)"""D`0`0 2oe<7ڻw/-[NT9W r'ӫD l\C\r> -[Y~t]n 7! z{zޞuޞ g:,9sNVZ;w"iKc]v %)ABB]3gΠDDDCӫi=po` zY-k:4,KΜ.^I<*~|nhRV_##Gl~஻!11߿؎ع-L((L]ޖĞ=ǟ6>ĎE˹%DDD@5AqMY֘owux|h4E\!ɷ}HH0 cǟn>އ4#ҍ-r[n?EPpl=oz S8~o؊<  1󦦯LƜ9Ϣ$6k L7G`Piu^|2))6}| D#}ؼeh:{e(+/ǁJmī^A3!VW<^""DQج:b;8$N@YY ׿s~Çj a<{~6r3ΟUQRZ9UOzbӦp7סwuǧ>AWgz})؆x ׿tLDDC_uvt $4Yx $$$ l[e+JKK]ZZ:JJJ ӦMwTWWcU՘9s&r豋6l@TV{WT)T#33Cwu7 "ȵp$;vرcVM2ͳ3!>clGj(dffR"r_@FO~[ToS˅WDD GoE*Wp *@^{Whmj{Z[lȱ s;hG3'kb<Ѓ쳿e/f}}7dϯ\A0>4(0+W,YH /z0X.1cbP^VW_=y;A\ X#jZK3O3f %kkT=طoS s[ll,Zl|/ &~8v$Ohh(%eNJ qK ?/?Z?t2=ۄ8{ 9$'ge-D~~jk`0P[[5^XXѠE֖+h7hBGm dqSX6C/9sḏnK,F~~>jj%8zAڵ ׯՉ<Xv-\ GƢ,IZ-jjjwfONG[[.EsZS%eՓ Z `ğ!7'G`mXFrs+F#'{ V\t|?Wc鲗X(X֔p=^~e{|*pL rs(k:_^+VNC__ڹȗt(3SSmBrX0>̟/_..OKDDC ܇,"Ѹk˺fDFiqYl*kZ陙s9"g뙒$Vmn٘={$mܹNg~8d$s=gJf͚e3f`ƌV+.ootRX g)f:]h}#ݥF$Ly?psq 'x:"""D_: 7>l$ADDDEc.^0:" 僈)]RDM!l]o¶@FwJ7@: r!___ܸZ~+"n Uܬl>Ȁm{-RpO'NBVa_=EęӍ=hmiw!] IDATt8&H T+m;-#m!>!'Oc_jPRR7nlEȕnPXdfl\C-Q|bC /ƾ\ŸtsDDDDDVDDDDDD.?"""""r+:ȭ8 """""zuxDF]| 4TqGǶ0-3mK߅6rH B06n|싆>GA9{:bN">@<0'Ρwɧq'h\OE#F`08TO@@   q޽{l2t:ʹ2Wʘ} A&Oò9ELϣȇ&e4Vw~$v| &'!J; &'a׮%#"g{x'caѢrnm #DA`}MG`PE`\m5۽]C_xWvHm&#LFBx[磏!%5 '$t#~G=Oc"[[F|B"Tj$ߴ8'?CL缩k<;7~Di1gγho*Z,Ӎ1lll"FAƍeZÇ݆Nۇ͛QQ^gPQ^r8$J4=~(`|%"OZ!!CBt,pk878|B_/_nʳwظi*7oQU%ؿSGaa!6mڈ =C]}**~Wg~|ztuvX(--Ŷ[p9TWU\rNŧ:MwxF4:#Gbݫlstg]CWnDJӫΞmBzl\[ضu!== ޲ӧO3{WאhhKyΎ>˽Zo#PaMylEii)KKKGII 6WVaڴS\\jL?p3gD^nx=vц ~ #99bdff:c>tFAASR$y䗳c;v)S`޼yVp|^O()݈%-Y[n_݄QjJ*r:8jW[2O{#틋U*tvvҚ,ɓlIzN:iӦI(c=>s $yR%~t֬]?\{܂ ڊK.IG[jCDd|/3 'q +}A+""Rm0Pզώqcx[Wh4̱ ShG9kbc}ɅF __?;v\'44mm2 '%y~Ǐ?޸ᅅ󇿟? m砃dlnt_o_exb!yVBu((X%B-W,\AFc -\=A~A,r_†"tvv`šC53gb{db磶VR롇Į]p_ /-_.ɓ5kʕ0zqa,ʒYբ}}7~'k[yyܼJ!oQq ^zi)=~]O=v-Ess34/OHI X}1-2J:ٗԵ\A9-ue'>hkkCҥhn!:Z<1uzRScQVQUVCL3Ȗ챍@^nsrhd/or,]"""k֚˯cOEww7AnN6e-Zk`ʕt\;Wr@RT8Cy<̟S&"+? (m4.뚭貮QZ\5ʚVyzf\dfεz$%k;ɹc={6fϞ-I;wS+..>/sϙҢYfYsƌ1cJ>\Ap{M98(,Ler3Qh.]뾑EDiMuqus{G:&LJ֎/|O""ۈ(3t…їtsb펜 ""dA4hlWtx&C4tٺl ޅml]0 7n1L|}}qFTj싼Rכ Uܬl>Ȁm{-RpOWj'N6Zþ{\M"tc#>xZ[Z=&R0ba[l dH[O'pڡ`t4ԩ*Tjč'}wp/rOy:M-'&z:b|>܇7[WuK0LDDDDDV|z5j^ aH BCUgqtl C9]hc[  ,4 cǾhs/rE>JiGPN64tim{-#m>Y GFpM N76>}q_a϶=^[33gB"ot|C싼ȕ8NWz[כm- A]>nc_]tݦo{U?44U <Z_^TPL4M(k.qSu 1T'8 wL^߅'~Ʃ2|!""r=A: P=0 Hύ݋e˖A9UΕ1 OR`E%8x ^Z?PTN(nr3 Yǽ1ppÒ3dUعs'Lq4e^nǙRS/{ࣽoMOMx+CQ$k70"q70=׬vk介1y#nAkt'SOCAGǎ55jkF׮o;wIIkےس=<F߇;k$ ZHY(˪tӺ^{bn]+.ZQDAqkb^j݊UDjE땶jJ"HBN|?ɜ9s~gr ̙.]1ut6RKKجy|͚U۹sCB!wuCkH'ߖ-Ͽ;\drw֭UΡS#!a^L=h`9o"ÿ{la:)>U=+ѬγcѪuxzyc̘qVNlbNWLucGMRȊc:1xX"99w`:dN>W IYk}"$%"1) G|omr2.YKq웣P J̟cx3Ғb4wrҼnҒbD-{ i'R@tt&jjK^+źXÇSL*'T&z*\r{FFf%Ec>|_%Ez9z(i\r%#1)INjPZRWƍkNş.,xxx`%\hW-_{h"kR $U"vx$%FG3Hu>Fڴǯ@hh 44+V, 1h@MwބnݺP [Cm3oڿWMN.Зyf7nɻ~F$$$ $D.$$+Wu8pǯѣ{w@6m~z1QQz5+/NZ+ F||e~noo{{;{#..lt X1lPDDDҥl_t)3gF`С:l1|ڴ)Ezz 33gLz,DDD##?f|y7^t:e =$ =$bbc1c4ʙ=W;P\\ 'Nb̘1z뱵3fLGLL 3u15j߾oߎw8Y̎ P(pdNGRSSQQQ^9{$%%"))|@r*U+j+^1/E^^Zh C֭[x{{cVT r"""kJ ЩZxz!FEn½nVW_y?;5 99BTdyi}k+'$8[|5k0o|(J՞ CTdfΌ@^Mx{y#b ̙;IJ¬7gcY\0ud.Xɳ"n-^'zoF'DFih̙;y,Id :7ƢE hb 97Ǎ3P\7 @{ 7rsnv#7-caj9]zs]Ջ/_|Q'mر&WX8a&Liu뒫7rHe<{$HU tX ;/!""zXFk{<5ellt!J)۫e+3/Hx T6:x=HAPekW֭LN[D)&+$'"""Xx]  ;;̽EŇаZ o $,A*2ᱮ,jX 'G0[B"K=vƉ x-4HkA&!9tvvV[RRsYȒ8FvO.`g{opH$-"C. 0Z 5cn~ݐ8}{Y1:drd29|v5E 1E5tPu]|}m= x-RogYz4o""""""p"""""DDDDDdqaltTS a _@ii [Y.5OGk@j\ %%(@..ۥ|,,;)s.u($sӅ ~Zh8x-1$R 1ʑQC.\08-.?>,IND)xlY0l^ V۵PRRa#F@V8t,j8j,r`{:lݕ KM7~C䯁$ngQb""Pe壏>Z:OD{J!"+H?Ĥ}ѫO/"""",AP]jܤL"A$<KKKa&D򔂠ѡP(иI( iڴ) 6m %gԡcY5o=8 tJ%AӦMQvNe<舲;w4=Δ:?omۆ~,ZAV$@eqqp>ck\KnݺY+ ""AU;csw;6k;)aUgJvmz{$d}R@&={b xGǑv ~g6ƶmOxzDؾn-g^<3n]b(.1ml 1e׿±Yj5便5ηs.Bv;^GaaN-[>w[?2C (8rW7tGB*jqz 7Ѭr> E&زjuRS|zVYs'MggdžU6Ƙ1/֭BŢf5.3 X[7O"=N[ +FyJ ֬]5IȾtk#Gɷ69K,F8Q(%ϏzDDT C_ziI1;9i^7wrBiIQ@bb"▽˿PVT ::ZXz5%ŕ˿b]ZLH)&y*qqqXz^{v##3)>|0<JsQ$$$` z2֯KFbRN_iI1XS^?]YKjUZAdm۫8sύČX<mڴիaE/\Л6 `ŊXa# ۛ45mqBppMb&"MUE7o ???@M|95yo؈ޅbʕX2X~=zthӦ-֯[#F *2Jo{2xIk`e|<AAGxxi# sG <Ƽ7d֭8}m+g {:Ȋ*/7Xh!&Wp jfE!)| ?g#H-8(U>}}}u^r^EDD ^eh]c뫓.P\\IFP`N ̜9S'rΟ?ꜛ Jc6:t/^Ӧy 8IDATOG޽b9\]]QQQ/RY=$;'11}6c3̝m,9ȺTMEo#[2u223FQC]Py]QKޱcGdddlOOπI#%IrlGΝyZ9WXgΜAdD$[@*?qvvFA-}Νɣ58<..vG\\\ P5:pyy,p=\v sS&@iӦ &&P(HO@l̜1H݄{;y)(+ŌL*gNl,_;v@qq281c\ck?f̘gcj|Uվ};l߾w*pdz',, .͛7P4L6M's///sHJJDRRbdEh!@vGci| <<<`pppȵ:dnݺȨYɁ7fEE "'""&AԻ:n\.F.[x Fn}g(}PPPY oo/DEFٷrBuH\͇RD^=apߺ[ɰ0DEF`݄7"fLO$zs6 SLF삅<+a%xqmtAdLL6]o.s Β.HVncXmLȑ0V*[ $aqVQ(|xzyFnn栅nh]_U"<|l8L-_@>ݵK9bz/ꤍ;֤G8w„ <͝n]rFczӒ$A6`[{E=, txzy#ZW˽~ ^ޚ2A#hZO%!J)۫e+3/Hx <""NUvjE@: cAd`:uE6F_5߼^ V"D%HRW@&7<֕E oUCA9;pq u($cjȀBkjd2ΝCn]aggu|Q*:\n0?>,r{:logtyD..2t`^ R3Z Y?ӧGQaN&A&÷kWyY0YdIltP__[@^ kԺ:jYDSy7lHTlt """""Q,c: : """""o t8DŞ"""""! """""&{:HTlt """""QUDDDDDdi\A p"""""% """"zJ5{` VDDDDDD┹DDDDD$*6:HTltTOKDDDDDTDƨ𺖓B[D"w㱦C!zSL#wñcjcu\.3JíG+gt7nfjtMC~Du䠥C!zZNmO|֡Rݍ$hT&}2hM۰*:uuDTOB sz5_Mzz A Vi̵bMܓc:Ȃ.6lĸzX1^%T׫!$'""J~3Q_Y&3^J֫ktTzY[Au$H͇l}:""C:kӦMP(TZ_n]7  3WT#f^ů{y/l01~c'"/E†c\v  ɓ&1J='׭ݻq888wޘ:u*?͌%(8pޘqsnVkF%&cE͹1mMqU <Q%@mӧ{M6sNHʄ _cZ/qu׿ C Gǎmh׮|wxwxv@K#cUPBiqKu^pqfL9b+.59sbܯnM;~{Š!ðQQQů;vڅ¿W898x@>>~"rrsun<;l8zƠ!co57(3fTSꇱWů;="'17&/ʚb1>̉U+Dy8p=z>#..:;h׮y!33۷o4iʕ+:ر#о}{|G?Od24oFBaaacW {h۶-бcGF$"/P5kѱ5r #GidgdžU6Ƙ1/֭BB6mN ]nT 8y C wuC7?$$휔JԵ^7lW6nO'7c3Oވ̴T Saϰi:L=be>mقeKXt 6632f4^z;%ܰ6y==5?;y{U>̞DZӝJ,{M[ZVoT:== .ƍQ\\#G -- V?RRRPTT!C`Ȑ!p ((3g'>>|e,^_~FiӦ!''׮]ϟoث2\:x|G(..|xch7ww\2n^{u.tgK.L悾}:<}B&sALaUz2ٍ $KE{7fF̬5ӎ311q_AډT(+*ő/y}H?yRݘzԵTRiC{ߔCȺ bU8r8oLp"[d_ g_sތ¬9Ⱥ3vه:a;t ֮Ed둘c| R"@NAaK2zŒ>2(a@U^QE=/?'/?3kpm6=MϦ Ār>lpK8*+S`sp#s߳k:?&F>Fbj}Zt>e浾q< ѻwoMZNNx Ϛ.^+Ͻ...ڵk>5۷8~xn߾ ___\~NWeιsa4[^=<=qd~.2;???M[ /W=,M#F-ӘzvP\TdRUV#?׻muZ:<<z_F@riW&L৞ѫO7ww \cl;]u~t^ Y^EF?7_} WWyn{c.bͅ\&Cyy9zW>^Um_f07Vc1hܸq{Ub Q}em-rvvϏϏݻ3#fdݻW,+***C#{ > ;v@ddv܁#Q#{eee8Yk}>/ݸnھ];dggO5櫩$Nkܸq[uscU5FOVj܃Უ`?FX03fako}Zc]7e1s:~eLo11W@:o*`ggu١J{mÒWޫW/߿"WVGB-55]v՛Gll,`ooNgcֵkWsI@"XS yF;p?po1y:<~%?޽? xՉziً?~ Kl@Sn{mÒj GթK"66۶mCQQ k :αϘ1(++^}ܽ{?&Olڋ1g̜9iiiP(HKK6hAqȑ#o>¯a<۷qg<Ѫ*ׂ͛ĜXbv܁"(e8q"cƌA ~1בȨ(\?_(--_^z~^uo"vA,:_1m4q,]Mh;7tdf23x}4OǡPR}6mjψ/7_EY\roF{|}ita,Neƴ<^8rtƊ(=a54`+u.` łE1md(<9bf,:gϊ[˖ÿgo͔b^[,dWƔ)S"SOa޽ضmZn WWW,_fͪsäI쌉'bxE[l'|ggg5 SLiچ s"<<\s.pppqtR)cVT}!/<-2~&Ϛ$|{7:t„ 1~+X 9Z'=$8[|;wgkz^,W5ݟ&NBvѳW/l޼Ə7 Ţe"Ͽ@RRmBgzz >ub漉ݺ fΛ2}&ž|cǍסW =7ާ_?,X֬Z~7 {|}iԩi(LBHk#oM.E2zBDo?e.Y)(UhPH$rW9:֡Q=wU)())u(gg'8:6CV-kz5yJ=ܺz8c¤wIc$.Q^.IN zmڴuUx:C=Tg3 mI*[RوB$!4 wՕ JT8^EDDDDDd! `WuLDDDDDdA ,H5Wqh5:l+n# """""yD FDDDDDDNM$$W{ȲrJ{D Qn똈2Uc84#9??-+NNRx6±#""""PBͻJUCzKF'ۭtM$XB_v0wIENDB`mathgl-2.4.4/website/udav/udav_cmd.png0000644000175000017500000022013313513030041020037 0ustar alastairalastairPNG  IHDR&HsBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwtn6 B*z/ T((R&% A^h (`wHBKyHfMi9,3w{g6;3w; ]`2/B!B),R;?S]|@L} B!4tdM$%%aHNnȩXaW8YhPomiB!,EApJ92[sEYq7g((ů B!nu[p5)U5DZ{BEQ()_np|f3gd9ZCViif3F*B!nu[Q\|g.!KIMk(&ELV\Q..V0HNIz( &V*1׮q '+bjPCb6~=2S022R }BԻFqoX_hÇqh:6n;FZL<~͒˃p,ܹs$$&ȹ糗;n0OfĻ#9u4scoZ҄3I899elWL`b<72k\.\ȤSǭ[ ;… d=i6;λFuVfSB?d?yi`o/Xo1g\+;/w®;x뭷c?ӧK|i+ٳgHHHMII;_W-wzVǩS2y2ii̞=';"B(4T$TI͚'ظQόa=.:Zm2m*M&1d"9)^OFzY?̰ IJqzKg5kΚ5kr4^db2vuZҵhȮDD,|/dĉW¥qxLK5kAUU5Cz*i)9UUYͺ1G.We[Fl ( O)^<ri:o ?S tJEz2ĉ޿.ɘ ^Nqg+35% z5GJ|i+U;$&$Xy,_Ա 6~[sv:Ze V3OVYKo. 3ddиUf2ӧgsguM&db*rp,0df`2~wRҬe̪JXtIq'b6Yx4NwϞ<ȣ /_S&b20}RYx1GUz~ԱnF-r2 BQT_/Q슅RUU|M6o~5k'qpDrr2;vtUhPU Ž;E" cVVOo:jɘEff&̢ !-VՙWFxx8ܱ[M'N3j՚=Çiۮm۵pDG#55VZc2}%7̌m8{̵5~9玕I<~(zs?w179rsx 2({uٻO:t|ثW;)!e~7_LV/V~IZJrc F>[STUQPJې̙3ٹc6|ٳ`K/"{cbNlQOCX̛ߚKcľ;OTcs7ꂪ(IՅ+W/c2 q÷=]\Grhd Ɛ`IS͍~d"##RSV{9ٙJAb4`bc6˛~t: 7ds}!f^wJlB?_}>b\f]i4)h)h5i(Q6Tf;[o]*bťW8w IIIT^232qvq+9w/UAJ89=!B!םz,>;+ԜgP:T)m //Rh4r#!WCJJ h4`6憯x{yB!nuE~*E(9ᦥhDBrplu(B!DI{5vv] @=l.EA<=$B!N]웷B!x~t7B!B((J,B!BQjRB!BZvW(VC!BqQQru !B!DIB!BQj~B!BʨPB!B2" !B!DeW,QB!B}϶X!B!J-mU+B!%[Е&Hdt4ƕA3_˻TtѤW6n|B/#qq-C?pB;;JP7p+&lXdX8*5%>KԾc6~)tya=.ЁM~ !y/GN]"b[(8fy2C{M\lԮm{Y\Mp;+Vl6ξ]ǧ7W/SKq3$&%@ɩU#J%hɑ=l鞱ߴ')v܄PU ?EԵd^}Kɜ#-?jOB!m? ZrlڔN~?}]'I;RE9ef?Xч;uę =OO/-R2f r-WRLq@Wq! #; D$gͥ{+RBQ矌t6w|y=w_ˋ6nD]XSYy/}zvd4a2A@PJV|t,7m_:dS ؠ[DHM=+#˗'55VC[ΞÍB^`̢?pu622uiNj YfOˁ „~R+ޖ*{Ah1FG}PQ;SAN>Gltg4fCttNZtUP*, \ϵ+TzCT [5dQ|-g *c&Ol#峫+4lH>}ݻwtgw{rcBjUm^̪[ctiH6QC_-*߼ IL`'ôU<ظ2ֶّB{[ORR"qiZ9QN⦘0Mkh=I3˶pV%ʁ^bB>Y/^s)JI Ѳ]I@gƜ?F?'*.=FZj( Tn rQΔwr,kh͟+|{O&Li1elH%!! Yl6ӹEX&lqž|Bnû/0zԭ߀wB?Eh9~x?yZl72Sׅ^"IKTTr _ . /Gq_u=5/T)[,#Cyze? R܈Q^$&$bOC~|.,n|ΉJ*SOѭ[7',dĈËysOrʌ= ,, MPP6pOLHܹsL0%))uի mBcԪYE{#+ùR9zw4Cœ埡͘L& 236}U Ձ|c?cF NтfDU3#19asw2g:(_!矴tLbYЩ*.G+~f V.KL{i)id܈Ώ/G(o&E^|^`,wi{9/s ܙOq/ Eޱ& /I Vw.49sXx7&<={(N7k6-j^]giӰ"HO7`4 Z1DJJ'Nd(yP,@RWVT&ф`ĐidKws7t-ޕЙIL2{C]bV@d05$EQu ESP &)Sg>P25$FxjYj'f-yyd~z9w\}<}:mڴmvL6sЩS|?;о}OyyG -ٳgyꩧihҤ _X!LXXeZ^Ď;(yn8M܈Wk\\5Z:e&5@d.]FYV7 ѡfu|th4zde0B\CZJ2 fS%-8y? ?j]F**fEF%-Sz!jxqG{~?'%Ij [Ro}::@ގʢ+QX*X媐3@A%>.6KQE)r֭[[-oۦ oռϧNm6Vڵm[h\_~:uiٲ%:u!n_|׮e5J* 0oƞS0_fHыTwʻ⌓Ɍɤ SVFJwj'+hPutL#YYi&àbR58霘ƣ<~}x5@˳$#GPZ"fߎVHzѳWO~wlqx6thf3zcǎ#)9{wƌUuФ*|ssaB ggg\;+ht:Y8FWEJؿ}fԬ̆d\91t 22 &Ly$5|8?n%W!Ľ-y׏`_)ҍIOlʦoWˌ3sr?qCN*FER5ahX*i[J8`J=wA@k s^_g BL&fΜE=r{_<Öڵ:uXf͚޽G}*}Z<@#+˘ӟ_uԥnDFFyWd!nPEwϳx P?x/6`iގM[⌢sbįX=/a狂HSS_\\]0v}`yW'4@B!c׮M{|*gڙ|Ûx(s(" y/Wy!:U=:YLfÇp;PTX`? {ȬW,ipUT5{_n@1WPK,gYLEVVqq߿˖R|y^yeH->nni¡C;nfδkرѨQ#K>\2;v:f|<ۿ?C_}-Z*+_ٳgv B6|V 1|'D䱞/V_l+{`o.Ź+w'ƿJZaOB!mjժCZu02٢ IDAT<.>N8NTTAAAb:/@iѢuNU;mӖɝJoQGr+\TW/_"ReJr_;\|Dz@V\]?|ggg|||hP>^|O=Ey;DG_RJ|w;=`N}1KU杷,i&N1ct&/򠗘;o>|iݚeK{Bjw2R_jY|2 EWA)._7 ,0G6b su.riBQ{?:U \IFٹsnnnxxxXy/;o}9zݺd'-Mb.f[|RNZȎm3R)5` |==ղ]:9vs%߸ڶL5Z7aŦWO=ؖfիPuJB{==[V'ԩ [mnO {E_9@nOeV,0K-T]\,Mq&BǮ o.LMҾi=TvZ;gOB!m%9Wv-N:EVm̰tY*^Q5 ܹs)yO,eV qR2*eUw@u# R'ޭW!ĽZ5jX>[GK- `"/\_neBiTMѿ/o/&(GXrFh2u+&=ke>*.V͝Ç"hаZMt#28GinUB!mraO{yya4) !n_;Up7$_oo/=ZmB{) ሜVpng)mB{3lɻB݌%wBa[P v) !B!y҇I!BQj9 nU!B8iB!BZBQEB!D)5iܨd+em!ȯnuB{޺5y[7TUE51*YEUŲ`gƬVœTFrTdt4ƕ&{y7*!Nf9Oœ]lhR=,JJ%*2:<*αst"JAQT+(9jTFJMI]vY&dG;ZЦMBi&Ff˗ӡCѯ_?~f q3L&233ou1v8w qʭK8<*T\\f*L2c]رcG۷o'11jhGlڴiӦr׮]3K.FzjԨ~j\Q/^Ljpvv&$$={rJjժErرߑuN:E>}X"Ջ8ViӦπ*oXXիWGSfM.]Z}/3ϰgJƍ9{,3f̠[n4mڔ&M0`""" ]7ߤiӦ <K7nꫯҼys^}Uv3< /;lf…tܙF3p~wzA&Mh۶- )wuBBB //R޽#GvZZfs)߹s'wFUUFmzݾQF͉'6l#G,i U={6mڠ˪.Έw1rJ߰ -V5`矻8R_l!Ethl ( & zjBBB8t=hZI&,[-ZU&{C7ofȐ!,[N:qUL?6l[o_|A-طodѢE<:te "44KҥK-=ʦM^QF̛7֭[c0?~<(ԫWO>-[ĨQPUUVuVʊ+h֬$22jHLL$88/Z^zHPP.]"66OOON<պ\zsmy駟tpU`РAXrQjUN8DFFRV-  4 ))H̙omGq~7nj쨆 sNHMM%88تYngffk8vdN>͠A?HMM'&&ơ2WcoƏ Ǐ/rCP&{%))pwgʔo%nֈH/_, ̪*L2c4 'NdyӧOgĉh4և'OҰaC*̇~Ȃ ޽;nnnԨQR5k| ]tݝ.]`*˖-N:1fXtռ G9t;wOOO>Clb/K.QR%Ν˶m,?#,X<:ub?UUٶmw&((Xùt'11իW'66cX%""Rذa4kjݣGb t:0i$'"" .ɣ=ȴiPrA^gѢEn޼Ν;hÖ;-bذavȰtRd&M/Mڷo5Y[EQX? ٿ޽{[*FDe/|ퟲ*ԩS-=ӧLRrIII̜5L(UBJ&dw۷/ǎ?Ǐӷo߂v׫'_G>>j֬(l޼ڵkӻwo6oLjՊܦ{~1dN:E8x z۶m+?coדɓ₪ԩSӧOܹsY`.I;ROڷoos믿m}׮]+Х3o[9{14hPSOY/--GҲe[[J ̏+,|J U-݅^q1k,TUe6+ j"""VZYϽvbzʿ2t_|֭[`1ʟ'ZzuGҽ{wF#{c?ܻNNN@3%m;Zvk :u_0o<:ĩSX~=dŅn(L>z֭[F ;{,^^^6Ş_}/_vՕtN8mؼysߞ-?dW,|MbcctfkW+/eԫWϪ%m*|ퟲ*ݻi֬<_!4 |Mœ=e! JD1b',?jשfʩSyT J9bcYf-w׏jk0x+[07hH>4j܄>wO4?lGÐF| ,3gZu*ҾCG֭#Lw¤Kӧjcڴi+~B׭[?jގ;N}1n8*WN.qy^̱*Ǟ̙3p]=7%͋ѦM7Q̙=6dTZw^[~DuIJJh4÷~p|Ç$%%3gX<4rHz-oNJJ ۷og3<UV->SؿCɼ{[رj{s(Ǚ8q"}ٳ%Ӷm[4imۖڵk[>RfMx1c#FA|ݻz1rH-Zdynr dӵkWy6o\d7:GϘ1UU9ҝՕ>~fG_T*#GZ*-]_o[=סCHHH`ٴhтZjٽ~Q+cOb!n VB5}j,Zh.=s>*VdP~BMNNM۶9|زG6m8s4ݺw7Gٲe {9}{ĉiҸ%˗y'-qמ=TTmnVPZΥhXzCB-',.\W_}"00.]X-]ϖ[~=SNرcTT &K/Y/YYfqE3f C )r[: <#G`>P.]Dpp0#GdСVi<#a6ٳ'7n'$##m۶1n8uuO:tVt:}44k֌~1|p<<<,89s LB!BRӀïB!Brb!B!(5 8B!BX!B!bJ*Bq(\\f;TrӼS\7(i_ov;ܩvڇEӎk`XBOff&ӦM~/_ *УG~)tbYUF#-.xߑ(7-B"!n!Cp!֭[9y$gԩh]p6mb8vhp>Jz}|s݉ǵRU, ˖={ѴekZ毽{KG.7úuXd u___~ionnƍ4iWNhh(F.( ̙3???i֬k֬YbZM₿? >>ܹsR MaԩSӇ+I^ZǞ,[^O͚5Yti;ŕ$.ҥKQz5j駟Zl6h[qF7o |gvao[>,,ի[\PwY^lPŋSZ5 aϞ=\ZjQ\9:vOӗ4~3E)[q;e_ +kzz:M6eԢE o>LJtiiiun7٣Bx)4}z^iVQ̜3$PF ^"=Ͳ i̘Q#YpPxe3c4V|spss]6?z^9i֮OƵ*U 䥁45jwl7SC­.w}ǐ!Cܹ3۷Elڵ+ӦMyytܙӧOw=<<8'ת IDATvAAAvV EQ8pM4̋^zkV^"$$$%%Q~}.Kǎ=z4ݻwٴiO>e)oI]v5j=z۰ag?o۶m1b}q8{ˑw?9'x²w}GϞ=-[v{l}^˿E}pqԩ7PByժUƍ6/i~ٳ ͞دŕuΝ<쳬Y^xkҬY֭cٲel۶2k׮ :޽{(nay׊njqd2*IFHmEVUÏuiL#&KueGѢy3^<Ⱦ/Ugyo(5 !++,$3Ir*_ȬѬiS`cYE~V{Wpuuɓ,U˖+W?__=]{v[qޙ՜u+m} ȌL 1d_"R">%CXJ!cl$& cgPXu??ҝ]~>:ϧك碻C7C7Uv >',,,0qD[W\AXXL"rAII JKK0̏rÑ +++$&&cǎXfX~ pww G^B"]F_MN-ۨ(mGz`SbH[7Zre۫bge*_ʊ(g^^qJ[FFF1boؾ};F)xԩ;%k7Wu|ӯ/uGjZn ݻwX;n߾'e ٳ9"WPר/$[׮ nz tAqcFc0?#4/76[+ |ac#򻹹9^~#^$N7{N?~֭:oooi PZZ* lmmK^o_)`222333 SN8RtA*cܹs~ =/+gJ]&6Uܹ3DPEu)UDTwyf4UDۑ"];-[pqq4Z;M4 F\\Tkaa<4lPw*]}"jcQn]|w {~p {9uׯ^WWvn^W(ϼ zV&2.I̎BOO?)[bѲE M9"rQҺhb䏍T)A|.8;;cϞ=x%>~{C Yd BBBx<$''c8-[ӧEFSNh۶L]``cc͛7*uT̙___!--Mbs-}]`` |}}.!((-= .cC=Ν ___QEu)i^43"ڎ>|ؽ{7o>Lann///̛7PTZEKuGgF[Eet-..ưa0w\] X|9\]]Q\\\ayeĉ $PVu렯.] 5]X(ȭ[}31cGFwnS>{_oDXZv.?pf¹Oo!5l6\`<8!s1 F"h^>7]ENn.N_Y.v} ~ع=͛5ټ4Ot};0 II8p{vtF?%-a?CyC SA6S<Qmbx"<<_GyXh V[c$-|gkؕkbg~q"r&͛q VGTܲtQ //AB M6ۄqXV4Q !((mڴ mEAHo~e{t| l. | )gCh(=cAh0"$JP t!"">%科}eA8r-;FV0PB>R(5cQ=7O;Py!͛{XS(\ U BKL4 &MҶAB -أENn.6mÇm8mEAAJP :Zd0tHOAA”-Υ&s9_Kl"D$աl.CEۤ:\)oYBk tCR1T5V5}+]CT k׮ ֮]8rRYj׌yAD#)>g2..7nĶm*=M۟S ςrvڅ]5 D>|066BCCQRR"7ÇưDllHxTTahhkkkl޼YB8k֬A-GnݺVVV044D۶m%?+*ݻw1bXXXN:puuE~~B*k3y*Tv;>  ݺuC||Re޸q#ڴi###ŋ`ccSSSzVMشh֬>| aÆ(,,Х2ڤpˉF֭Eae[@cpUWJYVMYng7eug;Y[/ȣAՇ)£Uaaa@~~>1c Axzz:,X_8qҰb 9rXx1󑜜TAxBBBCCDGGcҥHLLT*$&&"==|>'NҥKebXl\(*ȑ#\V"jkq8?W\///:tL0pppE߾}q=y999! #F޳gO̞=CwWMBBVZϳp [[[_@|'}0g1d[UltgQǏѵkWdffEEEÃPF (zؔU"YGw:Ty9z-#Gm;OrsJ CQ7o&3NUXJ-A6&===JRGA<@z~EEE,`Ç044XXX[Hsss E1W^E#\VUv >NNN0`4iT|2i~Y6a#2qpp… 1d<|'OMFm>T +*6y(@XXoܸq5js \ElBl|$z^}l)BePOrsalRi "'7-*a",ENNR/{ubG*=z@dd$5jSfl.Ȣ"Axx8Ǝ'N 113gĂ ]RmHNe+WbȐ!̸nДMg&6=o۶ XBU\\,2P2P e<g`>9r>׫Oopy<*#֭:T[[[={Vfxq9TtA8tiiii!##!!!h֬ pepivUf*Tf;ٳw^dffbɒ%0U\zVMψ# . 992VVSNwӕc^zy#o޼AJJ`fHyϑ*em{Gܪ)!ϐ#G3sUic˖-qiod˒%K8!99fѢEѣGrq}L߲@"%%\.)))CPPRqę;w.|}}*Flllyf#33"쪊# Uv0p@:u <\.ǏG۶m*sEY6aCEc``???L8*M 3g"-- <iii"٢l1fv Ԯ][ĿvpqqΝ;%(zT)0lڛ"NZ>VU8.ȭ#=c_ܼvڰ?#G3q>|`6^ع=%ϴnݚg0 G?%%۷/SfMĄ۷/siu҅144dZjƊoܸb +++&::ZB8􏉉aZjԨQf6m$Oϲ^rڵ+chhȴlْ fWQf򑥫Tf;8r_3LWWWÇj.ل҇a۷ :0LIq96mb,--ڵkCCC`w<SNI ;ucgg'^sĦy FE"A u!0),xz`^>g^><<}avnSOp5؍ȭN*͇>؏OǤ`4 A-ݫp]ۼMgl߾]۪ŋ[ QO,%#l6Q킼r%B5kUIWmAWiQxq1m"777M6~:mBi:b?{r,:;f͚j:y  |3g\nށf{Զ; Á /_^)J1vX4h'O;f͚mBi>u,Tu`hm˱x2{)kݺuG?3x~I]SyVK⻂ B0 .fҤI~:x<n޼ /KɧSTKH91V:Xz|Ѯ=jש >ݻ0~ZZBf1nxz/&>~z 5<~@~~-[c0.݂ZI:rN={~lk^(Ǝm`Qz}KW={mq"ہ>_;W|>#IIٳltKHH@o 6B$%%Iw|mPPP~l)_ou:8lf+S9:O  Da> R(ǎQTXcI[7_7I&XdHGڹTKK1{lAcǏaظa="իEEbxCؿ.^_ O GGGq9Oz*HH(!v܁˗…t0 ._ʕ+{N*5ʭ<իWSTymZ" 0pPnSV"PmݲuziNtg  QvGxYM ҄.1144BHHDnڴ SQ_"ptt8::1nxA刌}.VZ#H 23n4|{Ԯ]`oomۤif )iӧc˖-hذԑ,<'f¸qG;—-SI?e)ҏM.\@u8 3"TyVEn݊?SjW_}%rTA$oa%CP"999`x}}}8;v ~nW_}%端7n~+02_;;;|pvvFFdG5k ؘJ-`+oӦMx5|g̐) 8~8`| [OylSݻw8{6333쪌L6˗oѢTjCAA|~p*r)T"~>?+68{ ^<9eg p$ !/\.e_ϑ^D<|!3~؏VZp6nի~߽S<ҏPWyNǡÉصs'<OҥH=wRK?EOZo߾ nX0:vtziLͳP@ӄAAT)~ׇ3 PG2F0~ĉn{gϖ'k$G7ojֶ3]yę3;^?###dffbӦ(ܹ0v8xOݻa$''MR1f"nVt11IѲeKVV޹se 5k^^G5J0 /ϖSE?iN1cFoX`GLeuFW*^IAD咗G0*pt,gKGh/>LO(--oܴ^<{*w  ۷Ѱj IDATaCL捐 񤥑W|͛5d,)9 \xW#+*|>u늙~~ݫ 9 ~ݰW\A͚5أ-\ Qx=|ѣGc^={!::6[ZYȳ۷$޹} ujז/ξ+ Hؐ~lٴk~VNz)".=e{ߏ޽zJ Ϻqn6}AQߍΟFbC6WaŎ}:>r9ؒ^bDǢ2̄,KMњӧ_~9yMw鳧j˫HB__AA8Xw*_yKF|fbiloƜ3zTk|±=y"Y*-/p8V1c =4QGU˖-Å TyCm5 >}`ܹ˦<гy ? ٫''OYf7n,xxTD055ņ ѨqciyDSŚѐͬY'''mRexXf .\mU,jRWjWF>}9,;]T-wgE%3u8F3=ɣG5aM#£Gm5*(9pжm ϋ >}:5*ݘ0a|>jԨx 6Lޮ];888СC3fByϧ:Luuhɑ#WD|D\9vB׮]allF .,ð1Y-Z^٫ݻ1b,,,PN"??_$ ]Ѻukm۶SF_>===9QQQ!yfeÇcccXZZ"66V$\Q>⨢p4iga1rH?MԹ"ڇmYǰaаaC[nN3ly= \vM}||aѣGK5j>=/?uQu뢤G#GAII)իٷPQ>0#++ |>3fc_QXX'N -- +Vgbb"GgȑAnn` gppHE$%%!<<۶mCaa!bbb."CY}m  Ett4 K"11Qn9rxb#99p(_^8Ĭ&꜍ eæl֋,F޽{Ν;x6n܈={H+Ք.HqqqȵAЮ] _XX5jHٳ'._=/(4ʻh[/1ݛB=~|:w;rEDa-[HkBI^p8r ~yyyС`Tx Nnn.{+;;rNx-:v순ֺś Nbb" "( ۦgϞ={6*KHHUpyetrrB@@F!5m>庩 MYSSST=Ts62)[/׮]7oD%ICL6? ((;e˖ݻ|d۷1cN<\899a޼y۷HHYT\\ ???۷[ݻ իW4hO4l#GĊ+iu֕322pML4IğA*u-Eϋڟiv*g-w,5\EEJGDգ^U6,et*ӱ(--۠AMӓy6`hh({1W^(;|]C?EEE077W[_aۘWH>VVV(,,YFqLMM sssl.*zw,4agqLLLPPP q:g#C)"K``prr€ФI%.f͚󃙙= ///%3pwwǰaPF EEEW>~4|xHs"88=z4_eSSS,]%%%̙3eswwɓ>ԩS8}4֯_/6lO?a,\M5%b޽` ٳgRUiVA_0Qm100PnݺСCj矑4k *?ԩt5oq9TtA)98{є^`cgq$hΕ>lFD\zUB'[[[̞={Eff&,Y"SiϨ*u^RR"=NPW^u^~zeDݺuMdF–lXx1 0|Ӫ+ҥymzz: KiLKA --[ӧenŒ%K8!99VJ 6oތbdff[0g"-- <iiiոEJJ \.RRR燠 ]hpQp\ܿ'\.111"DLL rss~pBa޼y)6mKo>|w"~Qʶ?M%3r%ƣ{ 4g (?GQ8pQ6ā%KѣBBB7HKܬ,xzzƍhܸI`ygϞ?#̙>hTM6!""?%%748~ 7oDӦM`xxx*zZ-l,Lqq1,--see(۲)SPP?~o޼A0{l?^ѣGb \t fffӧ"""кuk6-0<gơCG 4Ⴅ9>pmWFK|ѲeKڵ ;vQZZ+V ::EEEꫯзo_7U~Zdω2(*:MMM{ܹ޽{"ؾ3>V*Py{,>xJ 4u,+/^nݺmU5lȑ#PX\.j׮DUcݻ7Q9hcAK t777ܸqŸtEf͠DPrn:_۪TGNN0'e]uAT ԧ;v,>|KKKxyyOjU;stQFa޽Y&ƎmDFR<uߠQ|pژc={Viyu&\vB >ÀᗝV3G3#QƤI$."4Ousu.@4DyB{T|q$t~)X:"O3 d3HAģAϪ,Tّ>>SAA|:L◽Z:9:!*eV?x Zh3+|wmkTD]RYآHgeT˯p8tMB>t*Af͚ ʣo`bb-[<OyhhoȤ{:s ժCE2hj6mVKK;.ߡqfZswgΜň`٪ v i]/u.0 VCx*.W^@z .]‹/9}+CB>K.Exxe:gf,`5m5QQј퍿n\#Ix /ԶZUyG|, =n +++m۶saVVV EII T>===ݻw1bXXXN:puuE~~@7i~l> "QQQ!yfQ`͚5hѢ}vڅ]5 DdGGGu"u'nyu'MWԔN< M4qAxlڣxQQQh۶- aeem۶M#<1l04lFFF֭#OgE+4}GQ{R.OeFw*(KJJ .neѱgYv]swD߾055EÆ lY(?uud[o߾ʈUZH}N8Kb˖-(,,͛l28X`~WĉHKKÊ+7r*\G#Grss4k *:˗9ooo,^HNNFjj }`Μ9pqqILLĐ!C;i ZSvg̘1ܹ3BBB~lڣ4}>,fڵHII(ڵk͛h޼92)ܞկ/`rTt.&6FYsc_ntVUZZ a}5[pKzxJ U1mڷk__:cQ:xqQQ4h"zzz(tϋǏ# iiixgJx;ͅpsssNNN0`4iª2ԯ2 U0]nڝ3X&XǢgEKK/=4ࢣ5u]ufaG"''%%%(---0adwww ++ ?~z ,LLLJ*l>㰱 ʠJݩ NŪUp$$$t*ސdXYY!11;vĚ5kT-GM]nڝ3"N"A*M;~7n&Dܹ3D%@np!fdd $$͚5._,naa<Wʔg``-Ξ=+3}8w_jj*:t蠑ʠ>lԩ`N9"Rwh۷oǾ}pJiҐSNR)fkkٳgc޽Ē%K M'MdTꮉgWJ(ۼT­퍮rաuǰmK FE 92}g}}tsrHIIH%K $$qqq(((Crr2,S 6oތbdff[$o?={gM-[rg5-Z???=z\.ĉ-; /RRRD$UA}0g"-- <iiiǷRwhOq1ԪUKj6Q3f̐H#k2HkoĩSrqqmVDvET+jhO讉gD]*̉QVj})h;H'eԷ8;[V֬&q̙_ӆm)d U-O>%͛'odG"nʼn'Νƍ >YnѥKy:t@HHƏ/Uʕ+1m4k}={%ZpFnx|gدκ*P5ݣUQGΝjmUT]W{NLԮ][ ibnGp׷lDQlټiLڼMT/.^ܺuK۪TaP]ڧm_~X`UMQ-[>cZE}nNDUAUv̰Z&m: * 777M6~:m@mx?S>+ԙp8eTֱPyUvՅrAG1vX<|b' *jQuigJU 3i$L4Ijh]}$k*Wu)_/OuHAAhR(U#]UUa|XBuHAA#BEΥ(؇mr<Ѷ {?  BWԱP풑F*at"4O m5O$L@wS? p8#rAjk҉   *B_   =OG   BIoHS   B!jPAAS'   T\m&  BmZ UYΝ;(..):tm   yUPn]tݻwǸq㴭RgССC$$$h[%  BG)Kǂav<\\Ia.z1,--ѭ[7uT%XrEx{{#""yyy?K.i[5  B4j͚7uCa̘15k/<<cƌAll'kp L0ACZXv-BBB0h ԩS BHH֮]mWSNń _Uh B[0`DBGF|Fb=pCjo.]իsN={É'0p@JqE… Z҈p88:: wttx|Ġwި[. Ѽys=gΜM.عs'?^i - 䙙!66 6mM>[^x&M5i/^ВFDuHMMOII7oDJJJ0tP$&&"<<xHOOǐ!CtRPhoԩSQQFر#o?o<899W4#Grss4k "2|deecƌ'N`ҥزe yf,[L.wЯ_?$'' ߿;v, '/?~<-[`ሏǞ={$d)+ٳg[CFFQ^=L4 iiijɬ>|7>Ĥ˧)RRRm5Zy ,,,uV8qBj}8::"))I/)) NNNZ҈.a…X|oXp!D_EwAΝ5CXX"##333X[[c[CZЯ_?DFFJ̴DGG]v033CPP^~(ϫ&;;} ԩ0?~\D;Я_?iӦXf N<)_l"##_ _ٝ;w .ǃK9g'Oą мysk׮رc:q<Oe+++z  {([ihh 6(Et/))a?#Xp;j&##vvvRGup8"@oԨDFqXnlllPV-E6mZjSSSxyy):Q}\P # 'Oƿŋ N۷oׯG.]rJet3!???رcx-;0̜9S۪Հ#G֭͛[9rDիWѯ_?n_-쌛7o}ի'O|i?~ÇaÆp8Sl 6Y u [$x=?0hР ===xxx(|(:"a>h CCCL2EfL6 _|)7ܹs1zhxyyݻݻ7^ӧΜ9^z ߼yccc0 v޽{U֬YHdee-_ϋ~`OA_|)qJM|bǎHKKի%tظq#=z/^СC(--eKBQwƂd?#33vvv 0p@}93e ٸqzRqrrƍ# QQQꫯQ CHH"""rJ̟?_j'FdT9܉&&&*FΊ:;ʦqww G"qgzQVx<܎xH|+++G˅GޕYW_>^F e'Ƀ`zjlݺ:t_~]ϣo߾l{ܾ}'Oď?Q;z O>СC1n8S/oeT×_~ڵk fcѣG;v,7n,vEppt֍WD5Apܬ*oHXekk,o"$$ ի000=z 6LJ=N)8F۷oŭ[mjĈ#"33Sd0ǏGxx󶵵ٳgeoΝKMM8,222f͚/_VZFΝ%K;K666O ޻>Nk׮-_34cBBR(˾}гgO<"a"cJ711w 6ӄ|a<9==CEDDz)&/yddd{ߓ ~2d,--i&MN2(n| O3B=zx_App%\tI̙3 <)))x-JJJE燣G")))rHIITSUlllyf#33J˘;w.|}}*Rq͜())A߾})Fq6899 _|vڥ\ 44@ْ_$wغu+^~UV{[LLLh"5 ZҸ7ne˖8ӧcرČgddk׮;Xp! q,TbcccԫW6m2l|f>ѭ[7ܾ}<==U:)>>())A%\=>]ںxbƊHEDD`Æ /p8:uD&_k׮yyyɿ|+WЦMyNB=e6mҤ kddd簱WWDl ˠ^ADZ85jԀ(*quu[쀴^%$ĉ#A烃N>fffի,X ^W$NsssTiO E[T  Qk\9őH:XAAAAh:GT*={2t:Y$`ՇA<  2:  a4y#  t,ѶAAAT1?c]AAA( 'HByQAAQ};Ь Z EAAr   BEBule󑝝:uBAAA|hΧ+ФIM0۷oӬ*3g $$4AA2)**BR(FŞ23gbh E^ 5 WưaeDر;wTIK"<<\jAA:?/?Bhx{Oō8r$yyy`4˜1c0k,_xwq9_r"j %7)6wMh#scj nn kX(BWf!"I7"*UWG:Kaq|:9 ox""###** ]t*uRH$ssAy߿VVV2]~6]1^cyA^mjN.o:uս{W\\ѪU+oqH+#F@rr2֬Y8q/F||}xZy[B֭kt,u0l7=+¸m[u}vpy?_;vlP͚5Ά)ML&ɣ6]v0777 nk zzsڲe lll `cc#O8HR)ƍ)1~xC(U...,++K6DGG3KKKJJJXbb"dJ_;~8{ +**bc,fiiN<c̙3[n,''Al]Wg[UiꫳꖩU]cFW9~ڮ[{EDDȔܹ{1u۩n:ۨq٘]ׯg3fP1|}}ٮ]cWXxkY.t+,rM ._0ϰd oή_Ko0OމEZZL(2SSS9r~z'N4xщN,to߾}]vӓ_9sI$:#Gdϟ)f666^ mڴaj2x`gŋ2uݻLMMnlXt 'S͆t3KKK'ON:SNnݺ .ȍl4QU}u:۩L}8TE ]NinE~m#G(4=Pg5=.]V"0vYq+++Y߾}YEEc2+++VYYq,e-³'zu^h|уNQ{!v ̯O"`ڴiĒ%K:3gDII @M'q&&&裏K1n8pss_9sGHNN뤦bРA000>`ee[n)=g888`رcOMMaoo/󷙙ի8׮]eʜqUՕwww8˴˗crWg[UiꫳNe͝6.]ݻw{׃FM˺]V__6l9sAxꊋرc! 8cKWKSkO??VL8uv;~ގ֭[gb ɓ1j(dgg A UUU(..槲2-s&ԿFT /2SSSL2?.^ ̘1_ZZlH$TWWC*1Vpp0ѽ{w8p}ڵk J㩛]OY:u*lmmq%TUUAǍ7uo4QU}u:۩ Ϛ}7F˖-;vvOOOXSLFM˺!C`ooM65?モ {nRj?+65^!U,F?{GXwW,Cjj* j~!0QpuƤNބ,}]0111J100 ,={K*agg'N(Nꐗbk8yLYRR̰જ?~~~ԩ p9O?saƍWK_۪*MrTU_j;˵tuMW9i:ź?#5^u@~guQRWˮXkَ֬C$XsGqq1D"߿v,yT}FgB]_[ *%gݻ*vcu.] ???eeeHLLĘ1c:;wƱcd5j=2ȑ#ѣ\СC(--EFF uP\u{;w.D"JKK!닅 v'O %%gݺu SNݻ(L6 VU9hGU)tեݺIׁ.=h 0o Szw\ĉx5=.j̲о}{|X`_77۶m 777DDDKUǼ"zw``2B]fŚw޾}/&EBԝry[^y& Y=W_}dD"Zn̈́B!sqqaǎݻuڕÙ!k׮?~>ܥT1 LB|>'-Cm͝yG\l ]]P]] &B{Hk!J<rc^JCoB!iDEF?;;WWW1qXyqzȃ ^{v#B!ԜK4*u%B!imLB! f!B!DSu#u+>TB!0kZ"i28=#/[>yV_*ayqO;VS{CMxs,/tl!)) Ç)D(..n$ Əe˖ũSl2Ă^/Bުr|?JZ]D!M- +VhPb Ȕݸq0551ƏQ֮]CCC 6Ea`dd-Z&MH$xq֮] +++SNYfffxZ1`˖-@ nݪ4 033C˖-1`DFFԉ ѽ{wB[ub0445o߮rSa˖-ѣwYfu]'qشiu놖-[gϞ/[[[j o233e(ZضmL0(//[I[R[:8NRGQŞ>W݉Bĉ4L,#;;&L9sݻs:uꄯ ?x{O ի\t R~)??<<-v)8}4R)sNeكcW_U+}PbXY IDAT"44˖-Á7qD899x16mڄ~i|ذa>|xXrxԏٳd|۷oABBFڽ{7:B=Gƶm 2s+;>UQP(tRg"00111 2qTWymzi{u5!Dϰdp9]NKcWR՞"v{M[6N`~V=dEY{AA>+尼ܻ,v7;e߹rrYĎp 1~W^^^,22R<ҲAxLٽ{)P(dm]L,D"֫W/&JÇTc2۷O,:: :Tanmڴa 9?^,;;Ef{QNuVmbcce۷ >\`׮]~2s|ɓ'YNةSXn؅ U_SisU߶櫻U yujӕb&iiiXjP"իWL\v eeefff8S^o333[&oNչ-Gz>|8Zn{-0̵kQqvvիW.3g888`رcGvLMMŠA```}}} nݒO:99=|p\|YuٓW^[VTTβNNN/_ȍjʣism֫XPͭPZޥ EyWƪU/ԩSakkK. VJmmmenŪǪUܖ5g`$&&{8p郵kKKK DjHR0:߶w *;Twقƍ گJsWe!+xxx… HII:ϟ:u;wNf4i[u@vv6Μ9D?^N^<)) {V^;;;,X{AJJ .]0`bbbTI};;;8qB|uKmPN߾}5ZTY駟p9lܸ c)ۯj+u\j{mgBjOonabAyQpd$''+V[nœ'Oٳgܹ3;TѺ?3c̘1D())D"AAAݫ6|}}1e 4./1w\D"B$ .TgԨQ8z(PZZ#GGK(,,DYY1fԩ7Bii)2220eKmO$SnGjmeT.{-L:w0m4jگj+u\j{mgEVrBj=̎Ѫv^]&m;oK$vvyvb:oZŋ#s,$$Df޽{Y׮]>_h+++ٚ5k؀XVX-XΝԩSYJJr&y4ɧ|!/&cmڴuޝݻPqÙ!k׮?~=HYk`R)=owAO_p/T1>"wi^o;v4w*/QN`A*V^ p3FOR^73g",g>}Сƌ9s>A6mԌdamm CCChٳ={61tP>}}:v7|#h!77_}>ܩByyu-_o=?bgL%,ϗ?^^^C֮]tLeJ__1) ={AAA2ennnM2 !D6ݣ6U!.OcT*Enn.V#F(~XZn3gO>K9C2e:t@~~~3eD!BkO%uBNml#f>u۴iOOOعs'ƏLXYYaذaNB!Z?xՒӝ7q+:Fu7|%%%8|0g5wjB!9ÁC}Fbσa?5ΟCy=)ŋ1WzM25=_˃X,Fnn.X,FzzzR'r 26mva޼yزe =ÂB!(eԌsUxyMk!5U CCCX[[0Ceh XYY!33|̼@jў<<<; B!Q\r6lC [W)B!BИX4lj'0`lݺ!B!MOn|" 5F=!B!M鉅n : B!E'o3]\ B!B!BHǩF!B!r<=h IuF!ѷIYfaɸrJsB!/FXTK$M'0x`îT*ŶmXZZbĉ8~LlB5:QQQd#Rm->tReߧȳ@4"$%%a2"2eǏqFѲeKԩSXl\]]2} Eee%u]l۶ aaahٲb_駟0rH&U8] >S{q7fDG9`Ŋ N,VX||ن ТE ݻW51i$󈍍Ųeːsss`ƌ-[`ժUs:w b̙|qFZ 999ٳ'lق |{.ptUenܸŋĉH$1bBCCѮ];>fDDV^W֭[SSS>߰0";;֘?F%ܠ_~Cuu5~GDGGѣG޽;|}}e:uN}v\rXp!{DFFk׮Xz5+WDRRC߾}`bbb{nt = 88bo6f̘x'~zdeeA(gϞ3gQC١011iT~G9sɓ'okMB4qD"--' &ȜX#44T9a 3l2b߾} Dxx8^u?},,,{qvލC=z4˗͝;zOOO[ *++ [nc~o,X~)vDze?cp>q٠Ü9seP(DZZbbb#FZuPVVǏ/))) Eqq1,--T8pׯ_9F> o߆#:vŋk֬ݻA۶m1j( Fnn.7W_Çqq7*V}7oB4>!fT(-obi4B˗e˗/G@@@e^~yAAA `cc;vW^~hӦ \]]+V E^`dd [l);uTpqqP(1p;w+бcG] !!!>|8kfC^^:@ׯ'111(--ŤI J_ZurppG[yΜ9g"66p)~Wܿ.]BNNb}vpy?PsPǎ[,GFZZn߾;wwUF8:@ `ƍ EEk7bΜ9'aXAϱ 4OOO\zĵkJE_FpOHMMU7ڵk nrvvիWez+-deefff8 :mffBt899ԩ} XXX 3f@ee% .1cر|HRN]ӧO ĠAd:߻wPXXQFVVV?|]WWW̚5 ȀL"w[{={qqq֭Eaĉ9s&nܸ'''O>iP7!!>QE(--ҥK5O!Ҩ> ===a`_I-oʔ~B(j\}֯*'M:u* C"4ȿtuGF^^OŋUV|Q^^V-Zj%JqA"]tAtt4233!7 aݫ۷WzBxx8֭[X7n ::شi8 BXXZnݠ͛7abb"w2ď@nn.TB?)\p)))pww[gҤIr; 7N8pk'eGKJJB޽u*ϟ:u;wN#JJJ(D"1bl޼gkk A~~>~`nnm۪UGOD"rJ4 P()q7RRRPZZcTC"//rΝ HRD"b…ZS[غu+{rvvFHHpUt_5?ǽ{レ,X[[_fD}v`ѢEOz41j(cԩɁ5/^Iʓ'O/^n``}}}DFFbHII }}}ߞSGnnn;v,bccbر9rL+V %%7o k.>|_|[`bbb~hZERB,Yrxxx୷Bee*jO***۽QŨ۟Bfn3i5xR#Gh1IRbܺu ۷oܖ2X<_z`R)I`d z%C{1/喝GZTVVR)]abbKKKz;!ﮎj0 N+?/w9@?;t耂ɓ'cǎf?~~~~?!D-VVVjtM>,O,,,[!󶖏SI͛-y&L5k5ܹZ#-[t%B!/gyt._Je˗ Ο?///^/"229ХKhp5HggNB!@XK}1GѱALMMU9 ٹs'"##Q]] 2)rsssr&B!Nm ƠP2G,8֭[̙38pWߚ5k SSSL6 B!BynŪcjwnӦ <==\r 233aeeaÆݺu+ϟP{ B!B#6#,UKO}o`ܶ _V<3fDDD 660a|6mڄYf5ΕBH QfɓqʕNB^x:bGr2<'|]"Æ CϞ=qu_mP!!!Oкuk:tR&40x`îT*ŶmXZZbĉ8~LlB5:QQQ't0*cLY7L@MymEOwlll0p@~/7&&&011G}Ԙ !MIII E"e$ ƍ 88wEYYN>cbٲeM6yɅ_~A߾}޽%K[n(//_ܹ3;M4rTeS:M25iP\\OeeeZLT84F@@VXѠ|Ŋ)۰aZh 6 FFFhѢ1i$D"󈍍ahhkkkl߾]f-[`cc@lݺUf>qشiu놖-[gϞ/[[[j o? ܸq0551Əܵkahhsssx{{P&߰0t=z-[4j/X //SPPoCBB {{{? :uN ///$%%aʔ)0`!Jj* 8Yr%ƌGGG888iiixyy/˂xfggc„ 2p<8̞=pvvF~~>-[ڷo_ϟG} {|ݻwСCD`` F ;;;esGfOOO[ *++JD'((?x `Ok.5-[ ^8N>// @CCCQ\\ KKK 55ann#F>۷舎;b0115k{Eqq1|||жm[5 ۷/rss^J6^}U<|ǏG|||b5u͛7 B!^W[*lذGFff&\\\d[Ayy! ˗/˖oU IDAT/_ɾ]~yAAA `cc;vW^~hӦ \]]JKhh(z###,\EEEزeL٩SX, B!#Gܹs'\]]add;bڵHHHw addggg/\]]<:tׯ_OcbbPZZI&A*/Gaȑ3gٳNX미>.]ňa8 涛;6XX,FEEF4ܾ}wᆱq:t@ ƍԍV_98?wppht|u|2dƍ3gNoL|B濹ַJޭQߏx 0-'^Ldffڵku)zf(HMM׮]k0ꜳ3^*SֳgOW^yEnYo]5]&++ 033q066n^o333[$SGިzʮR XXX 3f@ee% .1cر̉bTUUUӧĄ9p@ 4H{5jlmmaee/rss5k 777L2E!..={;Э[7-ĉ1sLܸqNNNHMM'|ҠnBBB}!cի/ik׮EHH.]R,]M|BnR۵XB^>zzzիܓ[[[7ߔ)퉅P(j_UN.3uT 4!!!077D"iM]XRRѣG#//ӧOŋrЪU+nm(//WN-yjNh]v Jr H.] ::H$2^h߾իñn:bܸqHMMŦM.q/_?4hкun޼ T (//ǟ,:GDD 77Wol|BHsk[ԡG'xxx… HII:&MBppmgg'N(kɓ2eIIIrN:Ν8F~̥D"1bl޼gkk A~~>~`nnm۪UGOD"rJ~._@B",,La*x{{#%% F)СCCCCu4jTԝ!8$''#99Y7}1fD"@"{z| |}}q!"##C涘cܹD(--H$/.\:ekk[ɓ'HIIjEaܹHJJٞ]9駟pQGo_|`ggDm駟Zuaaaxzz͛2u$ MJ,Y̜֭9%%% b&''wޘ?>6n܈Ç:u4@5֋Sz+2B| &L.]4W\ ƘLo:寫=Bif ذaϟk׮ :t+w-y}쌐իر#k~ᅬ{YYŸPMeE`aahbԨQԩSkkk,^X'O_xɓ?}V60vXoرc1rH+V@JJ 1o<`׮]8|0LLLP\\/ѣ?1ܲ#X[[X:ʂT*E׮]uq}ҲٟSQQ'''ݻVVV͚6^ yQEEFû1S #azx.k Iuuc'򒰲RQ:i<6[~~~={ Eϟ\^ubQ]o B!4`0ooog/zԜXhٱdIՕ9V"By>EOTxQ׿Rfo{xI!B^Dy@vǂB![4dA9 !BcuݼBiJ=|d֬Y!䥣LۨJUTT"2eƍÁw OرclٲJBCC/o߾|]wŒ%KЭ[7S:֯_ tǎi!>!/ bAiXbE+V @lÆ hѢbbb0l0EƤI #66!}v[l llluVaӦM֭Zl ;;;={ lmmѪU+[l27n܀LMMall21wGGG(,,7,, ݻw@ @=eK,˫됐8;;ǏopNS III2e  `HRZ 'eV\1cFZZ??&&^^^/`xyy=>>ĉ7n0dL6 .\Шy!3334:ę3g~ gY!>!/ϰdv<6KOijO;Y^]-dq`_ts@hq0f?+}\Q!{T=|p=xP䳂{y^^a9wYNN6}Aݛb<55ӇUWW3|yٹsڎ˩Y؁Ǐ_żҒ%&&,--YllصkǏ… {뭷d;~8{ +**bL޽{Dc>Cu9ºtD"{1;qܹs6SֆCf1bcYfeB`zzzرc| unݚ`۷YÆ ޽;k׮߿?1g1c֥Kܹ?~`&&&,''1Ƙ1=ʲX˖-q_~ښq֮]}4ȾK{ۗ=z1Xii)355_w?=],fOkrNp9-|y%3bAȿTAA:Çc HFFFpvv5j3WWW!//@ q @ii)&MT/ԪS=z#GΜ9g"66p)~Wܿ.]BNNb}vpy?PsJǎ[,GFZZn߾;wwUF8:@ `ƍ EEqcwFǯUwBn=mj˗/W@6n܈9s[iLZG yywq; !k}S{ݧzݨuzzzիDff&]Oφd eǮT*5 >\W^)ٳ'+"Qdeefff8 :mff&s+Tzz:d>@Œ3PYY@xyy… `};v,0}t5ҫԪSabb(8p  $޽{B5 BFF 77YfpssÔ)Snk=qгgO#..ݺuS>h"L83gč7T|' &$$4'>W^믿ЦM]!!!tRj׮c'`۶mri_Fii).]vlMGi'e9-\QNVrdke˖!88Xoa!===a`_I-oʔ׾h{b! Z>yWL: BHH!H_JO}N4QRRѣG#//ӧOŋrЪU+nm(//WN-yjNhtIR\rnnnH$pwwG.]LH$uNo^v Xnb1nܸhbӦM 8˗/ 4aaahݺuz7oބyB?DBBtɁ1tPW}"""rUڧ yq3ܬvk(7'2z})쬃 !.\@JJ ֙4iun;;;8qB^{ 'O)KJJjm?~~~ԩ p9c׻}M\H$xxx ==#F͛yRRRh۶ZuqiH$!** +WAz/_F`` B!LMMx1퍔"$$'** CE^^ 9x_ B<~sƍ垔6&ӧ1n8^ZIEc+k͛7;󸚳n{De/kIh%%k(KDecM%L"T4E[#3|<>=}ޟy9Yrr/n@_B#5TYJȱlUhY) Abb">5k޿A!>>>|@YYrrrp!ϽtRĉrx??? >>\.>XYYa۶m(**BRR\+.]OU$9ٹs'Ξ= x'''̝;FYY///W3gV2㞖%KϞ=)++QRRe˖aݺuI&ÇB:Ѿ}{aӦM8y$ym P:P1{lrqqqIBSSK.ѲeKꏌq!tFFF /?k֬!D ᅲ() ;vA~{4mj ̜:.e5)o5559s6lPZZMٙyGԍNNNG`` @YY=z4C(++ˋyzFF\]]Ǐ~'0y}HJJ ̙۷'OܹsʤYZZbڵbԄ3fٲe# GGG@]]wҊ^lDqq1L"x033ʫ~iYp!EGqQ~IQ gH $W'L)Sй >|(˗re0VĀi/>$SND á)σk gj=b5krB6"e$`艱MFF޽{333-#+x077W>Fnn.`bbR 2?hr.6Re_ 0DŽpuΞ;s0mHZllEP( BP {c1zH @rr 4hKK Z>NNXy@JP( BP(uju,* }&v BP(7IP(_ B6t8L2Gk Bz͛ѪU+ׯ_Ǟ={`ee /^VǏcذahܸ1tuu1dyF@}ХKhhhxQQQhݺ5`iiH_~EXbprr "ԁd#3n8/tƌ;;;=ݑHk֬AХKwe;_~se҂/0~i_o/^ѣƏ[n3QAAA044^uRظq#]T8pSNUnBypx% @PP޽ kkk7>|8F޽U qqq:u*n '''dggc8q"ȑ# ݻw͛;v,O?1zߏ'NAAA8p qq&rqwwǺug`ѢEX`@GgŊ>3gľ}T4/_v킝nݺc }kDGG yf:+{.;3gΠo߾J&&&prssoɓ'HJJBvv6}֭x=LLLdѣG022B߾}1k,?ҥ 5k BOOk׮:t߿tttₒt^ K,#//.\ӧꗍ-[ !!zzzD~~>_)BѡP FPRR’%Kj*&mժUXd =z:uR +V@xx8\]] L~HH""" mmm8;;#<<\M֭[Ѷm[hiiaGdd@ڕ+WU&%%}􁦦&tuub :uJ@ ggghiiYf Ù3g+W"<<{~z|ׯ_8qpG1cǎbԨQx7o-޽{~]ׯ+Wŝ;w:8v@KK ;v9s0yd>5k&tc{.|?D`ѢEMBMM 6mC>}x?>}$SAAֶTKX? 4l .K{7 6mj%W IDAT7kl_|$_%_)>XtP(owww}ӧc"%]D^^\]]0lap\믬uyayuPGPeeBsBh"+++ܽ{]vH۱Ԕ\UD_M7nupLozm>|kL0 .A Y#+UUU&q*:4@ WUx<߿WWWaСhٲ%>/^oSbٶm[޽֭CJJ ?~Ç#997o[`ժUnݺ!** 6{DICSS?~Çq)Tnn.EgϞ ӿ`رڵу*B?ݻ^Y_k?Ÿ] ._,s)) 6lBBBTLŨQG*ָx"*2]v|21i.]Bjn޼Xhii$+:uBBBQ+sI Æ Cjj*-[0yVVV,dggIII###谒W ֈcKU޽{ &4h(xxx~---'<=='l۶ >>>VɉAϞ= 2\Èۂ,^ޥHW^ŬYk.tA}u-[ǏK7 //BȿuC$qA|8Zl)RF^شibccѢE | ~KKK$%%K.x N:'O`ʕ /k֬6fϞqLEEEBTΛP(_5559s6lPZZMٙyG[Q7NNNG`` |eeexyy1O?ȃ+pqopssC~&^III9s}ɓ;wRzzzx=BCC4KKKf)QhjjBMMl2|Æ #JJJ;ip/6hjjSLHW~~< )B͛1uTD2J.x'9dGi4x Eݢ#&z?:}^ %9mDINHOc) {fffՕ[FV`nn}\Ĥww/..:SSZ[%~E#Q[9{cAP( Jb##+Vccc˭:u*%)ЎBP(uO> )AOGr5[QKR('OT|!_V9B(?ž*>W͡>x«ؘ0iyU$>9s...BӦMqF=zR(0~LMMMLL0jZBP(CE_ZC l ccc^-LN:bi:!Ə?(P)b m滎֢E BP >+)J߱c1~ܸj|2BBB-Vfҥ0aBCPD2PUQEok BP(_7T{/%q˗hڴ)tHʑӧԩS)n:{ϯ E,akCef) BP!Aqa 03kX7cQz^~ wwwٳ&& 44ǎéSXuT( BP(Jyv124Daee uuuXYYbm8rrpssիakk+R?@LL РAXKP( BP!j <>A;ƏA?w6n܈ӧOC[[[v#) BP(C*o'79&N “'O7ss$'ӧ-vaÆƍhԨ@~~~~LP(%%Jrš eCt"BP(pܣwh%^[INfQ(mgwS0sL [CP( *1ښ|yy9!HIN;/ 𖣅 r埼- ) BP(JjBaXP( BP(o E EP( BP-G7 BP( En /юBP( B6 :BP( BM*6GxElضh& 0D(,,ě75d"&MP &k BP(uC^nvϝ j38|}o-?ѶF"^ffBڽf PXp]ddfĤMP( Rܱ},Գ7EGGR`ɐnXB2挢Pdm38HVYF<}F_ߒ=3g"33su~}5}|nO'o'g!DQ\\,rahh~.]`BBNY?8IǏ) CCCbpSSS())IEVlݺ>o]V%%%=lbjR:lIoD0k\Qm'Om޼Z:quٳVVVhР md1>ZnA*\>)$sH*:/Xy%9>|AɎť{/{T"Da@Eߠ>,8r EdVT5-;/և;; EqqqpssQFիT>wpp(ӻwoldd!--M֭TTT %%%猌-ZZ vvvm`Mii>c[ooobԩ?ڶm+-;K@wۘZǪTβƯvRoġ'ڴi|nԨȴ|滴6asGQzݻ|Ϝ9ۣYf7orss|Ϟ=C߾}WBQ $$H_|9=z|,XnnnL_׫WDGGÃɟ?>:uJ4;rαhڴ֮߀歠>FFawNtS#t{ s+swNtb S#tb=w -S&훷g0n(t!;CBvڅ+W ݿ?3WGe| čS3n8XYYΝ;(--ǏQ^^.U~wڽr\ddd ˋ"t(++RV.l|Ʀ.8l]>TX[[DRR~W엷*ӱcG\rE իڎvbQ1,ggҐ&l3ycLގ;2emk>7oRRRl6"''G4~ & ==I>|8zꅴ4{ڡsեoy",ϋ7Wnݡݻco+V@Fԍ;X"{D нgO# v,6lF= CC,7\xy9A[G**;dXСPJw^BGGG ]GGػw/K.">>ld*ӢE ;wNC??? >>^@emۆ"$%%aԩʩcƌ?+{n}8< 7n[[[`̪3|!M'[dm@Ϥե2...8{, rq)XZZdWy (,,DBB|||dڎډoDŰk lNq& im:7fΜ)wL,m///Ġpttd]\\}vdffm7UUU9r8yPر{{{Xxxx ,, <\.Wh:6>;CQ$^Urސ92$%ȼGDCC{D@DOLU=tu݇t ȿʖgLOFy%k7d{Nަ||-mllٳgE={Bپ};iٲ%QUU%d˖-BT|!bnnN6oLZnMTTTH֭֭[ʋJ}6ҥ QSS#-Z 'hiilL||<ӧiذ!$}!Ν#ښ]V@~ݤsΤP/$锥kʈTGzM444H&MȐ!CŞWM$][l!fff֭[Gd엨3eN|#*]j;Eę4imBLSdǎBrľLTUUIÆ ɐ!CǏ|6oLt?|0133#Ņ W-_;vF /G%{T"ao&(G?#(u}"x5*w3o,^_77FJ#22߿Ss!#"+[@OѻH~HQr|<Ƶ+ 9{&N"SUw_8:Vd~•s$.ǣ ..^@Kss6Bjp8ªU`bbRP@~0b`7nΝ[f}[~Km'+0|pp8]@uIDAT8rHm$ p8kYmYPlXÐ CC0pDIӧc\deeiӦ;{32b~ xOFm 9X8BG1m G\=ǎæHI b2ן$~7 BZZ:;v,Ǝ[f-~lu%DUOgsh6-A%ByUy # Q /Ki:ʋJwHWP( BC>w, EО6tW) BP(箄Jҩ zQCP( BP/9gnP}BP( ;rxcQ _ BP(BaOrTr()+LAoTTTP+Gf:be4A(١1JP( E<2hbZo+(+Aem jptr9(\x k BP(uN7,<ƾvo"u"mtl6Zmg,VԤ9223q8侩A(41h01iVۦP( BCʫBɻA޸+$ S.mԮ! BP(T*:tS B(GT`7ڢ.5Q_/u޺iV\˗/9deeն))TkY BP2w\DGGG5z^"^JQmV[qYWٳgj VZ hޜ.Ln BoDFFjjjm9`jj %%ѣCSSS ---l{Lv4k&~;a&MnݒI]AII!nGa7C.]###xzz۷e?{{{hhh ;vUٗ&S <PWW6l7n ]]] 2o.!^l(njjjDddPY[nNi_[[[hhhu o7oFVkkk\~{쁕4hGGGxB/2lb2ǬYpY={ĕ+WoooaܹLge߽{sK0p@tUbLWÇw+Yy?>O׵ +WDѥK;_fڵ Vb}cƌAJJSM\Q^q\(Cyyue%=( .ra֭x-n݊˗#66V@.66W^СCtR{߇ 䊊R*@B޼y???L:M$R.>^bBBBܹs<3gd0uT,[ o޼q%un 888ѣG(((͛qrww7233K4o ,`U/6ӧ|rܹyyyضmV\Y믿]v!//۷oGppX}Lڹ^ŋcÆ ӧ5kְ:~~8qo߾1p@l߾ǏGNNz˗w^lٲ>>>h޼9/SNƍqYFB0yd899a(..|=$uqUNuDvv6f̘ f}wXt)^xR :ZZZvݿ%W/=*<. ۮ/33QXXHET,1i,SVIgϞ?̤9rr ')))M6;Ԭ28p nݺCCCc͚5hР@__޽*WFXs. ###23gę3g=z`…ӧSñzj ::PaELL ͱ~mۖAGJKKѼys5 qqqHMM鯪ōppm2999h߾=sѣG̙3Æ cuުilA:::xL+ȇСCddd|ywO?Ĕ9z(,&#͛WWWF&66nnnb;Lڹ`32ӧcʥKiii5; jՊ^T5f2}t$%%PRRBbb"usΡo߾xzzbɘ>}:ؔ)SpmPVVFqq1444+4mT9\rfu8vBǎE͝;Ϟ=ѣGkU._ٳgLá'N?[ &z?\ ByyyPPã>%Jʈ?wxP[6QVV۷3?f())3gxO $''YnlAްСCѣG_Wzz:̙YKZ :hҤ 'Sݪ"jؙBMMj-ƈ#pib֬YXx1fϞ-R~ܸq֭add2H]9噘-M{uv.. OFȺ\Jjj*;{{>}N:1τk׮۴i#3rJ̛7@E'޽{|+++],ٳgLd^zz.Y뚗]bȐ!Xl4i]^7n@yy9z===Ϙנ:| L?xY字 F kě7oz|#!N4k֮];u/]˭ggg'Ԕzo*/;a3ÇG^|EQM4'ĀXqBt!kkk\xQl +2")) Xٛ7o"00͛7 nܸ!KRSN:!!!ALuر#3-im&;;;;vLr!5 -f*.v1immm ==|zz:ʋ-[DΝѹsgXXX@SS޹sgf%PӧObqr|A୉u +++\rTm>o>?Lz兘#66L oߎL?8rJKKqIN9s?YYYgdrPl7007SSSmV`4 ٳgիW(,,ŋ)S`ҥʼn'rSߜ-Zܹsb@Q₳gϢ\.NXy+++l۶ EEEHJJ/^W@@|||p%2a޼yABB u6ǯ@޽o߾Eaa!Ο?A֡x`׀̽{`ii)0)55Uf :0ydlٲEann.2tuuZע"Ǐ(..ƌ33&ӧpwwGTTF| *TUTri%p*-46Ƃ F -G&Mw^s/*#yxxQFؾ}@ǡҨ;vdGFFbĉG@@sS)VBvv64i^z LVec9aeeKQ@DDѹsgcΜ9 d]ƍprrbwL6 jjj"(*fΜ+VI&077ǹs$EڱcO4jC id|yEaܸqǤIpBPWWW̟?hԨ&L___C 8Çc033VX9s֡x`׀̽{7ە@T}Q(ڢsx%]ֺzxx###4m-[Pv-??󃛛 00v8g}$lm(֮ "+V7>) =+W9nW.ҰaC${vEWO4B][". S(ruL0AaQ-BCCq]9`PRRO SsBqNI 7To~r*XT`A__puuʼn'j6QOkۆ?G۶mm" ޿kذPII@-^J݆"""BP, E^<=="$&&bԩ0aBmEJ3f >}Z jjjh߾7שy*.Wk^Pqq1KKKc7Zj?" Dnď?xXSU_#}]y(?ll:#1"##kˏ8{ ~Ex{{#rT&(uÇhذ!FQo&#RÈ#saҤI՞Av100nQs,jqGD4i6ʪ TTT~}O0j'ZD&9rrs[H[GгUk xM7o ﯸpp&h׾vC(G^hb`N6Xz JJJ|3qI ׭Gfͱq*[aCD"<sgºЫ_Y;2;rr'9E7Ǣmƾ ,Z_7JVVV(סCM7F^^v=KRSSͤ* $P]u=A\iz;:b˖-8y$\]]kƚm,2ю?LBr ‡wm1Bq\֭Z;{r3f+Whnb*P/G0%~D_p\MIXU?%šPZᣇֵPÇihen.PΝms" 6&ͭ1XłգvF„?+NQ(y_(*#~&>0[Py`GD`]ܹ?a&2&& X/qu䧷o W>'1vXU_ru9᧟ܰ~}8Opb]v8|QXGפ5X 聬Z7u@r "R߉B@k隨Vu))!5{6Msss}DRRoߎ}Zn={`O<~~ؽItook{nAڵIC]]IIIز%{)<aq7YcAMA?a֬Y dff"|#Dt9 BaaԃBZI@2# 2HDڹ&7Ǣ]PSUᘃذqOtîKLb^9s[P 1}T.Z,xbOޭ~ +ccYL~=c;B֮E@xеǬs6TLmy"->tAM]sƜ9vwO?~<*+SdE9kn8xX;ĝ.aaW]yƲeKlRuvFHH,$*  .a( =~#Z)5G=u}{JMͷƂ"6*/B}^AB& kEo玄~[.%*Xȩ'DopX41ov a_{H(23pm RMؼMPVDF&&&+򷳦 lGG+QDCXcAc*ļy3{}EPTwMq=4a'jn^*)}Rճ7}x_@) дz(Qp#Bv&mIYڤI[l&jgL,mU(\" ㋢W;;;"cz(H4XTݧΙz&J/,8`J2N]b9 xjj(2S0P?4wWWboU(,Znk*ɲLvG6 ca5 R^U*7/6~GsKgXd=yٿܼ'r888П$Q*k^E5ݽsvWd,|}=WAᶙLm]o{y,Vy4Ͱ  ^D`yt8Ir1(.#Hdê.@Q&i ((ala+8sJӴmr 4:acc1 ~ ' aާP?A&݋UhmnpMu~~jIN{?(5)IENDB`mathgl-2.4.4/website/udav/udav_prop.png0000644000175000017500000015526313513030041020267 0ustar alastairalastairPNG  IHDRoyesBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwXTGۇ] A4%hݨ%{ƚKhlXbFT@6,, RgsΜ9sddcRl R=J 7 2D5Le2Z[c,sC@ ˗u׆2xidB2qIiȑ[@ 41rc[2)tm$3(c@=8E$IHL&C&i \)6Mm,RF+;l>/W /1B}L LLx2R$%%d& 5-$\.:P@ БlST2掔kcql \#!"'! %Ƒ*(H)<҈OͽNNd2J # I }bbb/h{oo{Pml[9Ħ0V(ZD.O8#9k!-[']a" DRSS}GF061!%5{i2vxYYsylm055jXe~dbcc+:vqFx>_%==ccc~YFEPp0șN9޺}qꊟߢ;LLMMqqq[׮tԱΨαxPm ed(Jm=\3LM13 'ix f05 ryN'P(G]$ HMI!55#%$d2$"2B`|?ޞKiL{qӱ$==cǏ> #Gh{pFx>+P ~ʗ/ϒKs-8yGSS~oOO>?zWZy,SyYlXV&K%ƑajqN.%,HO,5I#)M$S$)s\|<gڴTLLͰ'.>WݛבdXYa$%&qAjU۫I_L&c… <:DLFV033׷/e˖U协' sss|||HOM)PLLL?awѭkW࿑]|-[$IpsgO_LcFbx NNًm}ul{d2V'LFrSV8]}׵gϞ \zXʖ-'}.yGS͚1g<֭[iӘ;o^l}M Ӕ)ȍ|w!I-aH-'i)I4&&O8v\ALɘ=&&O06%2Yj'T*yFIN'55E둜@ 'O̗<:M%rY*r^bdʕCqw޽̙cl c% @p q/055%9)TS$$cnfN81E+ȁ5j_Mу|CvU*t u߻v놲5 @Ŋr4uv6V{W5:ݶ}$q&%ϘoA$ؙ QQc`-[P((Rxˆ#ر7>e]˺>&=_LJM[jM&65!>oixS|lo޼1G"6VUYzRS^.Y پ}'6l,-ʘy6/3Nyvle8P"! 'ƍ/3eA&M¿.Y5KD&KA&K"cm.SiH@jJ2i9GǏGo$JZ)S2ccc9}4ʗ˓Ą{{S|yN>͵:UV%n޼7n$$$URí: }qO~DEEjjz#ƺ,)٦@7C&--M޽{9ldMggc@HH*>3χ￟#ǏuIWt-#F`ffFŊ[׃~^ef˗`ivG"uiS53z4Ə)?0w<ϋl9rWvzVZ|SC eY7i®;hۮrDL3IfI/ή))tM4^V4kz#Irdvd$HOKC/]{IKr)))}%A@.T*Q(3WcgkŽ;Fzz:OҮ]y;ORb"!,#xxxF|#S_2;Z3SSTimË1j93ئ$~Xf_hZ})]œ'O&88`fϚw{U6D=}jWӦf26Wa 7W7W~ݰȧd;=55SZUܿ36o}l[$-[.s5#G um =])CLs)K=о66ܾ_{S}lm̑$\-c^Ɯ'OceU4[7O651'1Xk?/(ATpq!<,\\\T\*Vj#s>^-:tLTgxXm۴毿~d2ڷm'O䣏zpIh׮-HyC~/y$2cI|3bu瑝:\xԪU oQnҽU-U|=OOΟ;ݿѼY3kI&i ώe)Ә8i"eINI=rDwAtC1.ڦjBڃTV eEj[3k{o37 \.gDEEͺ 4(G6l8&&&]wNTTGcܸ: GLkYO`o;t1\Ay֦:ېW/b .׮G<+a}5_Crum{{{mNRxtgl۾-[˶uWU x|48::`iiFRR>%ije56. #e:vʵ@x[YkQtA3gټq#11 j֪EzӢy3?77011Ύ:o//"gܯ=g.'Odԭsӂn3axZn͸p?^-JXx15W+suY-KHhq $N:5U+fc]09z4'1!#] ^%t?Ο'!![[[4h@z`էk7o`ȧpO4SmlR WEN269c$OD&ϸ,)MQ(-P*8r,.bee_;iBZ'˗Q| f<}Z[V.ĪY@Gvo٦鶳v:$c J 4d2 !IH dL66V֦Z;L RE,--x)QrHX,+F@PL3 C@ $Rti^zs^x- {ӼYӂ(rq͜EDD])bAID)Izu$$$G}_Z 2ާi;cҷѵK}7ΞB  6нOO|3o> ֵ+a'@PGRb"3gΤaÆS|yuUir[R&/Wv---sӫ~^1hZ[7cgk d"XiAx{y#!MIIkwqwwgïJRRΟg劕t%xP4nT(Ѧ̰=} ʽaf~G!4-eMrJ gǷ*.L.s{}w&t܅vQBdϫй ^ ӥ{lڲ5u׮1Y/u#YO?i27n,TADjǎ;1rDy6'sDJcǪ_> П۷nru*TƁ`˗-%A0`g6ms!A0~ə3,[1>!y d߾̙;E yߢ̚=ov:Hʗ/gN.]([RV3?U\u0n,kׯWKéR2eʔqL8_6l,PW]LjN찷n]jPV][$> MQXPP5jhe=VXO+ʔٹӦO4'OeKLM([֊ɓ's|[Yh޼eXмy fϚ̙Xx1M7̜jժo16n/aV̚5實k5N_2:MPwh._ᗯ\][_F p={/G^o/OB>\u6m۴חnOx#Z=+eYE=L@LL{hh(ק5kժ/oߦiӦji6m7ر#N8:9Hzy0O~w-7W k٢w͗y]?}|RŠ@<}A*԰ƴ?}.rv>r@K4ּ|RWuٳs;8H|śSnܻwƍi+i^6lp5jqrrBPPReW7tBiD;M7t`Ni#Xs_[xYKKQwn\.{'ZX88#<&&GG"I otbgNӳ/_̨(W/8iO">>ӧO1id>,_VXt4H5Я/ü|^_Lf\td=zB>7}9e+Wg>bccIJJs 6<߶*WĉP,@/ ?@<t+A&&&ڹ ۯ?]hа!+V_h kٱs'5kѷo?jо=Ç eԬUQF1p@LLLTi|Zdݚl۶ Q -bAyn4{ΝW3b15;tȗ-ƏR*+_ 2i>ZwNݤ*Wvz._‹/Uc5oM[qf?ёA@(EOoUɝ;wY؟K/HO˓+ָSO3}lP(ZcYz5@ |9h m}}u:'C|%NP(EJx"|͉122bϮ]ist!FNl8`:M@ S_ž1rC~I*UscO!C5122={43VMD)el^iӒÆJŊի'+~gEG'^ &I2|¦sw" 54b@ 0Mz^c٫@ 1+ _\.'=]旌4kԭW##IaT*~:VzxG Aij*pY?׼YploWH ժU+j: @ i @#@ ҫ@GD)z5H 'HS yi CO^civ")[ A OcjjJ ݫ˧3o> ΡWQ"o,uiii͟OJOH ,_s:Mv?˳7Wӳ-:t0SWꘚbogGNet>FMN7VJ:ު#kxvft. n}V7} FMhߩ3ڭ}N:u}emW0# IDAT/6Nxx 4_Ox5lLOzr_RëS@ nҠ#2t ,ɓS-"#:crApg^ӦQ67nbD58q)SӤq#lJ>}=W1kTzxpM&LGGڶiÞ`PByƌG0)S weut)G傘}1h!0|HF36s5tr8177JLq nL8ƍbaaAƍ4~L5Qٿ__>A_LYHLLTZ%<Q. @PȘsCCiVLFjJ ʕSǷ2h*MMYpV`HJ%^^ 8@1it7i܈IƳߟ`r U|xMǏA4'}&{dU\~2ehԨ! 3OA+|"RFG)h9W2c g:NIÈrG6\͘; @2@ E~ˉk=M1@GD)dt@ ҆L, dtR\$A, _4CHHH :8:9beYJ*NH %AA`aaC QX+U/t$%AAMGлLO_Ӻ{5^H+BK@BhJHhUKsБ - t GH|A'&'Cxü0t/f/%Y0(nZ27iP ]uƠ'RYL$)6 #}+$JN};M)#A#M$K*Oo*ȳH_ C$$$ݒDiқNGAfqU\rr2عs'<ԔF1tPt.ZYWnс.d/%%%Kغu+Ӳ%C _=#RԤ˗/'0o4hPQW`;HHrZO)))t.l\]]IJJ\Ν:K3%\NjZ*7JjՈĉ̚=6mZHq/_kLKY 6+Vжo9(v렣HȎ@RBYd_#K,fZ`eeMرcZk֬{G_~-[6s4iڄq'l ӦMc9<fo;9xE~Λ7iS"8>'OT(;v,$y cT$)o_7o?(kBG]볰/*9+;s-'z8p:g0]_8x |RB؏ )*=-N2?/_ 7p~\Uy 5b۶mj޽.]:S[r $IɃر'O#IJ.]=*Gto ȑ#̞=K ybE̛?Md>ZwNU&Ea$)t6pi> e!W/v0(̈gTpq[晾s.|Wt}UҥK9O;{wwwbccqusVA>￧ʗǏ{?}84Q4oޜJyVZ|- E.mfZ_:;us~F͚5A4h###UZMd'ИNڭ#N:_Ewtl` :v$((cҨqc< F9SoߦiӦji6mfPZTP:hӺ57n9&h <$I< AR*Ui۶-HիF$9,]}6͚5S kѼy՛^U 4Y_nܻwO򴅿Ϝa䉏+D<}BdS"#$2Zz,ٵ7UiѲ%˖/+zԵ>bzuO1k ;Inh:l(H[Я?U\͹x"\rɓ&HDSn޼IMJ 4)MO~}9s&Pmj3ԬYS4b'OsƤM~6ߪ @hh(ڷgye:*/:җ׷-OZO*k[oEst|mUss}z0RY7>#wo@6knTΝ;O=Ze̜:̜9ƍfͦQF֮]3gԱZi |P3c!;$_/!ѣ{)rQzJ7/8iO">>ӧO1id>,_`3n7L1۶󌄄xNW^5XbEP(Ua>NBB/N:?7-5(AE%n_'(/2:gLPNJG O{ikkKz-\Nz;ܷ1:В EGлӴkԭW##6RJ%ׯ]:4BG]ZH:VZΟ;z; (beeM*sM#t$%AAr 67V!@HPp- 9 J yO@ tDt@ ao9MU7)F@ AgCHHH :*",KJL't$ІВ UGywyK:t=d@¨\I분"$(Hzw Q'>[w\ㅎ"$(H2=ޕR/ЁhUKsБ - t+^f= ;E+ҙ埘\@4ԑPɠj̠)@ }ZHR*4BFt &J~^3zv2h'η[ZZ+"ϒΝ;;v,*lݺoϟ$MV-6(/-+PWi%W]v{%3fӧ/_ݻ3iDeqqyFPJGYɬӔ,a֭bjjO˖ 2__|ox{{ۻW-,kR+keEÆ 9~r#'KFϑf洮A#M įT?1)N;;Sre=z ܥ3L2z$L%]G>ԴT6njժlj'5{6mڴΗͰp<ծ7JSTKYƺuׯo^/t喔"> %ӎ"?\\*tWw؄]YOX_چ5k]{Gyza&x+kՑ5k卽#^ެ[^-چm۶ҧNθ`ADG?S?={Q G'|Zfߊ^2I:*j qw)tޝ?CN55B¬mHHLO+֭E6Һ/ I~Zəz^̞=Դ⬥ԩSYp!QQ9ȯVZMz88:ѬYsΞ=[grtԙBȫ]7;y+Yf|׼ӵ+kVIq;vT!ʜ8q"Ϝ&>>ӧO1idF|*MŊ @Hm_2q$N>fӞIH'>>G@:*j HCݻwg{ 550N;wc9u$C Qך>|5b+W,n]֬^ň#y0qcalݶg$$sDz*1:*Z*(d_{{;Ɣ颡'vM-i*8K'i?=Ta3/cn]1Cpvvn]ٵs'fj=p\\\1mJw2nxQ(<}V^Νd1SREF:zfxXȏK.aiiIfybS///:}Ѭ]cǑK t-cU43MЮ}^|I55rC q 4]Ma |E_>  )4lЀɓ&ѷo?ukV3o&LRa9JY/6o٢tO~5-jIS9I_DѺsR&UOt Aʊ-aR&bddĞ]hRc|qQQhH\*Bc@H 3rdGb%_ut{Ij[1tȉ4RlX_BWtdKUK%ߒ' iJoId(CB ʯ!!E~%IuEx=BCS\РHtQ^ޛV A- H֖t C)大+5Б@.:҆ޝׯ]nADTrusM#t$%AAwYjBBB8,ϟ퀠bgg5UT5Б@.: IDAT҈DlnPZ5C БZ60?@ 4!T{֊@ tDt@ 4@ i @#;Im FBBQꔠt䈕eY*U-BGm- ]uWݤޏa^ƒ;kBp2 GaaT[BG]Zt ;̈́ڿQ(֭ػgwBG]Zt ;hZ4  В KG0hG xOQ0|A'&O, Oy!:E#i)y$hASR'UG4T@ A-5@K@h!$(4 %JI*oK="ϒ#]K$$$7ְq{JJeXﯗ?ŋԨQ+V5~]uUKKKGr IZJ9s& 6ޞӭ[7Z}=FR]M7h.[С_M};~aÆr ڶ-WL%YG^q/__YuoRRR]/ĹYb%;u,E9AGy!!樤Pa(Ym]z K KzȸzZF2ímQi֬Y7xzynyL?N6mT-}ptrg!55;wRf-lSՍgb~2I*JJS9Y祍Gpᮖ n:zӴ'GG.YB͚066ʚ;cU:mmSg%KVmmls|צ춶mNKV8:9VL-OnZ+j #M^MJCjkMIRٸiSrA> y$%eܹ-Zȃ -d8?˗a؏*>l ӦMc9<fo;9xE~pw۶mSk]t[["#]몸%k6mT֖7o IJ<fǎ'OT(;vNZ+)z2, RRR [n(=>}HIIU++7J gǧb֬Y,\䧖ou0۷m:/Ǚ3gxb4n9ժUgb6m܄R)1l0P(Uy6o,> RKv9MEm۶Q*%s?2CTJ:|vڽQ:zD :-`鸸T=/;lXV)cs9MαuZq8 AAzR(Cɴs!:w $accCM9tZYW{Ѣys-Zp]|mZƍ8p 7nбcGqtrё!$ѢE ,,,8x $ $IãH'?uUg9MEm۶% Iؿ?zHđ#G}tiIԨQ#n+&YkwdlB( 2޼e3d…jIt9GLJepM"5:ݑ;wO>%))=zv ʕ?:ud-߯ԋ.,:;.@@EE X0 D7T (H@ST[1*IMQD74~'W ޡnwvٹݝ21fh[eeOpGFa xܼycƌ~gnA?%mmRQ 3|cښmk׮(+{S~aa76:ի:4C AFF&ϲ :թG ) oMLLpBbLGHNNF}}wٺk4TUU"== ^ظa=~44h qADFÆmܽ?Q]]d,Z\V 0Jr^Z}OL+y(T8mwaIpؘPxxxf[6onB݋%)wa:,.AߥLۆ-0i8l6&Ml'LhU܎w- >$ΟPSS9V\M䷩y>@^zSUzA۴|رښ0iG°ds[997LMKLJs栾6tOTۯ~JF(_/_ƹspAyCYY1~XݎwtmiKڎіz#K{("vOPk#ͷœ'Ogۯw蠽SvP["!fCbANŜ`wK /ѳW// 8sMԖl0iG -'$'WH▵q8J ﭓc+-)z;G[z@G&Lڑ0 hy1-Y}p|I.]PWW6'|())]va&H@Mbljki# een$o'6"hki LC0Amv$Gp}\‹@^]v6a&H_ @%֚=FmB!4tBaӤLB!DyHBa:MB!NB!5tI!0iJ`hl*6W&bD:/0v"O^B-,rZUUzzaTvYu55F*,&ސݷf&R票BDdD Gw(Β*,4 /{TZ S7ZV, „ibK?x-0z-njŦxQ0'dQ)1wBZZc${y\Ʀ`02188̜csK8̜[m1LwbKbR_SKk8pDDd{d966 g ,iz6ZYKb*.~[bDXXN/B w] 4>wlp/_•Kg!T56Wd$!qpl [V|._d&c" 19gۤd|M,nv]ྈ%zOOd *"ygdt4~8LՕL&1nw9.;ܬ xK$i8,QDz>2w6VPWS&6o܈tyݳ6@]]xmGzfXbbc6ԩlx;2%U,_L~VЀ%y(IL1a*F7{ZBOW^6kWJK#8$yy($vС[YZMLbZp[{)035Q#!miJ~ӄ^>>016;twG]]̬lD)Ñ%iDRS[^RIL[7oŒӐĤ އ]l7)!/m;ݸիVgPVVFэ<땕Qf˼A 7/gYNn( GjbX淎moSB !gkgWWUcTp84g8Mގi4t!gOÆ_l^UiB/MN#iNB)Mlbh㑶7$CLj_ަ:!á(&ig%ܳ׮]SPxgm]=}a%K~Hɓ裏dbBFzbm~pѳbI7g:uD_߽͗{gF= ?~'}}}()ۼ9CUUFTTT4gϞ%a``h?}wΝ;cΜ9xL/annuuuK.nΞ= 333cРA@]]X && * #GȼNbBMM ķ~CBCC&Lͨ^⾘7DFFb< UX;$-q%֋#c%ټBaddݷ0ٯ|qP-׍=KKK6%%%8q"Ob۶m5k7ӧ1{l)/^@nZ-8p ^x^Z;&=aёܹsx 07Դt,pZs0ADSRRXC%JUNISNd$֯_333Y| ?~*Mӏ'Ӳ~w,í[ 0i$q=xsE=bйsg ~|ѣB&145 :t2{ ƍ?~^_ҐٯݻwGYYϲ挍}v(S4‚g_|eee[npuu7O7"00:::0`._j)={6<==rJt+WĎ;xСCFaoo;;;h;v ]vŜ9svZwaCɓ'#>>000.*4ӧcǎX|9uUVˋ'u{U۷k׮X8::K.E׮]͛7< !DR$|wb͋8[/99Oi5=g˗nmh o,&-ak{233gy{Ҿ=9]x)++t|gG>͑f\\;M&bBFzZt)nܸdggc͚5pvvny!ivdYL(Z<3ROSLݻZ]y9 XRV[BdaٲeXl Gi5%:MBidp;G,G hutu*Bp~gt邺z,J!%%%գk.bo4_#MNHIJ„fiBDhu^[K EH(+Uo%6"hkiKGC))^}q'GfBaNGWZзooi /*#uZZO_Ii7=ڄBތ;wN4i!"qr1:N!0D&!uBCiB! )'B!9~HBaahl*6W&bDےY/r l'/=!%Ց)eji7d?Bŭ䧈 Mc띖|,V}JSl6qXllƌ%&N nȾvM2;dC聃{!DzR?G_!x_쇏1&o?pop_MDEm+2R88l6-e>pUGFa2SaG̳mRr2&7.nw9.;ܬ xK ppvxz"+-QGt o$(}\;]v0mTmUϞ* IDATgg jJ0iCa Oa K 0NE BH$NիWsxz~d@B X[A]M Zؼq#REwnX[CCC=tucOX[SN;[ym^/vŘ0PQQ{#G`~/fPWWG~gĎEII V֭Y %%ޯ1d`Hw(m[TT OR_l:^zaT{](-} ~zСQ?`{<˛5M|!im_7zJ(qg2[tB0h,AʧK(//YvΝV  p`>auF#p51QrEj?7n[`?e 4mU3g }%-TX Omi70Sx%n޺?MZ+-C`P䢦rr;88+ h>=}Zd_ˁ7O둑Z -=7[_PQQZdegc emW/Y*YrrQUUzSKۢ1NE BH$5Mavw'BNw8/[#1n.@<~l2y?(--E޽mmAB0 Az*yxr,Y#QQ(,aiiА}llpPED?p78l6LLzJ mU***8z$#_:em?wIYۢ1NE BHĚqPT)!ҞC #:">K!(rB!:MB!NC'h !~&1ixOGBC O9p!B^#MB!!5MB![N!H5^qI 3YC!<.aCMGՁV'MG<;M@CCV6%.B&^-X(R}]_\R0e4UX,qGp>S !đ&ǹӧd2+]1nx= #t!fndӧO1|P={&Ӳ%Ϟ> h6}4!k8tdLUy i%xiRB8z9wM$4Y^$[VG ˢNS<'5MB!ёlC=ӑ&!ȐFD=FϊA C&!ȐF*18ashԫ0iB ȏYWMGblvviB ;򋉉Ann.666Φ#M H*Bd˗'OCXt)m YI^_BS-_nۡ_]`z&]mK/U:=K!2$ti@@\]]Zepg#i Rި١!io$t0]V@={?&GS?IG"C܀trYM -cYԫ0D!"ipdVJ"과08Ќ@"{f{ #MB!!#M&eɮwza =/!f(1OFϊIE#ٓhV&(vC&iJpx#U6}JJJ4]tA]]=t]zڵK;V'M$'%N,!䭣,Dkl6EE)0 12)]TZYizrtx<,)Auu >}*qBxuuUuƋo(k.҆A?}g) GsIwMSo_aCɆB/9tLO!0iҐeB!/?tI!04Ln@O:!B#MB!!TWWgՁV'MG< FH(.)zN2uC!&'aI Ix F3Iۨd4?&!D!0gO']Ӹ:=KԳgd2'!ʳπa$ږ:MFp 0$mfSIQ i*+W'O<y#7lGfNP]]8BҎi=+;7d?B텙LVr[n>lfLNS|s;|~nބ,| [7o1[/#MM--*+' N rx8i !G4=*-\ch@_zϟ"|ͷ8},:UUUng1n9iJH抌ѳ6i۔g+K[%ݜ>m6#uFش/*^?/&υ;w fg8#k\T,LĤ$̙pለ( ,fČ''0s-0sNo]0F&f|󖄊 z86;訁۷fΘkZWEE8cȲ9l-^Z-kO`큁c*<{'W_h{]&f Zڝ|ݻi :7~NlǤ|zы^aKw͞rpZ/ʥ_гG|~O#QQp抌$ğ<=I):JK"e r0DVZ "‘e6*,྿|*#냰#HLN6)9]{_PVVƆupe gi|ٳp,z't&gS@CCCdyKiBBB Ԕd}vn//P_bFܜk(yX VK2<^B {u55l޸fIwndr xmㇳc,-Ve r N?42~XJ\(X􀍵5*mm<ܶCOX(ÆPWWlls5s>h>:ty+}T|vbTV_x-uڍoϹ#""`lpcG b< =0zavgb' !\lllY#ݿj|xPV=ޯa#agg={"|B,_Y٘jo]}նޏ>#cXq +Rިfgx|7o݂y|b9v#/?`4cGA}({Ⱦw/obaRΆukq8}***P[[lYX AA\`|Bzq^JTVV"=#{|Ó2\|V8>^[ <&hjvAlmh L.֋Za:xyy!33ŪOA:-DRR"PUU+W`bO/zK1^`,GnUX]~݉˖!EG$eeOѻ.Y4ޞ9GeU իVÓFT,LecC","aabbի )'ۉRk\\x11a*q8,߿SW&MߏuÆi̘6 , gO3wl.Xrl7?x'L<Xa<}Ū` 8|t GBF!ФO)c͋欴Co * 3_?#]]jZ:>3Gm!//[]?EJr+>(++t|<Əxz(T X 8;iI[, r0{dsVY]%KjZ:uuBܡΟ=#ڗ0g[i!țE/c:M:EdK.j5!IJJJG׮]ڮY:$mJ[K EH(+m"FQantniJ,kB30Zv^!]@KK鋵]نyH #El=OByLw@ܳB@(@&!XCIgg !X,0`4 !:5墸xC!8]hv҄~>m?uk $r"'%%訡 +@Qa!@o_Km(i۹?mU]] 3!\vv;!|E"m;krB"jvIm(i$uBC4#!"RC?IG|;B! dI\dӧXz5}}}ӧ8rUUUXXX… 4։i'ezӅ;dL?׭G\| ҒafjA[? x\={q'% h4v#+-~~)3zOOd *"yv7X¹3ʀ7.^7W辽7vTx!l-MMl޸1_VЀ==x2<;`nf uuu~?}F`1a*F"/7/_"t^ȑ#v Gdz" =^ ރmnȿ^wO/E]]?q=cǎ2d+njDQ5N'@}wYee%sic ///^^޽ s32,x?߾}Nh8zp8p8PR 0wO ƌ ]]va$Ul۶ ݺu͛71p@_زe mq"OX K@辽024;z:u 'OĠAm!!!m5!c5ܳ,>p-kccxyC{wF2kjkqK";nބӧ!=#I)kW`%|?} [>݆=ճ?͛ӧa"a###|022vzǏ1x`v?F^!DˡHVmҒiR['JݸիVgPVVFэ< s:h؜\MLaCy2ؿq@XxtXi>ݺ#o^[RsM@]]y8 L70Sx%n޺?XAGmm-yukq8}***P[[lY/xBmm-jjj~|nt;f!l'^3gq-|nŠ+0gn͛7#00?3_ Ė-[JC$sg ƈq t?}>֭[Ҫ7:QTr}4X.?D聃eجS2{y)z%zH(<a  c^R`K9HT n@cGXZZ 4dߴiHȀnMrJR>?Ν;R̓/7͘1c[޽{4h9"M[\gLMe36mu ׯܹ===,^>>>4։b͋欲 = (G 3_?ӾgHMKua?nbN肨NJ?#7{/_DaQv`!wPY}QKJл͝;,B!~R4YYBi8=+ !SӜ Mm#dh։MR)'4$0JNLV'-Km(iy@Òǝy@-󼩭E!i;oG*@~߾ o o 1jm0HȤBȻD!:MB!!>Bi= B 4!"4 !:M]$BOґ&!Pqr16}UUUbmW! $F f:şKZ[ d,%ɣޯ\MD NOQI?-[1v"L,'|b&;ĬUƦ8q2 G$9wZKs͆Yv%nQD;bfN G[b,8dze3_SKkw/oTD)O'y Y8-;{6M*,._d&c" 19g.\DDad&cqXn=3S v8-\˗p/٣>?pHh,%?׮AFJb(~C8w'\'=Ea'R|{>x_A^~>BDDFPWSmtL }EP=2)%n07Džsg_o\tIX7ueDFGYi)aaH/-IҮ$QGlZF" `Nd`/=*#QQp抌$ğ<=&% h4v7Ի"E!Q[NꐕSf͜_\A]]yblѩS'X[_+PYY v,w6VPWS&6o܈tq;l'@CC#(0@W,[oivgɉo/fPWWG~g !{ А衫+r[()&eB[[***xoH /VnۡK`ޞ,HBKҶ+yڟ;{dT4<[Ց0{속5444CWnۑ]5O[YZӃ>".yurJ*&AEE 33$bR׽aei;|x ߟ^[[J A^^>_(+1;;^,-бcG$%'c *0K4ݿÁRc9X K@辽024d-}[Zp[{)035Q#V ܜ糕Ev& `^?9&Dݻ|HaCynnPQRßwœ̈́Ka:̈́3gp51_/kvl6[f1{t{^uuu0a\bLjD;;9{.WyJJJۊG~|LniM1}32=v -]8֦?ڒ `^?Qs$}LBi _@NN.e\\_]tFyy9϶RVVF}A 7/gYNn(UE7nb٣QtX6tsr$_{{\/ Yٰ2Y`Z#(p}jZOƉ?GZFm(wʤl e8Ʊ2ߺ Emm-˛gzz9ZYlp-'555yTq70Sx%n޺?_binݚ5)iAqCxx` Xx1{EVv6֬߀%%B1bpoϸ#mt%NݒBmm-jjj~ce"pOrrxڙJgҒ߻G&Džؽ'UI˱;(yE^~>π=Bdd͋欶/ : n`by`VgϛO?QOAefecH8ytTVUaРp^nQ^}CcԳOWߠ{J7w~Z݉?ޅNw8/[`WXsf(aTWWv=~w.{CXD nf+}~?x{Μ;oobwիVbR>J2)4DĠ4:vꊾ}0UT{046on; k\Vq/͉KS?LfiFԿ#QDDFIYzփe`Ԯud"QV{aBoyҝ9 ꠄ'J]X1:M"{I)xLFfh7Q[!v|gD'&D杦q{kJVӧ! RޡF{yc ?;x ;ͮahl;"t^SF5 <{aܹXx"oӳVzɮ,!.:#2ŸBiz !HBaytI! MSё&!uBCiB! QI!04=3B!4=[4 !&7LB!Dn4 !$Bj|4g}UUUbm]!"_ Ӭ´bmsY C^ޞBewйsgYCcS{UUUiSedVgʤl ! uMVanZFBCzAwX2G!O; ^1|8v+|[\ax[XM[]񢢂'MbR-\SKkLvS ϙpለ( 6 a#-1qNYtTM&'Na,[a,<*oaLĮ#aeSN443p欀Z%O*ԑ&?7nt;.@Kr8] ?_)IBN^w}:JKATD8#0&ۤed ,vDVZ vѣ|k:l:n|UGFa2SaG̳}Rr2&7.v *[EFGYi)aaHX|>2o45yFs;l'@CC#(0p􃹙)ѯ>w!q1&2*^,.blѩS'X[_vnۡK`>HRLhU @@tOEEz´Xڅo A^^>_(+;Xwx JJ`͟wܜg;+K ;_n%v,8`|DՑǯZ!D:Mqx^uuu0WSW}Mm-z :dmAEEEzQuD!D< nU+ѳG(++ ÆAvN GjbXe2f!Y' 5z6g٠::W,WCk!D9QkL70Sx%n޺?֬HIMCMM {wukq8}***P[[lYA`LY Y1|*++*h all _x+խΚA(..!U6BH{P`! UP9\;#l7G; BuPEJ*cG{B!MX \ ۤғ!B/}c/"%h$BABaMB!!By4I!0D&! BC4hB! ?M|6!XtG B!D.?9&B BSàI'5 !Ii*<;wZe`f[* !ת~>.jx+We.|[aGXfKZ'F.QxOttt IPBȫCB4)%!uv|'Ns8s9fN|Jdp+\ODʜ> cacρq8~:hT\Hh|<l=yV6lkWƾֻxr8sHKNU+qe8ÂHơĈ#z:< $"xM"!1 =,_s03qED`HƩ ~&,+0gdCCCCh[/QV^Gn]ah`Т,$w&ۀ~km7_4>prѹsg8qX9}8P ]_ .!A8A#:r'EEmmmav6}XC^z"d:˗Pb+Wi &}&BSSzz_ I{&vlW^Sg"e\] x@l|<\\$ߚeed`oɑ&{Cnnp]8rDq9Gj{ʆ +*?^$FyOOFP:D; pr035:_\N7o!u&8"w4 dcֶv6),A% ~0J\|\]%ߚeed`oɑ櫿a~sU?8tdo<}%;zDTt,}88"I]]f 555}TTp@nVg"?; Y2sPYYܼ||Bg7o‘Ñ5]m@9BP7}L!2-5-} _a90ׇ*rrsE[#-e Y,-,0ktܶ'а&̑Hd޷𵪪/2LLVq5*JjuuuXZZbPرmѣGXZZ`OhضPe5d`om#!kӱ>$RPSSkiذifϚ),'~>Z#(X3a&Đg$&%㡦 01%/6lFl\ךea 0ʑ5ܠ}-[f§>zNJ̘Qg9{G(4hw4mkxm߯fäW/5ָ^^ΓiWWBSC, "%}lƿFOqs8T;~[G|0cd]saOg?.s}|x)/-Ɠ*4oCTt4> 6^iFŹs.GdzMM ==_/l䩸xW9<~.CQHZ q'O0i2.k'4 I6Ƽl118a]T81  ߇uk 9>kWƾdƖBGG7ov CK#16N/XD8 UP<(o:0c8l11Xly/`oFvnܱ G|SR0j1ە+xEc:|+spr[zLM9fٳg&PdZzFuzN袥q ~>ի'B֯kUӧ!hr3gbԩb/*(hkkCMM  ۷1acq&2R$H?7, k`odž:z5A8uFtV#:rME2/aoi¯EeŖ: )9p5*, qqxHlBSSzz_ IȺr8` }SQQ==ӛi~cPܶӑ1t.Xhzz(/+Z?!ժ )&6CBMM ;;a0Vž}.9"Ӹfڻb={L6m݊ HUC JH|G444CCS&cǓ1rرm2zzr5QZV}}MdGP}65]We 1ƹb-+mGw ?QQ񈍏 ".>Hl6ӽ{wTU<#f4q IDAT?`o'RNusiI;gwN;uǍEݱiVx *>B~d^C5OGFjTjyRM>AڍV ۣ^x;G'uRW:_3g|cPD=)%]՗`<Lt:vQF"9̙s(W,2+C[ ̽544ǖ8r8Dee%r}f***Px&9ur=]]Wcgk" ovqx'HMMõs&ݵ?~,lA UUU5H"-=CdZjZ:1kU9y7w fSҔ9RRS/ȑ()-Afu$`R[ZX`֌عm N asq<{p&ƿVq5*QMe\W}*"ۀ+\le~aii{CaǶE=`ii=a`B]7i9]ԟ YJ7/aƺ؄H.~hiuCp/τlނrx<\K_Je,:st 4Zj6lڄٳf*&&8)"/?AD˥}}1d3bQSS_8$O2..PUUXg$&%㡦 01ysY9@ G-|>vރ3gϡ <))]Pj7 5-]d]yuE* ("qΞ 7h,LWg3!d32񐞑!r8or_"Z*x<UW#*:+1ٺo:]vL;zH|8~y \UULh [1o\K//&1||fƪ5prUAk#(4!C1k4S}r8l۱'2}v؎ȳg1=}0O4w,`~ |}ڪlHnnU6߬YysȌdc[}qsχ\hn̙5~+:+YOy8Ԩ#pz6ݿϸ)&!l>ƌ}V e޻\>Um"DLJR  9Nlfb|78vG 'BtL,.],r5.!m-z6Y% 223w]t=6ꠂrV5{V 8vG!m;݅}a{_w*-sfDw[&x&|e|Vz V>夷I/م+geÆo,G(AX>>8~"t~;!A%e6j#Ņ@Bț@h_O9!BsC{BC4hB! ѠI!0D&!PIWB!ѽg !7 BC4hB!PB!o4 !h$BRywCuu\hii̴B!S845f\\p^D?u&HЭ2c?!z6x`Aw%$AOYZH,Ӟ'^y4-Cۖ:{{:::R?:tXO_UU:uB7zɵ#Y9p:BGם[ŋ:ܼ"W$füo~ڎ"U< xͷ-imk<RxOg"??̓+sT>~n"9H7EMM }լ?ѣGwhii ҥ w?==Oxwil[MffII ⠭{ë@SC#w[!߆\TT>ƿ mm0GwWj壬>zۡSǎn߽[PSÃYI/?*An 444`j --bat㿓&|(G%ȻQuNMʡE/(ǃ,[ʶ[H˵W1RR |y"F  v r-<`h;ؤܽ7朞%CQ z6yc+Ҷc2Y'z44l7oǃYìwoR\l- nW.ZZسQ]7ݺΝ51[R}L߷LS\mu)mL63#&?<,. VԸkˣ26ږHSNc-6yX, ꇴ,TҵT|蠪OQPxK%\N|@Nn8v7 o‰cn]*\KO: [WQY|سmѭkWxȸ~7oOJVNJJ=})oPRZ6kgsŏahjjUSC;vӿ6o6OSǎS~a!mmн[7"z69rs))›œTU!%-ClF`VmJ\kfEse! zem@CLM&q%lyE% og\}FZ&KX@]۷ol6fΜGI=\ }(1zC}=7ЬAVv.++shnzH[_US\4<픕Sӧӕ"9Fn uW^^mmm K(;v(Ck۔>VI֥C2˄CĵM\/^@|R2lX[ז?=ds;n }urrĈ&LJ@s|><^-Yx-?6! eex/^@Ii)4袥;O"FlWTŋ(+@fvċ CN ܻ_/^ԡqI'+'~G%xFJˋvɡ2Ŵ>޻#C޻C}30oȹ/^ԡץlldK-#M)MMM|fxg\XKYga.{VbR>2sŋu(+~}\ŭKYۇe䭗4YZ&.Ĕkmb# ?%dmKW |(--@tDW53i 7tPU./s푖wלtagkae|Er020U?K\K|AP\<5\chh\H cCCxHIKGmC}zne}Y9xV]-񐾬6ڦlZ#=+ 55<Lųgx \kc#>EZF6YSV,xŤn{[df(VHNMx1Uܺ}[Fzey_ֵtYZ9blXS@XdicoZ{8vG!D)igaΝQ/gfLʍ'H_{& {g1םFɣ=(voiw!DY |- Κ03 >f;-Bڔ#)R{ɣ=h'޳Vo^nrB!A ?K!񚌏I!0D&! BC4hB! @?BycX,8I{BC&܄B/I!0T?h9MB!D"VIM$BABa)' \t=TWW˵L{_!(hjx+2.W:a#?;erڥxixb9ё:;vDǎeƲaKG6=qMBK.̙3Y>hțJֶK6!o67(% m0DUU̽p+\O'Nk8s9z,NGZoTt4&L 6 c?uuu󾞝 #ǥƻs.Gd{[1\d {Tc:fN|Jdy+6p#=amk'~L$uZd>\w8F7`Ⱥ㽱 Θ)2w+tiim ,Y:sJ/"˗.Fbl4N87 /Z SLFq0ǎDb?xAAHE EBb22kO(W@r|,"Ð1(|d6o܈)&Igfj +8wH_/076n޺x!.re|t߯\E] Iq1XzB!*&F$~tL ~y3 ߇uk 9>kWƾDYl9˹H%'bt~CP:,h@jzp>\/r {!08y41QcbC&e󳳄Mɚ/O[em널WAuu5q5ŋqEp\x{{3yo6o'.ӃeHHJ?}8P ]_ .!A$p8@SS\G٠hoXގ uuukpL1;'#x3OǡC xYL:삤ըhX,b"\\'.;w~8| GD }"xy60p|}ľ~>ի'B֯;5W3k&={oEgd,7SL*k[':äRia8q"~',^sN0ߙerBuQUT6m݊ <~,kGWS?~\ @ lްp$&%OdO[Vj{dLx2F;-\9COOWb‰˕8i{ -vڳgDy[L*k['zJ4===ѷo_9s(((7^U`kc?/^Ijx<\AG?;L &W3>C1t("Ϟ"qQYYܼ|l߲'| ޼ GG6n+ɢXlܴ`Ė冷.w^;*#%M)ۂ2jBrHEE .D]]n (!=a90ׇ*rrs[Iy}ƳꏫQQru | /.sH 3:SR0rˋaii{CaǶE=`ii=a`Bi-ڷ-Qs5c:vnۂ~BhXĘHIM8_\PVUUEl+!m44Si_eg̘!ҥKѳgOeKojkku-ʬԴtZj6l9[|ܽgΞCUUx<SR`\X[uNէL⩪O>@@UUU$3N:n{pi9}:ևZjH[gϚ)5ﹳgbM-) '$ĤĘbcfţEE2չ2mldd% e[ !mpx:::r g)C ۺAXz =0ktov5Y:024__7 vlGhx8oχ ͝(>}}>׳g3k&xMbG[tsq;1ح>!nnؼu\1|*++*h all _xKy|}" pJ`llys|="" M p8ؾuĘ\Gsnܾ}zz?WEseB{EX=Bb5-Ji,Ai LJR  *|H\LDJ6ȵUtL,.],r)ݝZ|{H[[ǎ(2Drv}ݩBia@㳽"aCCC۷lޤB =KGLC0B!Dc4hB! 5 mB!r=MB!!4 !h$Bdh|0 BC&]D!%rB!h$BRX;B! !!Y|ɝP]]-2ZZZ03hBkY]] 1cZ҅V'deÖqOL7-d򮟶df]G؞݌|!8;{VgFi//b)v!?UUUhhh_KceVhޛM_7Mrx8/_8߲%8}\B1f@@ |l=kl^:+`0Ջ2fը6̌4mv7(-n'HѰk8IDAT?qE\ISp6tVo,keIxb~>uZb^[ٰq# k[3ad9\x6?qcƞ1pSbxm(3z,NGF&KKIGkHEE׋[G|4y*.^U(DEHl?!f%KPWWtܹMꈎEāذ. [K#16N^Iƽ,81q ^}CHMO;r#zYص'+V 9>aHCަ߯\E] Iq1XzB!*Ft xM"!1IlL&KKImk#Re`o_E"-9Wĥ˗E۱+6WBۧ~Tfjڵk/ŋrf&{1V#p8` 6o'.ӃeHHJO[oj_DVahjjWYN| %5AcC]]zD :6:|+spr1ב???p@lL&+җv^ 555 0n&RF_Oeet ! xW6cĉ駟xbΝ;|gVNd]r"w2iM‰˕kqLM.((Ou@ @ hѦw‘ 2A i{{׎e_wV{dLx2F;-\9COOWKàٺ <==ѷo_9s(((7b3p^緘&u ]}(&+җz(++G^=}%F煄$DEb-??&,SV^b6RSNTTTpBa֭@HH2BKe޷/32Eed*JKeWUUE)K sJߵ?~,2P\+jO&mcf iiLdZZF2}$Y}).wkk+dd\5c:vnۂ~BhX, 0@j>v'f̘!ҥKѳgOɅd xHFFHJNgs__l ٌظxԠW : d!Z*Vʝc=8s񐜒 ަӧc}HRӰa&̞5S!HMK)3G //˿&RHLJCMM `b"˿Cew!x+WPXX>>eee Xriغ}gt" ^G{Avލ۷@_O\ᇐ-[1IxV]>}0o\,_!W.kv#x|`9JoӈPYYUAkP\\ ccc]t;kWFX 7WW՗r5r6mي{wOyOždBSCo"s=bǶr! p,C)= AEs9\u;#lf5G]'8)m^{]t=Bvu`JI-WYmmm;(_J̙5=}7ošuoL|"]NndT9*tp% Z&o7֖ x!ĉ }dmboe&WB>t ,! !:6zBۆMB!G@BL;B!*@rB!XMI$BABaaФ !I$BI!x1iB! I!d=MB!! v=TWW˵L{+Z%!Zu%Puu5ƌkK]deF~vN(vfyFys5UguttBCCCZ+Bړ'6o݆[6`C!R?D6(  @~~l[םROQ6A[ƍ EMM LLLz=`&OKƄIp9z,GNjg"9z,l9;OlQ36x?kܛa ۔ O؆zFȳRsW$u|Xډ̗q?HOX)qq$Oe;j?Q[[ !xI6JJJJ0cH+ps@IiB[i=%K!!!ܹ.^cnjkBddfaמPZPVV ‚Ϝ9bc'&"4|6 UcE`H߯\Ekk*;ĞK8uDrӃsՔ26ȰUiG:e+W1v{"ٲѽ[7e2446n޺ sssfs5Jl.LGDn^>oٌ>BEE oބ#B J TQQ… QWW[BCC!!!r03퍜ӯwoi5c:vnۂ~BhXpU\n ssedLKMKyi-c&|:>E|i#.}ŖmM^0˔<ȳg"a3$:,--{o(ضѣ,--'4 l[[K]ߡfk̘1CKgϞr-?k ߀$<{ Ϟ=CBbo>IxA|BLLz /|>vރ3gϡ <))]PbsgĆ\KMÆMD̜>CBp-5MY3e ~JV"9ĖU4/YeJ֡ pDZX⌓Nc`N: 7W:Ip otp>{y/QPUUŞ0ܽw@%1|4\hjhq[99a׎ G ⯜? }}" pJ`llys (ẍPYYUAkP\\ cccG[xǣGP#?;Kf̝5 P\\ #CC,ز% L:8l۱ : ؉ny qs*)Bۏzί db'rUv菰8@S޶[m!J+cG{B!M[y9B!mjz u{|Coj^BM!0D&! BCf[<By+b))'B BC ?9yYB!o$BRSN!W!Y=B$)z7*+^w*o]=]t鬅w}Gj2pEO^Qfo6^` o1h$#={ݩQbbC|],&-1%W :#fgPzv#FyB `A ӧ$ο]Q ϧk9bf ($iBTEE\!yY@ O]+YB7 널E|X _%PWVsNhO|}ˋg;_UN;K&! AS]C<^i 68haÆ N׮701cp__j,||>UUU!p` l~XOjlfFXא_2B Bȫ"[s7z4,-pcf=/O%fZ9MpU21^hk#ѳgOi7r<#_/kWXBst13CaMpRGG6m}==xF"uX,RjаK9hsfbjpZ+q&MEhc~:xL*WxW~}9MBHk '`,KHOO_R.M[[[#66Nbl[6.rAjh3A3{vwƌ{_>_ 8r$6o\G 6W>|>JKJ_ww1ma~i\my+]bVdKL6 +1сsl0.@1?.T˜0\f-mhb j yOϓCr8oiяmho@OOB8h}h|ۧ?@)=RJ]Ůޔ| _h,ˑ" {N{h6ZqdXK*4-M4$w9!tf!Ritk1Ypq"ze:sP&;7)-MibIDOg 4A|Дİԁ9-i2!f1e61q70")1zk;vl&O Ji52bývn#l(bQ/lW;M!2^hJqy33rN^p:KpܰMs ]?> ~|ԁڱVt[3H8 R]UZ `-@J&DDD))$1$""JE)xLžL3R)1Ӝ/s$""ZJ+&W'""2TӔh2%]IDDDK-0%1$""JAwV3M"""#S(\V0G 5}B@ǭeS"^ՀOKGDDSdD݈I؞:X='57_QasY~p0sNIENDB`mathgl-2.4.4/website/udav/udav_inplot.png0000644000175000017500000014276713513030041020621 0ustar alastairalastairPNG  IHDRMsBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxy\T?̰"%X&Zj Kr -q%K--ͬ[V/hMTT@YeE``d`v1|Ȼ9|uLxBWJPRErC%dIma#P%$"""""I lĝ;wP^Â%@ui[o<ҦR▖HJ ʥ6wr2 qmG * @H$H$;KSmr,.n٤'7@C1 HTH* T VR* eee[Z -8\DII1 R ("""""=,yOZH$GαWJ`+z~ C* BI!9w`>*T;xR*(,*C}H$T I%Yz ں8֤"bvYeDzX5- R _)MJ{> ޅ&2YdBd-8qၨtCe+T6FHyy9"8$6(+/g ];<Ovvv&c5n~]"AЫW XTTTL+`wp59/Gz^0mt`e >׊ l۾YYYH$prrccâ>Qmny @I*U*C-Ri)llo&a?WNj". 6!5D*++{> AJEyY}Pz.$?22QYuHSgr㣹s_hM?PQQ'''TTT`|_oZת/Ro6믿&t9>vqqpwwok|Mb:#=c_B?^{5 7SSͺzS束WJKwIyR"Lv66YKMd}kp+;7QQq r`A?|VXTvڢn޴rU¢"ȫ{OZKD"S̋ݒ?ï>TM:A/@" ?['_#GB"=ۏqcٹfߢ"߿۷/*\zɐJ$xXkz]rElܴ .%A"1cR5Qs-EOy۶mǭto_x{.t՚̙3cN$''=z ѱcٳf\z A__?h߄ZmEwǰxq<#n<,7ڒ xឍ9s I1kld2e˖X|kKO"IeU&ڦcxGp:[ ;Km:ll!݁DRDT*rso'J৴^^ͽ _KD (+-EzZ*^`Ϟ_5Ҝ;w7oDXx8zt놰pUe? Ǿ}(//@UY(e.+jxXn=9z ?3ߏLf]?aGsw^6cʃ}//o|t)ΟӬsܺu΋S17p ,ٳ9{~Ş~=>pΞ= < C˗M֖իWq^TTK78o7^ukj h{ڌHJJ܏>BII1>cÒ-}(vl」6+xp!lܼnr6pQA"QB")TZ |gEQR\B"-DRD H*.z?%%ʪ[*AqzCIYiDrÇitߏ׮… ׯǃ];b>_c Jħ~Z.)) ܳbg0d0<=j[L1-J%*J_nf^(+-J"U7/_OT]^XV{^b%^{- SM֖>Miӧ#vfr,\yߟb O7͛e睟 E[xQH%rsowW"L Rܺe[Ə?[D'bA @ A?F.$uG> Ȥ*+(++CyY55H,ƌPͶEEE232O!b<ȨZzݒ<zjs().ni(SW>o|8Cp660|O]QQדQXX`=ǍkWr#!ao"??y.;!5TuuƄ7lp_5N87c{|i3]+WF=Vйsgd*(A@hhdgťK()y4?Rphdpm+ǟFf[U\y&ey92%k[92"5CF5kv&ˑv&V^ xWT*q59/ɓ'_D~UDYIFaay&ϝЯ#.n> rm3%:?)))(//Gݻn[Uo{S'ҥ$TTT ;;ӦMI׾C@jjqWa(--+t+/$|%70x a1'LTZo?T&ԤoBD{v(/3ZWw |֮{Qr"n$_(͔t۶AYv׮&!v6oي>}˻LﰍJeΟ?vprrK9سO䷋۶Ƹq?9At)J&ǭ[8u AaAm]8u4&̄a?L.JJJn~~XR=9 1pssgOY>[7ܛf7b((1r9_ #knwJ9:wكo6nDii)SNxgJ4ƌܜmyamOܹ(..\.GPPޛ>&wLxֿ[^{nl,,^۷c˖-xֿwZb!-- wJIS/%|O/äIoBP(v}EU7!=/]8yS]^^#joih}%wH| YF-p\xZ -Ŋ΃DRΝU^1cTtv%JΟr8nT*J .µm[z~ٍ7RAHIMӛnϞ_1g,tAذ~]M]uoٺ D Pw<ztu۲uspl];w.,X v1Z4APATX))7P5y'%֬]SNh=˳D=ѣ4i㑕xL0-0á5k) ^/5gN q9) ]:wҙW�QSu`׮՚VTҥ$̌>5M† 5sz CC3c:֭O0|b[f #ử!T[l2|bN9HZuE 8s6gѡ}{KMR &/FE!aW#;w/`saXM_5:̕///m^^^0;O)bȒ7}z\ t5*}ff 1rp>Yu2s4Y_n#? L06K,FObu1GG X`iǀAiˊ KJmWh)b @M3&+N i7郬{Ǖ"77W#ߗ.T2N4j>]qt<]&=Iss!Jqƍ&(R=blkb]~|B⦱Dzzƶtxzz6qZ;43.]:#z mn YtYoq_ۨOWOX8.^lܽ{Oc`!N:8y -„7ƙ|jcp!N<֤cjN:vĖM`ӷq[,ӟ5hO? M}:Oԓ}6fn݂7&M5ލqHOOGJeR0sl2˖~ t}bG…9OOo)4͌L&+/1!%_by\:E ɓ1rHO>8|05aC5D3MfM;mǣApssG233sg.CC;4To\qm:guc1ucLnnj֛RN4ƿ>G;hljSBTBT"zzߛڳC-%bHֵ[S3X!c5KUnMrl"2 r77i1!8sQy8y EҀF'D8rKlb"%ݻaaa~s}cccQPPA  NpsX+um߾ P(رcEjqZJ찞< czVӍ`Rswo@L X>֤thۮV{4I_vvvѽ;ΏÞ~Y-[a añuwIƛ;w.,X v1Z4APATX))7p>kj tby;=z&MB||< &㢖a=Cb,V۽U4G)FrRt7ݐr\JJ_nKg »f^XT]}I?oŊk0.쉿.\h5蘖 \MN3aЦ ^z% /s "Ggif|e}5ٱZ+*^BԫQIMcyy٧ Ïv`XbE]G\^ώc5HȀE.!˖-CLL  :t(bbbl2lڴ|I%b eekxMRzw3EѱcGL'JĉXhӚu֤JntRK03f64 6` ''' ĚXeYf #ử!T[l2|bN9H#? L06K,FObu1)bWH0ڴi}c@HMK ~~ݴeË́b6Cu+Wn5?cb2#FdT䮮3:}~n.r8==] /A\m_3OLF\eק+N>xbl,Lu T7n4AH,1cc_{6^ >37з'5ӳQY"v^ˬXkijLϤKH<}^E99HGLr_7zTOk1ELW^z 3bf#C&5Jd9bJm_==ׅhu"##id%b <1bE$bXKmu <'' G6&"J4>C"B"Ɒz߫B,%?jIe2?*A@h"JY+ⲦX#.kƊ+d&vdtq!* ̆ Vj9RP\\lBzh.Iw0VCs;֡9c:0VXJHy D*MDDDDDDun4IER'RyDDDDDDq.5DDDDDDGu+AI$ڈ["""%%- (G{8;9s3z\l4Q uh'gQ_$X!VbXc'%- mѫw('y>prr"(8PVVnT* ۾/GE 4?q¬rbH,35(O"kOԩP*P*:SaXi:uo֔ cu;I H ?}6 49s`~}=8sj_\wsF.O8q/D,|2݋0NհƢ @ 66޳cZJԵ}v( CP`ǎbiCD-z<q#!zLj4-llm'GGG Æbu5i_cӃm=P-[<ztu۲u 6[Q&jsbbEA 둒rzU>))7f횚tB3ibX%bEGŤI,c„ 8~jiZJ=CD fL+S?r7w\NJBκ_>s.ܷ?6~^^p|rϋEOEu"fΚeT*~ߋ`a\,]1V ?.@—p59ރC6x(15f;Ǧ͛՗ phdjTxz5 QFL'7JWa?ήf 2 ? WWWσbyu/nry>;v~ =#^,,[ 111:t(`Сe˰i&%Mqc5#My5>cǎכxsƴ6`uxt #B{uT*qRfҚ&a̚9CCޡ1']b՚5n4؇nR!n"8U8} y\}IL41 EG7DMRRQSw͛:~Ukך}NGEDDƶ9r<>KNc6i=MҤkO׮:| B4 ֙wcx;z*yߝ5ϫ+W&,Gsx| #:oU7 ^^_N3g1}Xڷd *`bllT6|1s. 9Gj `z!兌 ,; DD\ t5*}ff m~$%%G4מQμܧY_n#? L06K,FObu1u4G X`iǀAiˊ KJm&c;ĨyD0iZ=rWW>?7ri7ÆbuzCT2N7(O_8u~.PiHss!Jqƍ&(Rblkb]~|B#M⦱DzzƶtxzjMDp"jJUW'3ҥ3OFnnsrx,t7ݫ/"L׿q)o&oc1"s͇sʨ  |y1V,OXQkpXSLArr2|}}j*ݻK޺Y"v,9JD P}a潅z#%5 Wj] O޾cۖzߍ>#hM ȑ(//P`4y ŘS1'ѮjS0V,ұbl3Udd$"#ߟ D DDzmn8tŵD<46 j~'YOj獒YXB֏CDJ]5hzY?Aˢ%} ihӦ .Y O^M#Ve`^BRh"m H!qbZY+d&VN$bU˫T*EeEy7c˚b.Ǝ)v+և3ܖ89c}bՒdFTsE2VeMRcG\;N8X.NͣM2:Zhgt́ BV^ii(..AvvE!=yC[gt$+֡9J]b'5- E dG{8S'oB-T)l4Uhj'8=H)H,v"""""#MDDDDDDzT786U&#""""" HJGDDDDD @<""""HIKC1y3:7Q TNDxU/tnV/,%2 v=6;Li<iiܩEJR==&]JZyŶbI&s`~ȀJEXψb 2ɏK׿?۶EbP+y$:^ĥ2O<vPi,H.PBuUr[ #%.A2)vLzF\gI$HnHEr7]]ѥK:Y=d!"S!"kFSii)NMDpp t<=z AAopaMMzLsYSYTz|-/ofDg5=Mt2"GA`p0 NNN㋠#r4NJBYYQyaŪ("4^0hHQEbH,35(OƢOԩP*P*:X)Y[S>g Mgwww zfΜ9k0r?i7obY|He6 6A!>'l@fV>|0)))Xj5233ѳgO,E{I}>O2JUQF!(RP[`rgd tǭ!˖-CLL  :t(bbbl2lڴa'G5,U4f,S5dFN~~^͢ر))6l3;4NNNӱn}gçkW8::qcQXX9v4 wh(ѡ}{̘=5RK03f6T[]֬wq>|u3 q y~^FF4yyy!##<>K3 DD==O.wCVf>33Scz6wk𨿹2JC0Tj0kcLc44y1u䈏%._ 4u;D=X $ ;BꊼaXx q]?qߏ1턛1兣ǎim4kjhRØoTH<zX2WXXvޭm7;OLc>fO@' zfiMs;'{@kn}&GOEjZ#x套j |Iܾ}|[n&Lйr^X$"Ǡ>8~<͘iމ[1n̍Czz:*U*LS74ߝ gg/-G…9OOo^-S"a3;o>S]_lf9r$ЧO>|qqqR0g; $Db;mǣApssG233sg;;;tǿޜ9IonjcFvCB.caܼzi"њm+ƤwCtXKCT?h\g  JQX ^N8x߾4a<ޟ5YY7u1ñb L2ŪUлwF.yfzcHm4v 더4\IJYV\.C.wE/<͎1=K54M yȑ(//PB`4YFdjG<7Y<7YmcFG]HDF?fzcH7ԺtŵD<4L j~ Y"2"vU$eA}N~ RgZi&"Nu{x Lz]UuȣEhմ"JQYQvua=#.kg+և3vgH<.Nؿoh2 yuqD&a=#.kgqb5\xM"Q/)p\>t *-Zii(..AvvE!=yC[gttE!2Դ4#';G2a=N. P"MO&j:wZy_7KBD-2:Vٻ[ IdI֛$%N4,AvIo_fF%"ېl%Id+KF5R4cmt>~֊@!*ChB!B)p ӓB!BQ8!B!6ϣzB!RD!B!Th"B!rPB!BQ (V@A칕q3 L8>ZplGC2&,Uy$ڄQЫ&%s+5ud|@R$F`_p4kTyam+8:B'#+ ںptrf;*'~L8I}.0nHAQBdDX#֎Ꚛצ$L{_fQóaTY| [vǏ*(B\a&zOs3 >P%>_^M |Ǎ^6!&y$r_6!)('ܥ d/6={m@OօG&jOhp x2 0/ RHp84$!}|AG>}Bҭd;%4ly<$$\-d=U,mp?%Y* _b)SڞB#i>*4BT O>!# <hڬtttag~#C|_y6?vh ?M66R*.Kkeww|Yc |_|%KĘ+|VQ>C 4I7%JFO^ЫWY+z>z͛*<=|uWK8uarwdOIƵ+f JNUzR 4ׇZj#??J>χ@ @ @~~>BCCE Q3.\35 S &'},"ѣG...3f \_>llU1ς͚5E5_zz@m?I,ZTtŘ 66\tG"<t,FhmaeK#2qPR9m3ëWpU4i҄YߤI!/`4 ۷sά闩>sɷSM*M[ `ummmbE%c> o-=ļ@wV6;ñ`\8qсsmVM[`L\#@cSQ;bѩ+&N?DrEڴÒe8>LW/kE?ET7]ra7aQH0^ lںň8(!Tv*51N]`ogظ8ܽ{ǎŪ`ݶXHMM[67lĕݵ:::% U^5B<ѯc=I G{e\G,/[V,]mmm̝= JU$8(͚6;[oe2N(YE("I{fxxBUQ޴y6̟7w?g~6xx$7(!& '=zya``:LmӧOz}rrrDW}\=}{y4,xaҪYmA$ݼN]KWtҪ>޾|EjԩSWAa_1m4ڵKc$}+@M?6\#q>C !DEpDINn]ر\.iiiHKK l¬ J|: K潦fMZl=&@$(fMq#Ȳ7ܼ1ACC_56ڔ"F^:GU/%&@Mԧr4mBO)fq5\vM+$߾3Sr;vD+ed tRtulcldWK)&aw>|@FF&,(UKl߼֬C^>c//[koÇv,_qcXQ̪HOw ii,EϟQF P+5ž-Z͒j|RyG2iEt) }4z`ok[L} £;&M`?!o|~t\G̟;k Oa͛a7/)舫{x5yx91]:/U*e+Vb EʝX!yۃΝ;9s&&LPDl'HJ*='0n B-.X{dŒ4p(!HB,ZшhggzѰpD}ɷoV'.Aܻw+1]BHi۔ƈ:yc:dD1ysl* 4{sf8afϝ&L "11jB燱c*-@`QAf|j&&9rjE&`@Ǐ/(*ڤX7=/hZ8w$ 9Øjf(#3 o߾eӃ^ o- &$ڏЍ6oC}E.\)N Y=؊k Qq7y aTI3Ñzp_BQjM!GX0J9S'pC4! 4Ѡ;BJ0S4ϣ;V";S}Ԭ7B_[Oj&&=-Kgj1WᶄCC$g444W78<oҤJx7/?"Dj"6&J{[>;S#"pHwF72G,7p3 UUƤ, 1̦"̬,/_d;RQG6LL~`;BH}l740Ҷa_YLM FxhՒH!T64< !B!D!B!!`C5MB!R `qMB!B!%h`&m"B!"D!B!BCS<®,^b;RC”S(TVS9BڡR9BZ!O؅i"B-m]8:9 Ýdfe1s(ʅʹRʅ".UgzBaً0:HAVMira3Gir|K q CwFiQLU |3Xhr[B!B)UA9In=D?x6WzuT^ B!*>}[ɰw@+KK4hyyyHH ;;[hii%`IYZ~J2+&B!T~2'=zAM5tttд9o`>|ϟx6چy8p~>$A%^>Y,> KKKhiiBr|<ƌe+VǏR… pvvCS'#EGϨ/g!&S)V2zz^zen==q-YNU)ɸkW.cͪV+\UEM>ΟI&aժUŪUDb"snq4c/=x5/[.BBBtR9FHT#g3yz g2aoPnIH_>ll%-mpi 2 6\uŜxmרQ-,lbD;_qGްsG8t9!qȲȣ0d.|6pvZ uօvZb"(mݴ]] CC >_LL d;O‡ڹ (.?|r(P>CAa9Iꚦ*0 /SM[`L\#@cҊ C ذy B@m܄}^c_׭ t& v 6nނ],;+.!!"˼q""4Cڵ&Qq"DE.n[BML&iڡ|"+ R}6A 6дb8qFCC̝= =ļ@wV6;ñ`\8qсsm̌a9{.nJƜyf 404d;4Ƌ/`dd$/^`)"" Ia0?%GIT__%>\|r4P>CFYDjToV-[۷"˄ڻnk93gz'O`/O$ O6lDԌilמ0~%GHT=jժ̬,@V-+ؓTug!JNڟ &Oz&=zy>''zzzCCփ؄N^y ۡШQ#dggy̲l4jԈŨ*Jc;wlMMM%GGTŘGcێptqsñ'0bPOC !D]=`PX$y|7dr+ReoldWWӂSfV-XU˗֮YoCcL:/ӧ?Xx1MvhD clް:::,GKئQ#GbntpqQZm3_yiB<077ǦM䤴*Jcgwԡ~q-VE]D5 ÐAKST~Dz(+P>Cý{i&)ZZZh G#-Grrr$߾{[[ԨQ٦`:dpۻw領!l8XbY޽ѷwo* ABEi,en\*7н[Wԯ_"#g*3y'mV 8;;!#3 >dӃ^]8S;B!e}[+6mXv(CQ`G+f&:!5gimZjah$P!(Cw6m/lpTq&B!jLʉ!Djjaοd=B!BBU3[GU3U".Έb M'%D^tutq)&0b/^DmɇJ+ i8J; 3D\5UXL ޑ(5ѷBCCKP(t jՂOߋl#n'2iRRPP~:x<x<RSSYBJQx!sMdOIxHMMdO޳} ZZZֵ ={›0i$Z Xj(JH C cxG%_ϰefI֬Y3g˗HLLċ//خOʐ(`033#Sh'OAAAHOOg9jB)PЧIT^-7Ǣ` 2 ̺"mg8addc`9=u!u|흜.෰ HO 0n,455ˌYl)v Ǔtꢃ3͞== ?+W"p|e;uB%1}ZKcڵ Xv-ۧs}GwoihT'iصc6lڌ{У{wC%1::[WWׯG-m6Eԟ"4QaA(Psssf;T߿ LQBw0$ @ mwlؼ!AHEHP 6nX ;+3fax.Ϡa_d{̛/a Hyv(3֊ڴe fǕK18r|>/].瑙fM,kn Yb_FAKK ͚5СC,>!!"˼qI*OUdmh٢9 |=|ؼU>/_POEiE LҰ`333ܾ}< .ĝ;w,!y}?Ƃ tpqfǂysBGGN\.ed 2 ںψ/w6 4;[ԬYff ce#n|+. mmm404ٳ ^ǏpYS$a/>}СCg GzǙm^x### I*7>_ ".`6/??OKAAA;v2q>V`GSvaܸqСڶmgϞ1Mx<d>!U@d_>>ļ"p Wq?UtowJMM>i4OZl)^__oPZ{5j`pu";XfM5 4?#1z)849055Y֪e D*ڵk9s,Odffb֭.N^[LMMFFHz.35:M7ơG0t #G`hh\GG$^?:^޽._"66?3X8uTZBŋɓ,Rʇ#))m\.|| r8?9+WڂX|9Hyq9_gΜAڵKFOEi"t9sr4ڵ+v7nĉ믿sNf#вX}BHSPhy!{x5yx91]:wf?!o|>$cQAXv c//[^>흜 lF.^v1q2c'>Y5l/âKI:chؠTǛ|{2UyzzRcB*j^ 0J{^ | (]yP4]՜?077g;WZ!e˖%氺{.:~FY!BD5M*.bcb͍PH%)|>))wPaeEȃ*$)) ͚5CӦM>`ee+++7pp @V0|p#44ȈCx%Js7:aBbtMAtU)S ,`oo駟&RC wwwV#aE5M*δpRV4Q \rN>Moܹs000@vvvZŋc8*;DB @ԇj!"ar_/** /_Õ+WJ@ `^طo88f̘BԄa8J!R J򜴕gѢEHHH` 4kÇ3իWʕ+ظq#S:~&D}iԥB!r>`޼yH&#FI&1>}ߟ)Dq8?^^v$i"BWbXlVWv~aLA[n8vSڴiS &B!@n}݋GoN:XַofΜիWTQ i"BǾsvhǎe UڨÇ"-[Qg 4 204.LM~`;RQ'i_U(Ixm*}ݻ,Ā[lڷoVȦpOiR߿g/ jDd;(ESմ p.UV5jTfff*)*ӧIJ Ǐ?8p *4jDW@Vl!?QULlx6lZnv(U6o ;; x߿?бcG%D'e_t ;wfb#4BĢ0NB"5KT`R>sssl۶MPPKStSN:1Lxyy!**JdX$=BlWVUӢE ]vbS$''zRߦ={dܹ3"""BԎ;p5#$U@c@B!U}8۾aaa"͉K___a͓РAecƌ@ ۙTDDђylخ={a]{%(Ek@^0B^w]?9Gy/I]pU\gb ]g,OHv*ԩ= wwwQ#0vX 5h Ĉ4닊b;L6vd@GصgF!Y`\ȣпHaON£0\1wӿ8,]]tx_B0} B^^hke,O38yXd{JTAAAf;*<۶mC->Ƌ/zqss+/^  k.xzzQ2iJMMv-mi"322p1hp:ìCvF%s1& ^ظy }VbFƁn=qH$s+zꭥkVax ~߰֬)s޽E=70m777#DZ3~`̝= ٞ?!SPu k|}}T` )! C18s "jlO}"acǎc,f!URҰuxޞwmXhX{1o404D.oJƯ!0`>,[[ 7%B,~b/Ł W^#l& SaimS~06Fhf֍a>s6ȨvGѲd;pM sT}z{TT u1z{v>OH堊M>>h޼9kPPp7nĩS2ׯU?QQQL8SSS̲t35ݺusc{)]ܘXN"Ru-0bP <ak.ahh rb8:cAy#}tv(:55 N\,S MM|aU%~ aŲӓkL(C M~oa ,?!hIÇ㏂!cǎEƍ*z)رcaffM~Gݍ=ژ;w.b߬YMYҰo>1c!p8jcpb 6o*㧏Li_Wp1._;G|F(lUPKq8}'"`DX[ ^wBtv?by??5&Bib%Q'jٲeݻwlx<Əԑ vZfYvv6>}N:I}VZ7n;w/Ѽ[r:J]&/ׯ+a{zxM^jZd7*Rhq&t̼~# -4hc.^!ˌUH~=\HSS|Vd7xyz550~ƞ;`ll@t0o|>fϛJLRٔY?!}`UdLĉCux *$ʮԤݻC Y^Z5iF.xx1m۶h۶-.##8y$`ذayj(BjBΝD LΝ;䟧0g$&~= 6 p9>x22A,Y ?M3gCfMu---NI]q)&aμUv@~MFFHz.ۋ4+Ϙ?fLg n-[_~Tػk'jԨaŲ%".^wR?N(R9H;R=,==w;v Fypu!ݓ0p@p8DFF_~Tt3g$dhh(Q󼊔' fffppp`=yYfr(AD;3f߾Xz5Fψشe R܅vZppǚU+E0v,s5j4 :0;9Aƍ]>Yc6\G̟;k O!&Oc7>̑B,zYۻn tR9_|AKKmC=O?v¿D<|?!UfhM@ aGNJ}PNV;wƼy]L_25ϓyT߿ T!$C\މYߩ+:ut-XC .P08Ď[ƽ{7w/vyZ+s݂+u0Io +B#a[iiQ(z;*~(QԩSp5@NеkW6O2ݻwO)6l؀)S`ȑ΁ejjʌ ,,,0fܾ}s8k#ڧI (B19s,. e; BXA韐ʃHJJb̺H3GHHRI牊-v(R+:Dс$={;v0V0k =4xUuh$!JIzɓ'عs'3$z=RdZU',ihh >>t)P=;ooo?Sfddٳg4ϓVƍK9hѾBף(y*0CgWuW\X`ڴi077T5Mڵ+g033۶mC~pQ zfjB|3q/!iMc"ꧪ)4 ox<|>ƍWTTv$>R%<999WUp86177ǃp=,4%a Ν;#FPja_T: IDAT]]\A'77C!j,E֩v%P'i_:u{mOi=z% 5wÇ)$WZ_Ǐ3<}T}=^(Vw5jԈsMH&MX#ݻyO!8EGc/ej2p$ ^|v8D NmJ "rW L111000ɓKk۶H ĉp86l,,,}6 scPDyyyr[h߾=SVDEU ?D֭5B!j[nݻw%救Fsww;h{ݻw/w~777aԩAHHf̘5kOaÆJ*Ç}a OWz"""hҤ /KF#BԔ q_>lmmzT4 :rp@ӧOիWc:u*~W̙3rJ^GeCȻD*qƉܲݼWUp aB!D]l۶ *=|qx<6m0$yuA @ `ʕa^E YBExFffL:E-%%EU'<Ǐ/O ),4Q!Bd#`oo Ǐx ݻw͍)D ̘1N)HQmGU`p8Ȑi u'|x N$D!1s$UVśijj,'T|⼼)SpA :ѣG: 333gp@ϤbE+D!1ETV+Th{=iv ''';wжm[AAAHMM!U)¦lRi8"e{zh?OS> h2H_Yؾu PU($M/H_}:O L`mm-s111쉉8}4~ȑhѢEܹسgۇ#F0G)S#L> eff"++&hS 零Hfu̘1$/// >Yv`Go߾ ɤB7⦦SRϩ$ y Y 2Mm{?%Sq=!RSӰ|*yX͟?VVV܏i!8y=U~^c]YvF"ѱCeG /0eee!%%K.pqyjٲ%s&MݻXp!x|@ƍ%޿kGvr,\CvFnѫp^qf]iVw,>D^hg~#v 8 O>st¨"KA#Iz|"i([.+`a􂵝zzC%9y4.\ݺbUYV]]ȲII8~<+4%^S4QfQgaCq\4GA 𿵿[X&3f۷oXlttt$ڷk+<.4׳y6xzBy=, W_[X"l&\eIW}ET6Xt芉SG"u{6dr?Hz}l]Pzue6,YZ?۶nӖ-=W.ȡXSB\N\Gܹs>}x"Ër\Gf?M;*sqI aAU={ĸqT⦱I&1bx<,Yg2ŋ"IEJS {ndffbAAAr=** m۶eslԨkfMiy(4}?Ƃ tpv  5kք)By8rͳ :uzhkeukVKt ;{ ~}x1ǎoSdp:jb?#.>;lܸ׮]>}Oe:yJBk'y]Opt6?g6oʬ‰˅\̝m%^cYӦcpȲ%o%%4!$uVKK^U^ܶ;EwtG%[t \hkk!Ξ+}5kD۶V~V͛Aj`gk,OMKCY&oE)HQygTs(*?&% oL)ԬY3[cƌ)s.]&'O)H]|~hhhLJ?88/__8ϔ$;OOO ϟ?Wj3KUQ*[@2 9^Jq!}jjPp RC{ymİ8x(ݻ֦\;@c@M:wFpbax4tYcy6ZL?rW\\&Ob߾}P0,gyEk'y]{G{,1?6\Gm%+XZ|ٿ+w:+%*[/ǰYfok[bV-[۷bǠl: . :FMp_ݻ#1QiPuJ;RTY;ʏՍ7Uu+++i޼9гgO.!$${nT^@Ź?:: .K._88&҂a(F8""B.MiUS C |=Ƃ [F>xyD\WbD? (ͯGw;~~уFc5?01ԯ_ѩ+͛ѣ?>RSS1br$!͵ɓGVUku u]ERCyء~6\q \z:̜!SQygTs(*?V7OU$ i:ѣrfn9΀FD,(MRTlʵ`ޅKD1F cCsUTcc!KD PD#&"_1̑6T=<23Y^͛7`ƌET&zϞ=߿?shѢN8V'NX!J+?ܲ{Ry=l 6mقl;8Q0fH,];ca:u񦾽{ᇽq?CޯL)1\ƏC]kkͽfff-ŀCTɓ'#77-,Xq4]]]Oŋ*/$WSC$Rpg'yaV2ueHx Β^{0..H^$].섿 no& 7ƣGVޟ ˗/q988؋9Fa|!6n,>明~n]ٜ* >!TZF%<}ti| %MM7.$/_ I+L7F\?zH[?_HRf} –s,C5:KzzaƎ_ᗋ_.^,Uq}|.ծm[ĬX __L*Eذq#6ռʟ}},94=fEVRJ^I ~vaʕpww7E–|Ԍ3?Iիq|Py.0{lxyy޽{*- 7o4 k LG799g\4?,AѺU+D/ի1g^$>>xo8qwCaͺuHrU-,Q^1ҧw/,^ޟ4ǜ;[tj~cFļ|7cӧayx!rr'=vnܸ#F_a46m..g1"B~ 6aĉ7LN`l~7ԯ_'Lǭum-SXkuJء=?~O>Y_ G m SǪ]hZ!fJ,JV;MYshz̊J.C*}C/ׯ`d2vڅݻw TW>} t۲e }W1b֭N9X=u-lٲE|ޭ[7nZwAW0/!QWs8-U hح[431Sy =}u u%_N_FDLI}M3vEԹJKKCƍyӧQF 'Miiiؾ};*yͱ/CϞ=غp׮]Î; HЧOԩSZ/ۇc{'Uzk.R\V{\H%UI+Z8Wح[J}LUyc(11nh[5g.15U^TPnoL]ƍo>\ZB&[$ z#G ((H\~1tرcxzzgffE*d2 OOOc7z%D}WWׯcǎ:?n$@t*Cy} q]mZ?ŃLԯoA`xh*g1b|RRR&LݻwA1.][moڵhҤIߏ` !!\wFCC/-4 S{o^ L&7Ыd2;VpL^~}F y4im֭ $Y7o֭[(ZF |'fffJWc H$7q(e͈#T\qRG=ͭիعs'L&S)b)D4{Aq4ԪUK/ KF*e{ŋub%-,,s/{>55UcGD" 0i"""*޼yUoootcZЂUG?#D*003f)S 11 5jywwwܽ{We۷oq]deeaر=>4(8߽޽{HJJM˗/ jժ@y,ۿ?.\ ܹ.## -:333g !2yu)胩H$/0 &`gg'VT?3>|x-j7.|20`@{WZΝ;;]/V 7 $@l֯_T \f͚ė8urC1 yELXTJ\IIL>#3U,,9#+Μ:UJ8|0Ο?@1Pt]F=;w>駟0>&75*ʕ+صk_~&={xlgԫWR)sͯ\$MڝU;w>E6:u @Moq{F ;#$_о}{tX&X.AI9&úy& 0I&*222QCEƍ߇įԨQ#c`rL1vQ!I} :ܯ^OҹeSAiiiؾ};gϞ.t۷lTSYYYرׯ_gT} O K9a*3d2.]ի  ֥&T{U*Ta ։'r5cLa)\[8ܸqCA߾}ѷo_jԬ [xzpe[lx P͛7accwCCss$2q˗/cE I&ؼy3tv8ԩSQF }0L1a*FӦMş |;3g///CW.(JKjĩ|%fx8 s"#!J0a8GDT\o-7u"5-Z,tfⲡC!66Ç+.۳g7w5k1@Bb"Νŋ>3 JѴiz&vh2FN$ ДJ'^zla2 H}}:uBNdž !!!pssk eD"{w+3U0g ^{{;̙%è4#cKܹsn͚6Ef ?I0"vغm;GF)?Wѱ!EwkR0Ho $4gΜc#FhÇヘ&LFSUV>a7,Pgb-|!l*co#&&]am3v6ʟ_xɅmk]7(@rr2mڴA׮]k.z #F(VʼnkKݤÊkBك`̐+ì#Ow?qC&"{^a?T<9J5{Ʃӧg8p#G4X8Q U}Eqxw_s6>St iРN:W233)&I'_03)xt̋?OBHHޮI䀱KSѽ{wd2DFFBСCy'O;r)--B&LB&1a*PoӧayiWĸ[B(w/:u펶f5bc#"*K\oiaawagk#m>٣n=qyȰ»!*s@۶ذkƢYs?{xbҥx z.OKeZnTbΝb7 11aiG1njdfV +'YΝХs"@ :!"*oEP|߽{ǣ{nxvm~5Sy֭E_$Fg*7?36l؀1c{ 8Wƾ16U?VT.y%{[4Q<=|=41lG[SN :tȈş5I._\&cbyd,v9r$_&٣͛w^#E[z۷oǦM (&&LS̓SjsB\"*GVfMz @\C WU~Dhݺ5ƍ'&RCTTD >UT1v:t(;>}… HKK3vHiN"(rQe5 DT:qVVEne+))H|9R._FuMִiTʞa*G={asСƍ;$KOOǕ+WܭQ[L !Q w{xءJ:aei[nw=ӧ YVVMXYU]۸71`DDm6>#,ZȠH$v E=jxʊ3gbΜ9z;>[^KrYmI5,O*? lm?4jd@!6l &>?<\'ЧOq}ll,lllZ/$$}vLof¤W{{OקO;vL7tPC &#a¤;yISGDDDDԩ(ݻWLV^k}AI&?.QI .yDDDDT:{.pG!** uVn%i۶-fΜnݺ4J333n:̚5KgǬȔ&MDDDDTŋxbٳg l`ܹ/6l؀Ν;$NRd (w# @[_xx89RÄIC׽{wH$v!~7 Aٞ֘223RDD&vڨfY v  QӥK7۶mCDD$ zAgmݽ{L󴗑 ТUcBDDŸ ")lSrrXo2tX֝;wp=tءkyIFvv6v6vDDTؽs |}}+>OLL!!!pssS'55,un޼`ޏMyT:GDTv>'NĢEc,Z&L@bbbnjӑDVZ%k͚5puuEʕ\]5k+W ֭['+*7;w#GD PR%8::b/'OD```hjҥG=PF Xti>|ݻwGj`cc+VsIQ{Q;vă'.;zC,L&5ڴἠƑ丮0=dD/_ý1?œHHL70mfςnl@n]5>d+C Ahh(XZZ"99_} AJO~L8k׮E`` =zٳgcر|-[_|ظq#7o$9GPPPcٳsƍѢE \p#GDz5%믿bѢEz)Y^=<} 4@-gOǼyTٳ',Y9PfMMDDDeзo_qݻwߊ_w ڵ{,Ekd2;vvvzfBݿu&b*̙%sf0j81in]Pzu@//,ZJߺu FZ-[Į]޼yFϞ=(*|w[b֬Y'OYe]LL :t IJeYhҴh"Ġcǎ;"::_}zvJ[7nsi|ӧOG-s>|Xjz xlllTG>ODDƌ񹉈lkذ!f͚ƍضm|pppO?$4Qhr7;axJXpC0`tM}}ߺ ԩmhj'MMbG.] '99YL`"p;wVVVֿmH mUX R```ۗD?qMS(TRÇ5Meҥx)>LOF $/W\A||<ѯ_?72.)HPJ`B.$b-xNq˜?rW/jE\| Sq5Mؔkaog'OWظis奊09aϟcǎ탧F,,,J&00oƙ3g4*U///lܸ qmyzCm>|zxŋcسgK>sQФI%HJJit,4HEyo<l bĻ;8!#774ʛ+_1`hYOi7ny,3330_kb6m09rss'N<~`` ߏ޽{#** CUYuNWrwwӧѧO=<<%\ +Wh_`oo/>oӦ ~GL:U\?߿|wعs'>UDDDT1~~~tǍ 1bDaJ v3]RtP=O-[>,G}xrrr&Lx' ''/_sfm,B/266OHP5{8r :tHer5{{{=zȸ"""0e8p/^۷1bĈѣ㏱fu|N:/^ɓ2e >B7}t|8y3gΜ˗/ #44Ǐ/T^p dggػw/F)S0o<` 8;;E$0{<<|ryJ:>̛7Vڷo;v.\-P)%00Q~}̜9syxxҥ ={&޼;v,߿;;;DDD[n_~1n8ܿ/TZJƏ/ &LP›w U\\g__Z =zǪUt8;;c͚5hժU8p ?.PzXEOsq7&r:hC0E^@"nPEp9LxCiyp"dhжuMt;LSjo+H,<&%"""""*W$ω_^L"i6kr$4ivĿDDTZR@RvTjpIcADD%8u, (ʪ0cg23{޸=seV¶͛{~86t2Zʘ4%eyDDDD|w܁K8sso!<<mU[z5U1wkۮ=֯[#?BP}v˛V`="""")u 7oD~n7id5ySrssNIE,,,ŋHuy7. u ͡aCLK+ש)IDAT_VHMcCx`ӶX ˗/ѷCB^ڦݴXNDDDDT8]т!:_q.])SQn=HfHJEq 4_3gy8pBZ,P;i2Gp/\^cՊջkcw?aF]Si1i"""""в &԰0ܸ Ϟ=ñc0l0q;gg'lڴ /_f#r2Ϙ8} />##Gŋ!=&M$xt̋?OBHHN A@By% 3~+>w?t|:c~OSClٱGcF_LH/rJؽ{Է1c͚7ի1z(qŋΝpukѣ`*/*۴ns`~|4jAMq}@۶ذkƢYs?{xbҥx V0NT؝w 3Kj=*W,n Vk`k-;vbƍXk4ImH>Z H9tsۿ?rssJbffݻ.m~s W|]5Q =#nLSCKD'(TtMݖzMP`\n9hB:)$s@, ADDDD3rAqOꓨU84eܖL ZVҒ_/AUSھ^LH?BRҤ1m2i"""""Y&^ R)^EZ5 s!53ëW ]enn_4)IQhDDDDTU•x5gQ\.Ǖ+nUͽ[Xq" wpNPM4cўAfʃ1a"""""]qpǽ{sb>}fpʄZjʪ:f_}|{Wٛg./+4wh?A \41Q%""""qtt4vҨ B u5C)H%'""""""$ KI885 $y ^wKDDDDDTIHr$E"DDDDDD*T&D@)(J>'LDDDDDD"YycZB 󈈈fKv&""""""%ki*l9[HJ꒿.E!χG$+3?-u=ŋQ>|ŋpw( ;vbr*?mYjV:g_]BQF3,]1[Q *Æ`@u&LG0qbexrb[5۝1N|6b0k\EddƏg]E{׮]ƛ F;֬Nz w˗//Ѿ;wq +>k-^RXdl>yG{%KZgǎ:uѠ^=ڶmɓ'ٹs'I=Xk+V`޽$ !R[:CJJW>Ɓ*,.oǓʔVƁdff0n8֬^;[I5TŎj`H`Lzԭ 1 ,C!UrHKMl6c˲۽֮YKlV4/9@fj ;tZ0(:cvl޼@y/&??xEQ8x0vC_{͑MVz*C^| Ya$Ɲf0o%5>/t4G6C_{D.@>9]CzZ*`IN{gϞ,p zDBqU),x8n'#=ׇδiJ[.y!cܹvR筅cp0&G}ukݜNqx٨&Mв6_olIJD6(J6Lng۰; X X'0hBxi͖͛('RRR믿 Ƞi&GD_ vkQGaϞ=DGG{=J5SZ232.jBTr˷~_xW0Ïp:LSΥJ[VҥKŗ|5c& ~<wY)vi٪?nBUtΞMlWU(t]%6¼yo0gpb>ONHKKcժ+E&-GO?Ѡzr:ƞ-B4"##,\ c>Y'v_,:@JR'##Ps/O?4i o#΄  f'ٲekGrIT ÏQV-23 ]ZH̛}ʻ#FApp0͚5㕡gZ`3ax>9jժp~;.CFhh%=^zL|}}W>cǍ]6$'%zms{;0L0:_}En .p}^p^[Mt:ի˗-ĉ91ztBq5*.[4-/fZX:v"3-ĝ9kI+q=36I-WBfOKO2zu{]r"+uN˨ /فiĞeϞr}qdq:4jl6c4ٱcDG7$*2DcBZ __?TIFz:g<ɛb!"VN'gtwm}}~͚5TltOjJreY}|T% _?TUrAٳdef^ELpF#v-7GV->8+08P,+rm#%,)4|N,RϒYU>yBtY:i=Hkjx9u9B\}.fnyQC>z@Qj:! `tB@ſTl.wbOsP Ԫ]mXΜ>MRvFEB!H ŞE={﹇5j_LfǎG7B!JbWCyXF\ 4@Q\unk B@=dZ(|9s =rT4 ֩CDD!er=!Buw&}l60:I^=B-s-Q ~%{%,%s233l8NF#V___LFcB+~1Z ]ױee(]ՅB\.fny%Q5ٛrZVIEl2a )S!>WZ9R]j!bW|9IX'B!B H/B!B ~!B!B_!B!_!B!%B!B! Nn_n 7)+X(ɾ(}~ !Boe,WZrP\}^2˺ma4M?O?ɲ٨JӦM>nժb]v;3/ƩSfZ4oFM%.WR+W !B!((J7Ғ'!/\W>fnƤ_^ pN~wQZU32M|R%%u%B!B((E_\K+hҢo)Sq\]b-gړZУ̝7kyn~*oLYӦb4mWӽt;74c yevLv‹$xm3w|zZ֞,yaz~hE.ƛ+'+WrҤE+nރ<7:t [cr'%Kd[èUZf3!!~1ʭ[QSa篨sƅ?rs[\cS{+#B!r]In'Mb믳ajN-[2}ƌKU֮[Ǥ_wٰv5#y/M+tVݽ;{㧅 yr*k /NJKXd1aa|<mL{Çaj{w8M_{ԩ[͛i=:Z3O b̘:M[xʫ4o֌hɒcQ*WL̡Ůs며WszcrjNΨsÙ2:6%U\?B!B+rόzV5@[K2=> ? =띉_XGkΞe˖!/Zܬek֯]b 7aԯWu3Yb6:}3{a&8\wggλXzg}~Gx C˶~}*eWwiժ%͛6믧Q1Gz*BGcҥs':+Vsͅz-~_B!B\y#jef}AcJ@g?<ș_uUNJТY3Zh^aS=^y_k֋=͘>b˖MNJxBm;ý^ 44s;/G{oihצ-UT.r[W7kʪ5kؽ{ ~^HZZ}5b]O:Fcbhެ:͛z~ }罖r|Jr!B!\I*#򊓙?TXS~ v5k5WԼL&o74n rJ8N,sI-Vk_x~0_Z+W3zXzr [zopŽ*!<6%q% !B!.l ~t,_R+Tuټuk6o)bm0 4BbVL+{W] `0kou)sqӦ Sc¸̟=\xؾ= Kr=v*֭S-[yu[VKul S~B!%K})&|?-ذq#yRU'Qǰi233{fF)|9Ho؀VI#}"==A<ߛ6ٳ,Y׬Qy?ƞ{96p@'A^L?ko,3[,233Y_ԨqMq-^BRRNcǏtr~|xI_E{Qa֭deeeVF}}]cSRe{G!Bqik ~iiݚO>Ϥɓyo(tM*,FQswЁAaoOTT$OPh /0⽑>}k=Ĵ/'?0vx>JʴiՊs/vG weT\12_RD {g8DFD̠Ath߾unղo6 ~ʡC RYrTvڍ-Z4gGc/Ӄ`{c&<<̠Ox)Tsڥs'ƛ'}<\cSRe{G!BqigoYZZfW_;;]2G!BS1pDM.]}!M&cblܵw{rWK!Bvɺ oҶM^~5ND;+4Uػg.u )sWBu\,]7hz᲋龒? HGH|r;ΑIU"CtnmMlJזe/&)G8[2 ~8]X&4qIspfv$;uQͿJoDčEuVɓ'QU.EܳgϲqF |҃(nݚ עEh֬9YYYn_~֩q˫q/>ꃉѩne^^и%ݯsŊlܸT; " IDAT;;oɄ(uy)``0,vϋCSR.αtB˽bwo!oFp!- ]Ǔxf ~Sqg0~x^{b,I]Ս-ԨLjNil{53M и~b ϹӨ[kb iYSO/*UJit '0fԉF nr:OQ~93[?dLFe`ǃ;7ײe˱Z ` l6zB+q^vmf˖-lܸo7x#Gr]wDx뭷hݺuĭ(e`"ئTqzNZqK_eƍyKU#F?Ѻuk̙iG5Pi;v jWjjt}YזWE__h !ɽ.to-L4شu' g\)z1')r4Թ\NΥiN2FQGu_!q*${y.OҠ^]PUp:dfesÇ֨4A7O7%W-ǩqeh[ZDMfn2uiMDDMj6jveg`0O@v&zLe_=88ʀ"@6ԊVd$-j5bI7O7/Eټimڸ͛6Ѿ}{,Yr>N~[NBb"* (+gv_&<<JÆ kHJJߟV+O?47m}7L2уaÆǢE 8~«▤S48{(4hp~VۢYp88~8ޝDFf8|PÁVHJz3lNޟ<ѫ/???222.w5W'IBW{@xX%o̰g-W[UQl,.DNMϋ4{A$k%Чg7*V*26efe06\N.8vU""2#'/ﮞ)nۂԳgPr$`0$!|:l Mo~1[ѵz Z.$99`pT>;֘3;ƾCɹBt9qut6Tm&+54݄ն*Q]K@Z?Y'-w[v> 6#ؗvxd&Kn*q<ٲٝoߞnI/m_UQ mwQvݻw}|Me:N͛S~}wEٳܹӳNRRzѹso˖[o˚5kHMMw:Z ___N{=nFBy~ZpC2.7ܫ}h";HJJbժUԨQcǎѣG O?-VZ2{~a@S=zz@[SOEQ<-ݻw~`ԨQ <9_x| ?wy'.oGrL̟??{ĭh:ztb/{&Nms%$1-}x#,څ+r"\8B!l݋󲧞")9Ȉ ztƍMүGm"ܼbO+Y幷z5<#1@5 _©PB-dXdD(~Υ$mpdj1ۃPp(j?1HOQcuY!l2mtUQP qӷv/ph%̓2^p޸~㮹4>Ԗw l "TiIj|3V͕w^Q,*[NP%E嚆^'&Vd1Mhؘu\ߵlq7ـ5L# ޭDF?g?)t N\_xX8Fӊh"<,J7U3`eO?n?s VJBB,w^ۋ0k5i(L͉Q3T\եpF19naڷk+xEҥK?*"ojD>I~n~r9qbl2yzb6[nw\޽{V,sΑd$N "Tt|?#K.[ne˵k H9@#ĝ8Y'8YfРA;dfex`b6ybdF?1FbcRZFaq??}݇i̜9=е\׵OWY۩KlR̴{zɌ6]p\8v6F0@9^jɓL4֭[y=үŔ/'cy w%Kxa&L@p߇ xաL%;{Ʉgn6lѣG7o#NDD[nRh(v,YjժtRƌ>I&l۶AO=]`߽INBKWoa€hFQ (g:u=tj\g>^3wEөqx 믿رLb͚5c֭ ziªУGzy{pq﫺lro0år">9s>ǨXuQ3dܛ(9u.+B ω,~y]G󍐊 Hـr?fڲH'..ظTET\;O;]]+.nIJ-:<͕NXXKILf¬xݩ aaa{>:ƽᖙ2cѵӸD 1TkN0XBqSvbP 9CvSۏSs]z fTz@jTVt')m \͗&Ն|ǴUڸNznKpn+>dh4b׋ 7XYN8.:uRT5{2w`q=}8/=ҩ#&Nk.e<M4_hXn+8ί[ֵ?^x3?lfQ\sMu!+xy/^8'w<+}Y)\.ϟh$##oֳxܹFrjL/iZ ¿ѶQ%ʲtUU<9.ma\N['!ǬEEEx"ϺkV,3-更mγpͷPL4+L>3g…\{]veŊ\w]~wEaɒ?۷/Knݺ.F$**3nx>=mЮ]{F?\LdB!(g1[(MJN~tNv{=`Y^Wޒm){٤$>3ƌC:t> VŽޚaF51jiK`P[V(8S\ )sL!QAKpNרc 9{NE!;K%%8ժZ BFc^;sOedt2( j*ԮsP2. M!bdO2ŜWJr|o4Ϭaaa19^|797$ӧӷo_f͚:(y܊Z\YHNR0 0>*f̀BL;Ii:G™x4CDv#GȑLsN8b$|Ԥ`k.:tPCʕ+Zk׮L>A?y衇Xt)g N:G6mks\:B!D^8Lhe#YCUݽ'6tR'3= [{^7ށh׶׺۵cEW[6DFD-8:uumv4ͅ{gf+=_Ieiߑ#8]:uOa9NBY o*_ ~Rȶ=dwAEM-CE=cz 6䟨bxjݚg۽Z=e#]CGCʡ#?߃9=ŞN6rM2ǽjbm'fCWݿp]븡 f4݅ &Q,m۶6mxYiӆm۶ҢE")mܼ]TKN'&|||P]hy$F F'J_m&2Oy<_3FvGuϛ @N 5ziqN*. bgMl~? o`kC1c&} TtؑN:t)f͚E`` ~~~Zڵk[v?gv;.`0P-=^ -gs1_SPZ0L˥rX>&\[!#kziۮg3>K=j$UTrQ>>>-Ծ][+֯_M]<DZmvMJ;Þ={h׮m뒻{v~tBQ2 FRjF?ŪUG5lvb20M{,TWݱ/ν5oÌ`k:D|J>wN0jHoЌY ҭ7ҥRPMTVrzF6M*"vEt/cy8+df\9r[ W9 }vw+gnKrֹr'n%HkjVרz(8 _슕s 2S7b$pF+>բSF%LpL뗶7:uġCԩc>O?i|S:CIV4M/8iM&57aGZbj+w|PLfP SMPUճl۶m̞5 ???6nkۆ fZzY\m۶oGaĈu睞eь-[RDGGchѢus X~o_+r߁BbQlY #͞Ġa34.|8~t?Q*#x*!%ԭ[u{uԫW\*\{kUw`56ӶmԩjdY &3 :8 cv"A` BaQ{.Ԭ ~fp*ΜhT23 9P7:'!əsawNWrGh<%QjEuV+GA۷ piOX޸yQQQ; ՂbVI8 ׵ʍ7T tY`ƄI73˼\X'N'"&&+3q2}o>ԩ 2}TW^M6ep<ѣG`tO?yӦ8[,C#:Y].alW-7T港Y,\Ma;h6! IDATnaoYg؛oxԨ^3qxc7^r_φFo w:=N KޅSGyׯ_hlUuiӦp84/MӰX,ddd$eh-uR/bWиE{5kՂbr|Eӂp88r#{[oճvZ̚5Gy+xm/3`Zhۦ ?>+ 74fw;#eKΌ9#kحaozBus=С c39붋ҦP(L0b|QPg4f2| 5a cg[mZQH*[*-躷Vy?ϣ>gyϽs.\(/  {qbyC x^ ńᮘdgP믾‚::-еkW=,biwo40c8T]]}~=u$%'ñsg1u鉿cQof-ZLt1eTS֦f"u: >@xvq@eE9xxWNf44J޵dFG%/^jȬS-e`f? f0kd WSE|^4|)޻SSSUmkk>xŋ15(ޯ~a w1;CBMD<[uww̜1ӦMGnc1i`RG ߋ{qD}wo6 dkeeonΝTdeeM@K/zLG}ޮ}pq pAk= 6/-@[f(+磢 EjT>A_JY{o8OZlo/| #|>:vχiւP2zy{c"4rћo$ -u&I8ws5kDc?ͷySGaӦh}vlAp+|<yL ^Ok++W_O_5He^cG=Jk"kc=BCCk.J\TUs_ȯ_^o{^eg |97 ;+s_)OMnG9r\4ũ'D&N("?)/_)өS'=|`em-r^<[___IM' ȽZ`ݢ |ڧ+V_ f2Io ?1[կ*P?VEE#3!v톋cѢE A.3555r[6t(>ÆK\46uk@m(E6 ކd!RP xnrxP޽?޽Zo`± (K/cF{&Fo.:mTTTCh(첶7So~)S::v PQYm*n`iiɅHW_SsgLܽ{߇}͛3u֫,jGu %Հ+7$n%U] zp[OLÏŏ˗ET9U+>Eju=(EG 4ꄓ1q !ġ| :܋ 썏⓾  x ]۶HspIgp!1Nq=C~OAC+^F!t:uSZ\\z{k^ WiGzbȩ4FkruloK]] )ĺJg[4S 5V%U]Q"V#fw#ܨ T1q!AADG{ #ޖ0[2`fggWOW)D 7@]׮]tرFϲo`dJS(,ATTTPQY C#CKzI{r7;ڿY&jS& D{qPZ![kwxQ5+EH!Rٱ3TUv󑒜###KzI{gr7;zA󄒡& C!h@WE8"%) ׯڊȐkQ6KOr4uA115!:K_huCQޡj >AoԀ-)eB`C  Cq3봊XBoamAABA|PAAIm#>'H+  Ϩ=:10>| 1A|bUCM U 瓃OAAAr/TTUKx)x  ߏ !220aڬ+K.~~~wRSSի: Dž $Vp=^*hCjjj& p>=gPM hx6oތ}BOO077ѣ_ȚJԌ]vk׮ž}_g vqeN:Obذa033?nܸQg[׮] ;Vp= 1p@ڵ :::7  Χ|# >h?XxB$#F#GtRdgg׸|2І2gΜ97oz:LII= SSS2=<<-ZDgϐΝ;+E#hii}زeH `mm X[[cӦM"<֭C.]իرclmm 777שν{ CCClFB~~ݻwZZZ011? D썌444`cc 6ԸΟ?#F {ĉqu\/|}}/L"1i$ի2e uӧܹs8bl"Qu,ZH5xxxGسgNsEE1h 8;;cx1(,,DXX|}}"d4(//O?www8;;  Ν;2۶m$xzzgϞRC%5}AA|̜5fͩ|jEQ0` dfr30p P\,?`l \~%aDrr -)) YYYEn۶ W ǎÔ)S|;wN$Xd 6n܈lܸb{QPPOOOxzzb͈F^^ziӦթM6X`̰0XHHH7|#?uBCC ̄6mBxxXȺ'?|Fee%=zm۶ҥK8?** QQQx ''QQQ8t@1c`Æ HJJ…  {.p=10b1C ӧQVVHLL1dDDD_ř3gNlvv6rss1uTDDD ++ AAAmmmaff???x{{]vb.2333Eٳg#""P}`QZZ\\\#77lbʕ ;&N7oވx"v)~#\O*AXP^^r|h "x|cGn岔aV=˕{ھgƍO7_,%ھM؂l5vrȡil̘1t___%R1ƚ5kJJJjj'5w"i`}ї*8/,,W:y377/Rɓ'PpƢELNv322ommΝ;'1͍I/- {XٹsݻK=RRRdAu)T xnV{=/gs|}G3џѣ?g?afdL0dy199D1x!())7rx!"99/1uq̝{"++X,,~]~[LWRR.ށ`d#L9r1cl"hЫWo0wجvZ\AQ a$l1>,Bc%oFzz:ӑ r-x6$&&bRSSSѯ_?4wwwܾ}[$N𿾾ĴϟשNff&`ll -[ B˫ڵȹH͛7ѷo_2@j666x8vcǎCRb޼y4h\]]aeeMMM6LMM-χ*++k."55 Gf`eeŷ~hժ"#XYYaĉXbrrroƵkפ@hvv6444`ll,Vvٲe~Cy))) 6 h\m߁lll߱ >>]8AA1hP H^>#8"">A~~1;ᅬҥ|1inׯ?ajѣ{(1w 1L<=©S Zl)(PQQAaa!zQF!$$FFFX|d >000*GىW֭[(Ն3g}2ۑ\r %=/W"{3Q̹8 -ZhB޽Dʘ@X@X[ys gի=r5Aᅬ̙ 01iS{SV".b+W&9s!!h^00halqꔿv>{HzN04 Xz q xyyI,3n8,]T麻tKԩ؞䱱W-pBijjjo2y8::ŋ"iv2Eyy`"Z pY`Խj>6Ցc֬YHLLѣGEFKKKUرC0~cʕpss-.]$guo޼9fϞ8̘18(..FǎEHsPZZ*z"m۶ܲA(IbziiBCcѱoeݒi„nbu]]q޻Ps1zXcEoWdap;47HJz"8o9sN#'A|@xEII ޼ySJ#-- EEERdYwtt`ѼbܺuKydEEEr@ )K=,--%-GA_$hFGbgqJӧ߂|Jћl}fxDp_֭n-nV ڮ"8 W2፧O_z:u 'wSK1/(<®,K/AN444pi|'3gZn mmmѣqHy軻cժUXp! 1h G /> |w곹ٲe v }}}5 _}UexxxÄ ```ɓ'odŋ駟0{l8q666e-[]]]rvwesp m,A|(2zuuu̜93gάlaFQFI͟2erIզ؋ -𤵻zI0i$/R-Ut999ӧOsss(Ǐkkkhhh9?^x!3޽x`>a p-m۶~qXXA)))055EAAա%v3333g>|(_}Cb9*b!!!3f̨ADի"*7V5.HΫo|%KZZ"#j%k@K{ },gOy8|.LHLMM5tj]M "6 ؾ]޾>\ԔKA4 LMMhae2WШ]ŧ~Ç|Pmԅ{qDA|贀+++CRbR͕}_/sa3N"7yybddHEGp;VuA^kڵ 55Z~ Ŷm(((e8w%(;|矯M 'WwϞaak_ԪY Xz 1Ý;wp  piPjO٭O9Vlm qH/7$%b!|%`!*,-EV7 IDATvf ʄǡCwЭz脣oQYɰg }{~8wh\~xw󦦗   hp g` ;wϵ#~nLqLHڙ3ѱXInww UUeKAAA41x :lF/f7/Ɓ4)3gjl   AQd۔go˖]Bx@߭M# hj#((~~~|1ZhuuuoƍCLLL툎G}---o[l߰akkklڴI$aݺuС455ѥK\z;v쀭-:չwahh-[bԨQ{n8;;CKK &&&GAAlllaÆ1b899wޘ8q"_/}ZL֭[!8/((@@@={]{Arri@xx8 ggg?? /RRRDtc̘1Iɓ']?lٲEUǢEҠ? ___dff 322''';wl۶-鉞={"**JeQӗA|e M=HNN%%%!++ Hm۶aJرc2e BBBsΉDQYYGa۶mtBTT={ATT:$~DEEa̘1ذap|]DEE޽{b6 88(//Zh]"11Ɛ!C_gΜ8qԩS,cvډVWWqUAڵkװfֻ~È#0b 2OFYY4"{yy h"DGGcو5TUUiiipqq*"""\]ZZ+W"008q"޼y#ŋعsCp=tO$zcn=f)l5 ){+ص}7QLFbLG;FbÚ{1kk%..VV2jcij2([Qj[Cƴ0]Zl,cΘc_Vݺ?kWVVC}}*c&1fa:c[36p c|V"\$|vmߦolASav;9QP4ƌ#HeQQQ"ecYfD&}'5w`X>}D %թNu^xEdNjy 344h23Y}C Ҳ3p射cGaN˖-֮];vivƆ =~~Z>>>/d'Of b1z~GA'N0޽{Ʋ:ggIm?c;͟?_pVX`(++cۛUTT4k׮1###ܹsXPPļ/RZZG;w.޽#%%Ef4h[nBe Gݹ}SVJXdv#Ty$@f&w8;53~< i:tY_@t4%mw45kޥ<} :<~ ^ 775fZƶz4 8yn,7uҾkMܾ}HOOGjj*|||1$GmHLLĀ槦_~"i}H}}}iϟ?SLxyy<-[VWѵkWsccc7oo߾"emllp1 ǎC֑ży0h mmmB[[[bEa͸x" 555">>rh֬o1`8::" ZWdDEѣGp~~~Į]`啱ĉb o߾k׮I]3#%%lhhhXepuSRRl?AćNW6z ܱp!УG|ȕ+`̘Q'A99 ++@C8~\ܘ1W^Ν&aҨvBOvq)P:gpЧl!UmWLmmয়;BWf_7qׇ0x0Uʵʐ)kZBEE .Ċ+|r|wu[[[P*9ҬYZF^:Դ΄ `kk"e>^E];b۶mpvvqL2ӧO+2^V95Fee%z ===@||AQ  K._XmXٌ l K_{#v+ce,[my7ڕSBGG;w.JKKw9+C΂6nNc6@M :;:PW77kc9T-[G!( rΛ0ws/*M_\TX[YY5027<<[D'sh`<>;MFQ\~C4Ć^c$ܹۖ~Qkiߵ&7_7nKbqaҥJݥK?^j~N䎍m? M6PSS舋/I@傭Ɗ틳gU酷1$M;w`u3WZZ*bǎȑ#077ʕ+[[[\tI۷:NNN(,,Dxx8|>~JYGD84~y#͛7ٳ3f`߾}kGKLcǎ"z9eee(--zT\׎m ^Aʁs0 ̱g0p>Q7ec^ } >v10j MMdfMٝg%wDtџ hjøxY}Ac?^0\SSOh7sG4-Zd&KZ$DJJ8? 2ltut*vܯ,|\,^C3u,L΅K믹:{Yݴ=^yGkOFkb7|`oυ߿|)7j%sZYNL|9 TXo}p"㫯Pn_O:WSp/5Ew83f/0tP˗@^^_k>}:?" 53gM!&&ӧO|Xe0yd6o޼zOhEn=f>qƻE{~>\?/_'Oaxi/O~}g%Xe U֫08Ygy)~+MC3fx૤i=DA˶-QRX5k0=}:ԛK?#vލXQ[֭n kn_rE 39|{h3':^"E?ahss%VoɍlBNRxnE=+ } ===###" U iiih۶-t~Hװ¾}-lOgϞE@@\SSShiinff&q˗/CMqq13f`ܸq nADCg8vpJ0ƐTE׏j+l!֪z7CɳXm+&SR`iI5&?8 '=I;`c/չ;w`Ϟ=EQZZZFݹ>+(ٜ#od]t(M!0lxgB{=?Yy#åkOOEWq6{EҞ>*""/.Lcu\()7]@/ eu` 7-cRn^e%7ETHiA(SSSdڍV+khhڮ aɒ%۷D>+J}ͅ.>S>|Xd*`dd$Un.lܴ Bpr#iT9GBDw[i9MrBx+&rs:"qk"!~s<vk߾}ؼy3мysR}[:bYܿS<_J3"i8xxs@]]9/ˑ:5Ι|qsWP̹62[5r\=Mh˚͵SQג#n4_ FF۹ ÇBF ϒʔA"!!īW{/w;w$:64K( *Ѷɳo,cnr/rh3.M. 0q=BVRR"Ykv\b0_K>\,C]uPA#Gop..50-\x` "nI4<ιP|wi-9Oj/YMȑ㝘ȥI95ZWB3+D}rEȓ0ҾkA ÍZNAoWox!64Q\Pexpv %(4 ]Wſ ., w<<<0c "//+V@FFzrwr@z:7(*&Op.3n55Ai:j"zdǤI@~>wlW¸;wr\3^~)>.r'ܱz5}MBυy[jxXs%0` F/MN=ĤI_EPv_:;rkj*մ%!FAAOh#w|nE¯byv\Eu -4iT't{/{0mΣ#[6vvv}B# r;skmw7mun팀:4uŽ8}ܜ[t/* _qBCCn8{Cw\cp/*ΝMOHσq#vݩܱc3ދVVmھZSo4|_ϟϽ4..\ϭPULνl<[:gIHAAD=ߣW>U*ѨLqNU-QUbY زql%%܂ii; 4@?*AArlU#Dx#Q/pكx lLAA 4ޠ$A(mHhJo}q ֎DSg  COָf{ k8꣯#  >pT   x9AAA@>AAAA|_rsS>]]WV;s[+SAAAh>(u0~<*WT 8; m-hK`6P   歃OKcJ3F,[ƍԩm   ç^B􃂎wk٘0M뉌HOS{ 'e ;woǏ |ᅬ[|x{̙-AXEdmKI DGF::ܺt*ޥ plWrڜO>._V   ç^|GGc]]MAڲe0v#Zjc²2 IDAT܌8 -ZhB޽ ?ԣG\9˗_[w,LJ Ƴgx!PX([~n. ܼc$-uA8tڶm[okBc4Ͼ{H[e?m۶5PĖ׭ [TUUѦMlٲN5obS Dž یzAxLȑl҇Í,-@hh,:v aB`` /ֽr% ÇۉGRF_*j XLj?՟^ DEQ̞=QQQ`aלi8?>N f֨cVOmm)++æMxF!\vZ4ۏF>di#k7K71i"2?;wglm ѼJK+Ьu^vX tl9@UU|}}nD4@0a}|rtA46$x<^:puum0} gaiJ}cS{!e!GS\ 2z UUU <u~3s΍mJP/-LL#/Xz^k+s߾[ؼy8Zys GWWX*+eֻ>$ɀljBtAO޽҂ QPP R&::NNN҂,Y x<|>TTT#F J*jG}---o^>)K8J 6ƦMlRĎDFF  \m۶bܻw044D˖-1j(`jj*"O?c aȑ066&w(+g&&I6V!3WSm6l 444`ee[QD,۫UeehEtʻ֪H{}N5~[:t&t邫Wbǎ6ܐpWORJNsڴi7oވrs2$:[nEDD༠HP*ɣcƌT'O6-ed*555Z]W}lƍ-?駟ggg"33S@899عs' %%m۶ERR<==ѳgOKpvn#GGG߅sk*ʕT@KK4 22A\Z-q̘C8Fo};0|l#GoG..뢃 }",, +V@~~>PH˗h"o(,,ĩSpEU"&dR-ǎÔ)S|;wJ}A,Y7nDAA6n܈P9rFvTԩS Blڴ b9˗/ }||l<|mڴ m۶RRR<ݻ#addsssѣѷo_ܽ{^ºuw^6״4$鳗F@g SmK.͛QXX-[ 88O^y #~*Sk:+sjvVg?~􄧧'6oތhwޘ6m} {^>a}VE;YTo> >2=KKK&9HOOGyy9ТE ts=ׯիk׮a͚5cgg#F`Ĉ2dN>ѭVU(r?{U;z(.][7oҥKegѢEٳkkk4@UUD?+WD`` 1qDd->q,99mX?eOroc%_G]Y^^+bv%3-(ఆ<***E'7n?{{-_~y{GV'ulagg;%*@K,- c;,aʊ"ٲJJݛm{;"#34d쯿 î-6]n''n Pz||Hړ'OO>aH,fmm>Ykb+۷ozZ]&+Ŏ j5h&b%5kInyLQCZQ&,A#"1 J ؀Ⱥ.K<>3g漧gYe~ԿPIQQQ*"##+ZADt]S k2110""Zt)}G5 W&^jIv(֦?)e^^^^zoR4!V^udH@iii5mT^JhG]}QEXԩ)yyyQRR>~BCCsZӴihԩ4dzI4%eS;CW/Fb)c>|8QIIIҹsg ǏKSSƐcXEGGh\I3fиnڴiԧOE=|PVVּ [Tɯ?SSjrSSh_j'P "#ӨOda,,S>iދ*iDktʾwwgԴ*4iݿH%mΝ||6SF+b9y{DG\ѷk׈F$jHxItee.QfD 9b<ck%SSS255%dLLL$'u(IW}Yf(??_e}~~>5kL8Y[[SAAAѣG*i_NԼys@T4b"'O&___""ׯ8p@vdkkKӦM/Nb饶zԷ+XMS{Y[[땯QJSJ_ӔXyɐ @ek>uuERM޽{ʕ+5me2Γ djjJ:uRiT^JDDԺukzABDTZZJo 6L:۷+T 9w)5kLcɰaèM6_Pf 'r1www U|2rŀߘjbgWTo+9N(.^ӧV>%%Temm͛}7 /Uhz|{Q\GNA ,ce{+2hV^z ؼYDCI` cuج@II JKKbV|DKn+¢RyJL$Q\~ĉprr¹sRiӦ1T>}(nҥKann^#N,޽[cLK,5kvrCWbuP3ڵ رcڵk"11]vhJjj*x;VzɚU~.g1ƌ{>lllpeIIIzǎӺLΝ;W޸8tݻwG|||9s ,XVZ OVYoii=z`ѢEpwwG˖-ѣG,^nnnTI쌹sbǎ8{,.]3]fbekSCX]hj/+ih_+X;ib6bԁ\2,~~~ɓ'___r9&MdB|'ؼy36oެ2YuիrJa5ˬY}U8UtL4JO*:^ߥ֭?ĉ:ٳ>;v Lݍ7P\\N:)ԫM@ bc.]  ""yyy(**BLL F!yC,رc;ŋ#((@aa!._M68rI̙@Ƣ ¼yE8qrrBhh(qYL>BC",, >>>aذa*|||믿8t-Xm&VF65I3gVh/Iդ+ih_+ΐmHϹ&bmehYcذaZ'SfeeW ._ w߅ ;Е]vŒ%KrJ+e˖СC8|04i> EYII *rb+C| "ǫLx.**J1i^qq1O+AɊ8y$a0_ RSS_}?<M)))N|$皖j+}ʢ{ /@bTもر#}eO&\N7nܐTǏW0T7tciܸb^رc,e%%%*s1HF}b+C֭[Gm۶UK5jd2z饗Ғ~mŜ DD .$SSSj޼95hЀV\IDD+W$}uY1wU3ɴ32ԧ ZS.NBYm:wjnڈ Mgbb۷*㏟4cL&gk筼m߾}ؾ};6j}e-ڶmc+_1Ԟ… 퍒4nZUNIQQcxxxh,;r_0}}T::u 4Evv6^~e߻w7oԺ:3;;KN_ZZ "z}_t7Mlә q=c1XBpp0uT̖-[kU-[EiWLxkK@=d2[~=ڷo\GGGT~hݺ*p۫C*Q6>+@χzҔ222/cܸq-Z@ff^+L&CYYLLL^>bMj'O૯€1cƍׯ_ᅬ^z7ou8<W^yEg_ ̱[vdPUFMєR(j?N.]PLL ݿnݺE;Vٙ=J?Ї~HSL!"7xl٢͛7oADDǏ'ggg:~8ѥKhСb 1W_}E#JHH ___""z),,L%?H'OVÃ4oL , ""tСCa/ᆪ͛ӿ/O>,,,ÇZ돏5s쮌vR1>/[Tɯ?SSjr@j'-3X5x*n߾M666Z{.ю;hȐ!*L;wT}u5R|!VK:u22///JJJR'--M.??_㲦M*PrBDI^^^fԿHլYv/h(֖RÐ>A*ˢ* Ο?"eQʟχzTb_MDD_5(`/]>#G3km]MJkuq'͘1CiӦQ>}>|H(++Kcz>v̱j۱[J*lWTVoxhb;<[oT_;Ֆݎ1ƞg[7 Mgbb۷*㏟qd2VI&)Wqf͚xŭ())G`gg$j իnݺ\͛po+88aaa=z41dK{ƢEoի4iqUWӲd2iӦpppPhmm+WYf*i *Sj+`RJ{Hُ:kkk\zBZ[[ѣGicc+W܇zPu!hC>RIS]vA|طo `׮]pssâE#~AAWR)Zk4̜9cǎEV.\@^ںvǤI0e+WХKԴBz>vܱ2j۱[J&QR_*k綟YrR'۫4AL?(3rb6O8NNN8wRIbBBBn߾?+V@||< ///UlC9] 2ڵ رcڵk 6ѵkW{HMME߾}SRRбcGr|?j&B)213g`hժpi&;E IDATL@DD?ݡꊽ{ꝧ3Ν;vٳXtb222pI=>..Ne6Ν;W}길8tŠZl DD~Lmm m1ݺuU8qB}t]c;Tu/2CI,6KKK-;Zl=z`pss^qv0 Ɛ~meeٳg#!!}v@|O`ƍ(..V%JϨn+:T&>Q,ߪ/5NFֿB&L]0$'''gϞUDRӯ_?źKb@^^#Fh+PXXCQ AAA?~< 33Jq̙Caa!bcc`9s 00*i͛gP~F=@D8wzmڴ#GPVVW| "#00P}̟?ڡH NbH ') :aaa[}||aoIXW_σ}uTT3xWzBrrAaa!N< @̗&^.55|>v]o߾*w\HUێ݀x*RR(oUrtJOGzz:J_%.^ŋq1- iiiH+ MNg۶ Q0 6`h֬|}}TH3~x̛7O  4wFDDڶm͛cŊ5kfΜ+V۷Ǒ#G}v4SL۷ɓѬY3{Xx֍5 2e 5k)SO?o\xx8&NXo |z i)^ư7: EZ>SL8֘:u*W*.]ԅLgEZORb6lTeee:tX;yo駟/_FѸqcŀgϞƀТE X[[+tWmcwgUێ݀x*RR(%_ceb7 <<=pnW[? OI}ڠuYN[왚CIxNa${uվ}}vuMǎ-ZSNТE˨N:{iii5 cF#֯sss_~Yc7͛7  QUe^ -)+CKSS{[&6Q1ɞݿ_O>Gǣ<&MbȐ߱omE]+ɢA)fLE˖TXWVF01v{[wEFhM|<|R2{dee!88+WP _)/^ >}:{zJѷ_ڢ[nZ7ֹ>nV}[y:7ٔ Ρp} ׮ FPP{|57cF ݛҥ*-'յ[7ҥ 1X'> vvv5S2x`;͛7ǤI0qD̞=bR_>c1 Ok.nƍ][[[[cVgW_xwZacͷ>&L &tkcwT[ۥUFEK0gΟuQ7jԋÇlY(:u Kzz n2c1c5Oq99ΝaҤ$ݛ )'G*&jʼ1͟-NL?DNNԸ?qc1cU7z:ѯoo>psk+.aʔ4M6?upV+dgΝ||&\U%y1:ԩSqyܹ믿;?OMXCLո~ps(;ΚK,Ann.bbbX ,\}qaQcyqi"%:̘1y&Zj`i_Ji€vp& F݁@.NJv0( Ib9 ̙:CUq0lBzKUJ,R#f*^ŀGQjD^bFxt+wdp`z_/kt4`a!zTV2"PYHʿD015ElQ/L4|cLTxxx,RyVaـD\̘1zӱqFߒ2d[MHIIQY֩|$iR?R$%%a:fff055 ZnW5#Gŋxq%̘1HHH+)iݸqGF- ФI*Ɏݬe}RЯ`f&|q61neU.€yt`F@SzP}ߢ~触 W47X"TϞ ʷ1xvBL$@NTuy0zɄɫ&#G/.1Cx>^8%;w~ ׿TtE *&k׮W^%Ŧﶚѭ[7饔KJΝ;hѢbYRRR;v G+݋ӧkWJ,x0c bFݙ3g^xpIu3WWgb:;?5n.I­ʷ7Xly4ŪQ7V33avx16ƪ;rw m'<"QAaӧ{ÔlF8t(ڡLrǎ W Uq9#@xzH!I:j[_X ' CMci2|"..EPPJ9s 00*i͛HӦM9rDʵ~W v̙ʡm7R?C,رcPIxb(,,˗1~.]  ""yyy(**BLL FW,Y6۷x7|SXQPٳ:̊3K 6"ʢr1}|_ KW͟/L' 7XR]¤}*MȑWušmMSrϙ#cljn{pU矅ΝI~١m#С :+KHs+ ZX(ׁB>/ Wk[NN„ٳO o wߦxLE)C9wE_[6Fc1l!C!?|OT^u8Fڵ [Yv-ۓUڵڷoOmO^^^dnnNKW^rlciÆ Z/\R'77y$˩gϞe˖ ڵzIrڵkW!X&+++ ooo:r^h+g5j5k֌,,,ёHXQH...$˩M6fXm)mZ/-%&"V.D^^DDDDʡjkǏ?,]; ֭?V)G,VhZ"{{"33Ժޱ%r84mO}XVNcoOTmZ5}DQϞʶDD͛B[7mv˅~\%D"amYS1Mm=EԬ_~bzC\ˡ۔{'n}ʤ̛q2n^[2BS?vJÃO_~9]PIVGJm@-p'Fpk>DeO>W`η"|cL+=].^[b8jK+q$Jfџ2% ]4Gjʕ  ڈW i~='A`+~#\>/"q-?֭)HJVlw߈Hc1c:Io3;"(}PP?ܽKbQ??g y"ݸq矇صmXF`(ԩahc1c9쑊*uǑ#Wo8UHqߊoݺ7իNj/q*131ܳgZn-;Em.g}61Xf7N_~e99EoE ZBvvʲ>A6݇8zte1ƌgضmk:O;2XM311D 2"L P%GU2^V}tЬ²͟ [;EhݺJ;w⋪߯XXƧ*f1*pss0X=vܹCHN/ +}֭) A%DGWH\\^R?r*\ǨQ1e Ung1V7\ h4l۶=[66@&/lL] t l :l89'p6!!# O?3* 07/_H+L&CYYLLLTn r9ZaիWu01˗1j(h 6+)U`zz:`cc&MJ(ɰvZt 63N:M6 5 d #r9HFEEW^077=/_ B޽annmbÆ *aoo\GGGT:6)uuV-[D@@MzWE_[d5WS4}cyը ֽW]ѥKr"ŘJOK&Bܾ]oMߟE^4sǧ֭))BNNnME0>}⊽L&úuQP*Bg1VE~ _ol?0c ܼ j矁<`p& ݁@mV69' > 2_U%"ߑX|9֯_<_˖-Cttʶ8qʴ_cڵخT1c233qMj j?1|p!** w܁;*pժU C~~>6l؀ŋ-x ,\}qa:*p>}:,Y\ ..N^J>|˖-Ï?|bʕMJX_~%rssq9a̙zŦ>W!uc'Ё[L!?|Oy9s'[eci,G4y^j3\NÆm i##ӨOda,,S>iދcEVn3fc6۲1B16/7B~.$'q)edHO.ݳQZڳ5mMT~##TӔ<Dݝ"##U޽ﯲuQFG޽{*)UV~~eM*EU`dd$y)UryLg*0##tTءt)1ƦNS&&&}6:}]5-ucϓJ/J~rRLRoxhR;.{-a0*90XuF }mh:SܾWYD=N WG,ܸ̚%\1>=^&Tg׶"LM>[_P88wo\X_&&@x?ݟfָr 5{67MAA푟ѣGZ0="ˁ IDAT2d^R7n`֬YG 455U>]-ؚ/PPPJXPPm7oHJWMLLP--- kkkԟ \R!NkkJ&NKKK+cdeeǎC@@Θ֡1 a1':E)))uz& I&37'%%zD""M5kT'4'2hZ"{{"336lнX"oo"++" #G?~oڵkޞޞ֯_/-U LLL$ԦMZfM ӤĪr۷ jX&+++ ooo:\ڵzIrڵkW!#" vQ ֭[W SM˥ĦwE۷'SSSv@͛7'\N={-[OJJό1d>aGy8[1y< 8 .qw\ iU-wsLkx@&#a1D=zC`1SQxY c9P3ocLcUu&^3c<>c1c1V~31c1cu =}$3c1cc1cz1c1X=|c1c0ybc1cUӟX+1c1X=gc1c1V|c1cx >?c1cE#zc1cn e˖@^^J᰷\.#BBB'b̘1UV _|z ܸqCMYY;x{{G3f RSSU{19z;&M?B9s&\\\0e?ZcݰaƌZpb?3撒\C &L{~~~NJ+0fhAI'O૯€1cƨW^͛lݺ5Ο?ÇW^m۴փ1{1Lgo˗#99###oƎH=cX~= l,[ 'ODFFb刈@>}pL0/"x ~~g8pvvvX|9gggDEE)ʭ6oi&<~~)UN8X~-{aܹ9s&n @U|ٲe駟?&LP/2L3;wDQQ=@bb"@vv6zLVK; ̞=m۶$%%aСXl7nȑ#Ƈ~ |g1cv "^~e7ЦM ڵk*WG_~pB:u sAÆ ope}nݺ(wJJ >|իWǩS0i$9 6T#>>^夁^{ bS*uҤI@MTAǏϏJJJ_~W5#..:tx_o3lmmwpp<==iƌM6(Ç eeeUH'WJJ22d]VRZcÎmR%L9OIz_LINfxU)c?VZ=--MqYi<b0p@奲l+:vYfF67nYj^~\=T޷hBTxxxQ/ .{=4mz‘#GлwoOс۷oɓsss,YDQ8s 2 Gǎѭ[7 :&M|[[[ <+W۷uYVVqơ[l)ҐC)5k dgg㫯ٳgc73 ,_~ "§~qr'''$''W^QY^>5t| S)fĉׯ֬Y-[BfT/gI]lllry++++Çϛ'%%)uQ1\NoϟGzz:vލ$]Ve-[4h@6DS"++ VĚGGG4iDҥKҥ LLLW^yXd lmm_TINNСCuQjjΉvڅuaƺu0yd$&&k׮ֺ߾}*ާcǎNO?R>cc ";;&c1V ${1gbӼXjvvvƱcǴܹsC.]3g`hժpiѽ{w349::N$&&ŋx"=yDlXf ȑ#{֬YHJJ¾}`iiXC4lP%MWۣaggիWNNN8~b=… oeeٳg#!!}v@m'|nܸbtI%mǏÇZ_N(uhڴhZc73U cLi>#|nnn CBB} =.k*r@,Vn,٬~I]ڜ?®>{ is9~$ĊڲIJ'!l r1wf=914}{5 fffuM^ш:S}Ezz:1`ٳذax[nq*TTT ''ח{Eff&֬Y#7H <]tAyy9^]bgg $$$?Dii)222LX[[sW#3hT9s'4!> >!B!Μ9ÇcѢE055>C777l޼AAA066ƈ#ƭ;v,1}tbXt %,, {쁡!<==1gҥK1eaƌo!ZiZɓ'䄋/bشi?'''>}7b…8u?h\ƍqutԉ&M8::).\ , CΝajj=z^GG˖-?ڵkF>DQQ3;v쀙ЩS'o{pss -䝭Wv.deeB/$6f?"Q D$?BZ}w*iiiЁpp t&{ abb"5a]ϯ۷/7ׯ_#''ݺuCvٳǟ.]@WWF{o3ܽ{WV^^G_|&O1Bܡc ij}^t|4>!055]t;خ/zRN(jo1;&+ :v(wrj۷oԉ"##_>k8!4o =!BHCocQ+>>>i0!4qxs݃O!B!o4>!B!Ҝ|B!B!>!҈{2k,իVƣG0e08Wnܸl<]u!߉\5B*}By+8::*\Xc)}v8;;B0aΝ;'7i"""w^p|XzuCMZLߟw:YX~ff&<<<ヶm6DǏq޽ A077o2 !}By -_~m~-/_.짟~BVp1|h۶-Zj L<AAWW Z+++BXYY!44Tj@ -[ЫW/nHLLݻacc}}}Ν;ƍ򂱱1:tOOOIo>CWW;w %B!vM2>>>?uA$aÆ 4hm#O?aС0`|||%1f SN˗k_ZZyӧOǓ'Oƺc_{^\\ .^ <GFF7hڵk1b>(--JJJ dffJ]QQ'"??_j+]@XXSwՏe˖q|@ظq#`oo~_a̙СCg.nݺ!==Fᅬeu Nc@!M0k֬AFFlmm1qD.Ν;m۶:ĉ={6m777`՘6mѣXf v $''>C.]g8y$ͱf5 ͟?_Rfuƿo޽_ҥK(Cpp0~G <Ϟ=W_}ya߾}ėJ^;vqe|g5E (СC(++ùsPXXHMMũSHIIAAA|ڴiرcѽ{wDDDĉ@Ϟ=q]xxxxwq}\x Aʟ3g /)5x{{{L07n -- Xz5lmm7 77cƌ磠9~z̝;Gc 666033~{Rej /_Fbb"?3,XP@޽ѦM/pBXXX@_ZZ;wHi7n˖-Cbb"-Z֭[?6 ''q=ngff˗شifΜDL:cƌA֭ʈ@;ֈM2iO!eRyJy!366枻H4GfڰM6 swwg?fÇg6KLLd Xii)bW?`1m'pII6dVXXȾ@ffb3f`#F`1>wqN:7n'..Ջ{?J˞4i[d Ņ} V~ׯ_QF1///VYY`_xuQz+++#w ;wufb\]^|H_*|dff*C#F-[JK!Mײx?f4?/fffY;<|ByKy{{cݺuܥfI1g%'^4 6LlJ-sssWݻ7eMnn.,Xxyj znbb"u~VVߖ?a``;;;={ | uÇtuurJ> @ 'лwopwwԩSk;gtÇڵkCq.[ vvvFbb"tttTRy@zzz`ƍHIIAaa!?.u938uwܹs|@|{/w^hkk7XXZZbԩ7o&N]]/ѣ 9s&χP(InDfffۇ!fOBFKK AAAҥKmcc R˫Μv䕯*&u2e >l޼;wFeee(^M/A166B.s$KҸu{&]{wsNFzz:nܸ#G -- [lʳsėW̥KPUU'''R`mm:pn޼}BKK %%%x鉕+Wcǎذaԗ*pwwWZ˽ IDAT֮] H@Z V>c 3fqin_5TYYYJ';|0n݊ 00[nŴiӐ~Hagffw50H;Y_~%wۂ"EEE(((hI!yI!˗/#%%ƍfXn]mkk+\ߧO}y,$''#((]v.]v& ꚵ5*~:_lnb gJKKyfٳgkUv\\kٳ{x%Zn-vǏ6m lllgڵk*`١7hGEEA__[P:ߦM,\III/pA \wޑ*Gx‡/֭!Ŵ@bBy $%%!))I/O>'|X<{ x>q+V@@@Nsܺu[_UU 䠴T Q__ʕ+vZ sCzjDGGRgޑܤyz*w222@!B!Μ9ÇcѢE055>C777l޼AAA066ƈ#ƭ;v,1}tbXt %,, {쁡!<==1gҥK1eaƌo!ZiZɓ'䄋/bشi?'''>}7b…8u?hT'O0zh,Z~) ((;vݻwOOO 8p,,,A CΝajj=z^GG˖-?ڵkKa,?{,K.խv333?{ wUѣG_|ɓ'7x R"#棪 1y؞|4>!055]t;ج/zRN(jc;vLW"uQڷoߨEFFr`gghqBHs~B!ʕ+3f  Q׷è4v<|B!(w^cA!48dB!Bi|9 B!B!h͐B!B!- !B!B!BH fOB!B!3B!BHK;B!B!hB!B!-0B!Bi|B!B!Š>!B!{B!BHsT=i>'B!BZBi2/uVo1ch oj4imB6Gs>ɶ`bbR/}ڻlg;wDϞ=ѪU+b~E6춵єbyۈgѧI !#7kEpBDDD5}8! [ iɒ%p ?/_cLv%4rBoA߼/8::6XyЇ)ϦԿhn's]+MCNSnۂ9ڵGYM).'Ҥ۷EΝb4.,--fTVVO @$AKK;%|c4htuuaaa0dR-;$$VVV Bhhh!+<< FHHH|7mڄnݺAKKqƍ򂱱1:tOOOХK<|}}c011A~~> ''cǎ Zn"""Ba[lA^кuk"11w ;wHm/C[괝 W_8$ˑ~'f^g|TBرcG|,vٶRy2Ue񩯪1z~+;'m+>TѵkWzJjyii)LLLPRRx@|L7߱c֯_=/..?xuUTT`ĉ1ڊ+ݠI,:+efd_~fEQ];!ݵ13&h)i ۗİϟ{I&'ri-KHH`eee͛ݝ.OYLMM͛7r$9r3YddZqȊf=z`{57tP-eΝcɓ'?gӧOӇedd0u޽{1.]åg7nd%%%իW,))yzz*svvflH-=z4 *MWɫ.bVcŧl9۩w^g¢kj1B1O|^PU_UIcJ}j_ߣGf۷o_eӦMS+cx]ńB!}6{5suuesQZoEM/ʊ8p{Ȍٓ'O|ȌÇgRi򘕕LT<Ȼ\eNNNѣR9† V\\\s1vKOOWc=}s?c~`ZZZ܇UV/Kۮ];4IXvv6D29*MW.&m'oRQ]ߩzirLS7y!WWWUL>ye,1^QY_TEX;0Hĭsuueiii }5 T75k1c1bSgP=i$d %1Z [!4 znbb"usZZ>@[[ZZZ֭n߾( 6L* ׮]S+YYYYpvvZ&[;Rsss1n8n:#G"&&p1L:'O:u \ڹsgƮ]Qw߆r=y{Χ/CU.&m'ojrT;U3M |&5V=FS&׿,UU)@QU+>u6m۷o1V8!I(b̙Xz4˖-@GqUspp@jj* ** wܹs%7BH~jCee% CUUUDjǢW2R,s"P(|ʔ)+WPQQ/^H+C\|GAA222֭CLL ,--qq6mR{0ݗɧ/CU.&m /K8低TߩzirL6Sn]#.U P^e}QվSy-Z 6WyfXBaK. NNN000PC}qpp+W UVAWW!b4'Ҭ 8ǎUxԲ4󱵵QO>?šo߾j"* B׮]K.Iǀ|r899s0`VXGGGKW_}"%%VUd :"W⨫ב~u1AU{ j*vu)S׿Oh*|@ձWUJӺxyy!//'bbb4P(ԩSq _cϞ=سgrssyQPRRkB$߿b!>!feժU Ν;Q\\2O>ᝇ;Kܿeee8<ԎeŊɓ'QZZ8ݻwٳggvϟX"66XxڱHZd ϟ8|UAhh(ˑٳgH۷۷cȑR<<< ̄ u%O_h8ZuկTQW#UNLc67o^P``Z媊]]||4F>m+}i]ttt9mڴ+999Fxx8&O ]wgW^__ʕ+vZү.c!Ó̻4!4dO <&R<66 :iӆ鱡Cg.N:1P{=w^)cBуIٳ'涓~˖-Ғ0KKKm6Z^mGUVʊmݺUeRSS= {l5ҥIMu5ƤQ'N`LWWuؑyzz۷o+W^<| Ф}c]ߺh;M$Uqh:]Ƨ){11OlÞ={(obg]yT啡&ǔz9[l_S|={ڶm jĠ6?~ݛ}ܲK.1P2:&$$ԘlS2GGG4T,MQCNw:.Ob$6})SƏH3ѧ1ɏ. u۽ TNKKC'\4!3@Po7Eo[}ZTT8]v۶my<-o6 ˖-СCQYYۣ\ᶒ)++%=|B!McLmkbj+[C6m`dd1c &&F…@Dw7L|nʟ";:6ki.\&{>i>z:!4eo栽acѠ}aH[[(((P3f ==BII aҤI׿v^D쯿.j栱-Oqq5O6H䍿 t#u@|~:O!`#Xl|/WEGG"HXСCغu+֭[SN?~iիuT%24H {7LH`eeUA mT3>g*ӘXۚ˿VNVCsYTu,Ф jm-JRe(# %x-i&t ZZrTlٲzB֭akkD޽666ׇ H4@ @HH! aii*PAAWW5n~KKKBX[[>MbkL;>߿߿А}׌1H/ou/^oϞ=م IHH`,!!7o2wwwVYܹs=y}lzɺ۳7+<==Ga,&&={0sss|{{6ndWKJbL"K% XnMokعs3 cΘD(_rfs/f1eGMB8y1ww$w+vۗq16ic'FUiRGU35eq7o2#G37ss$^m꧌m3>گ4`J\1֯xd5T?*O>u;c3ֽ;cOKQmT}sr%5Oggg͞?/^ Բ YXXXsvyֽ{wvZ%Ib͛OçY=jY9>vZtLv&3y'1BHt!7E_~FżXee%c}a׼esɺk׎)ɉ=zTjّ#Gؐ!CnӮcJ=@(Nr=}*0**_r~^R"χgLf<$w+vLM^!cQQGGTɉ1ǎaLզ~ۆ>Jc[ߤ>>EDH0\m,Xn|bL]]T6Ⱦo9^`Wd{ɖh $@/=\%P_GGGvPAOȍ)|wx>f LT^p&4&UVط{?268wf}D8q">}HBK})[,1a'+..Ɖ' .ɓ'ؿ?}@NwgfAKK UUUł B/k`` oߎq #F)nݺCÿpx1,--QRR"@`v`8 1$ WK]Uml\` >x,XU};%U٩fB_w+vo|Q}} ?02u zxX|)su׫M }'U:TC$_2xر+\< X|k-#괍*[|^?Q=F$y˪x1 $ǰBLIG~~>t1nݺU#N##ZŦȡok;}UUcHOKW󢓳 =<{Ϟ t IDATyyEUIçBvYuTEOOm%iR?Mg|!-u ذXT~_h~.IU|ueOA>1溩˟ӤAϗym5Z@?BiZ, ,@ZZߠe߸qSN 1߿=8p ;t>id%''#((]v.]4-+?šo߾* 8xHI$1t4~udkW@GP,j@nU֎u-p}2]qqW&yg|~mc$//eq)*:hGmD6m ÇQQQ7obܹO4VBPPv܉b!&&|Zid 44HIIٳ2"::EaEii)bccŋ+wL|*:Z~m$CQUYc250P~ZIc&kyT/y!..N*@ I]bpI"''>d̟?FIObg${Y۷oH=&J%$$ԘdHYzIL[[[:E0XLL ;v,344dzzzښ2tlСM6LOO :={V4RSS= {lRJ} tuuYǎ'}T~[laLGGYZZm۶),[xb)]]:v^-eQxN {=U=ɝ2*}jxvmP<͊˔Zr.R@6ܭڑx]caqyB!c=z0&~,-/azdL[b cxTWqyl3aacsYTXw _{ٟmǞA:^+[T/w{dP6u/c>|{L(=z(Y=XVۺuk&ONwIf8TDBH}t7s0O&aÆaٲe:t(*++Ѿ}{ܶ gΜٳ[OMIזPNKӔۭ)F'M&sTm&}5${ztB\sD_U Ν;>}ڶUVҥ k$s%4vkʱR)iPo:!> uE[[666 ^$o*qTC}DO]P4MݚsljuFM/ T_k.?QӜ5 GSosӔۭ)֘]H},?!I=!BQ͘BH3@B!UgA7BHSvf6vMVm㼮#B!!Uj8!@7e!B7MҔ%&"BHތ >!q xyy:t'탽=tuuѹsgX*pXZZB(ZO BرcG4"##1h aaaR|6mڄnݺAKK+Ě5kPYY>B!=> R1w\ݻڵ+GQQ\HyqO>իW_EII BCCvZe[۷oGII °b 9sFn'N`Xr%8gqu?~.\H$… l2O())ӧN< !BtBHHOOСC: 88RiكaÆm۶033æMk׮͛ꊶm T?Fؼy3Fm v]ݻV\0 2BXX,B!} =!q:t 0@깉%YYYpvvJꪲlydffMaÆST9|ttt ---t o߮ !Ғ=BД)S`cc+W/^@UUT{i$HTcP(.--E^^*++QUUHX6!BBDrr2еkWҥKjѿK-?^yۼr ѩ1766ƣG)i8v4B!E_B!(//GJJ fϞvK,R" @vͫVXpy)iժU Ν;Q\\2O>Jh~B!j՟ >!={3gyxxx`ҥ2e 0c |7*[d MCCCĊ+M͛7#((1bܸ6l9s  7x`dd  ((HiL}9;w:uBpp0,XA!B$4!ggge?zӦMôiӤ͚5KiٳgVzŀlV:ccc3O4Iaxs)! BH%IB!B!-|B!Bi{ !wB!- !B!!B!b4!B!0pcz:O!B!Z  B!BHsFg !B!B!BH fFB!B!7B!B!-I; B!B!h~&B!Bi1hO!B!4'B@>sἶ5k|}}qUkѣG2e { ___ܸqxy]v-4-Cr;ɿ:dggk4!ƒxO7B[C QzGGNH۷ 077DŽ p9Iڻw//HMM]DD݋}^[W\ŋy> ǏW(,,ѣaff???:_~ZZqhZv㣏>޽{Ѯ];̓&ByKg !-XOJ-Ę1cpq[(++Å 駟b 6+㏍Xff&;}TTt2Om۶ cܻwn䧊 7HB^4'XbR~'j ǎÇ~mۢUVɓq4htuuaaa0!!!P(BCC lٲzB֭akkD޽666ׇ ܹSmnܸ///CDQQT탽=tuuѹsgX*pXZZB(!!!jʕ+HJJΜ9| agg???ddd0H=-[ƭx"<<<0x`߿ܠk׮ň#`oo>R^^^())App0|||)7e_TTT`ƍpss=|||˭믿0sLaСسggnݐQFGDDDJu B4E|By M0RtaRiw܉%Ky 'NٳrJ!&&FꪂGb͚5ضmm6^eɓ'Q\\QFaԨQؾ};"###899asE~~>޽]"00P*`|(**•+W 0on8-[H,\ׯ999ppp6֯_???_|M6a̙pssԩSիecϞ= _Hn'wu4'Il`3tz?5~I~ "!v#Uơ j}`!""ǎþ}'Nرc1~x. 룤*˔N''',X^^^r2_}ƌ-;z(6n܈l;ė_X֫W/<~Xmd={ C^^gjj*4=B߾}A+-Z\;vT)kÒ|gœ9s|ro׮]àAlի ̙3x)~w >sE***0f~6鉯  ܸq5?0uTܺu i&? MJJѣQXX(w}Æ O?TcٳDhkkիWajj*vرץٳU%r؏WUU1t>/:~茇Zؖ::BHuqgggs}I1N3͚̜&wpV-;;R0m4e{644ɓ'&77 ,@||<7>[\mRMLL.ʂT[ bxxx֭[xŇH$/w^hkk#;;BOOlܸ)))(,,ϥsF[UKKKL:ĉѵkWkpE=zTa3g_~~>B!LLLjw&233kB!ԩ7t9 B!DKK AAAҥK^ncc R˫Μv䕯*&u2e >l޼;wFeee^.>NիW1zhTVVbܸqѣ9;wR|c1c߿ӧOC(RSSamm:pio޼}BKK %%%x鉕+Wcǎذa"pwwWZ~VVҳ֭[qb֭6mRSSѯ_?)wLݻ6 }ZZKXXX(GQQ lR?B!o7-v˗qM3yd[˶ӧO*C߾}<U]BGG.]R;#>>^j_2Pׅ PYY [[[:t}ttj (s_|]EPmǏ6m lllgڵk>ߦM,\III/pA[ }YrVr _~/_*|D"uο[n000PB-:O!o1@$i :u | +sXձb BOO...(((իk.E0|t ˗ fccP̚5 Kdо}{ 8,u1]˗իܽZz5/utcٳga@yy9 hii! nUUU@NN,,,/LYFn|K.aϞ=044'̙vXt)L###̘1|Mc=z4>STTT_*++Nƍqutԉۇ&Mn.\w|„ `s055E=[ٻsc3ApAA*YJMRfץ{K{SQ 5$b9.ȖtB "1 3sa|<>:a9c ",, :uիW f}ٳ'z tYC 1rH8::Vuo }o rp <:={޽{ojy&BBB0{lf1X2]} YgD);1cUpqq1srԝѿ&@];w^xyyy:N;wlp}S /ROd1ƚ_ceʔ)2eJs('Nĉ; c :|c1cc1cD1c1k >c1֌!{̙31eDEEg2e ~͛:u*5h駤Gp䠴]|9;siɓ<4c1Q~W1dѻǧ1bv \'''8zƱYھ};vZ --M~ؾ};|XΝ?, 曈3Im5Ç֭[?~`UUUXr%F oooL8yyyW^{///5 ۶mSwqO#::Zg"1ƌIsATjUo>,]6l@qq16l؀/i;wQ\\qaܸqDll,n޼ ___̚5Q`̙v~7 8e_ΝCmm->Ç/~lܸ˗/oP.N>rjѸp6l؀SNPPPm۶7nQ >/ƕ+WPUU &;_~%⧟~RM]B/3gٳ'L`8;;kݮ];9s'OT-7ǧ'x ^y;?#>|fI WᑎR IDAT\}„ ٳ'`…/nnnbᰴė_~Pl?xW{g#G⭷Beee4m6r>M3ƘDOYyAk[tfc-cL[cnQo|f4""C&MR-8q"EGGklCDԡC'LJbbb}i,ۻw/=^\ֵkFݻq̴4mnܸAvvv~~~;}2,.._BN>Ç4`@]t!O?|KHHM>MFcƌ*""zgjCp$%%Q߾}UWZE/t&OLS󣯿l{!7ldoow)Jh̙:M>˃]~~) :T#++`3֭['j[kKb~=-KVegKEG($*@&g11!!!XbTرvD4Z/$==?999X6rH;˞x nݺ\vΝF퓗>ɸu-7x`׎gggcĈh0\h߾=Fu wqq1q%ܻwOK  ɓ'aeeNʫCP(B\gϞŭ[PZZqotC^ʕ+9sn.9e`4[B( [0i$ pyطo{{5r8::6Ve}`޽r uSNڵ+ -- C.]T]xJJJO#((9W_iC$33>|8/_Z̟?K,'"L6 ׯ_Ç!͚l7۳g֯_]vaX~=ya{ܧzJ:++ O8plllT͕7;vT̞=111nUyyyO>ÇZy?~޽U b1ִxc0LT̞=wŋ/Dܻwոy&ctڋ/Fxx8<2&q0g̚5 (++Cbb"1w\4;6n܈ ={3f̐|ya֬YHJJȏ6gDԟE!$$.]\ ** oU7߿?222Twӏ‘#GTъ ܺu Gee%}\tIUUUEYYI  ?˗/W}l ԛ3&ޱUTT_~QaLY߉'Tׯl֯_s?| c|,1Xr?#F9sGq={Vc{Lȑ#f,Xvvv3f FZꫯbxwѭ[7K/5evuڴimۆnݺ!((_$#00}N [[[L6 Ə_~UUU_j=ݹsǏǜ9s/,X͛7~0tPǏj믃н{w}z+++,\aaaԩ^7OOOF GGGڪOCH0l3Ƙ~,$*f wp"%Cc1mE c]0g5'q锗ZQߪ˗5nÇE޽ѩS'_^^B7'4GB2#G ,, 'N?kk_޳gO߻wM7oDHHfϞ7x10Xs<=Eo_SS"BFzϋE'?}&{|}cuٙW:\nKbĈ:'MXM~aa!:w^xz{Ν;7bccl1Ƙy]c1b;w YL2SLi0eĉ8qbsc+U1k1kEw3c1cmOc1c6'1c1X|c1c "<c1c571c1X|c1c >c1c1XLa0c1c' >c1c1E|}c1c53c1cm|1c1k|c1c /g1dM.=zdǗ9ch GjoghۙKKjbxvڵ MƸ2eζlWWWkNR 1hooc< XZZW^شiIl~71ƚGSt񚫎̭峵kNC|||7bѢE ų:cI W&CիWc ɀn樣P--mJ~m-,,رcaii٨ʣbD@@ MV3kQvoooX[[{ Eqq6򂵵5 .]jǓd}X kkkNSOK,#""\777lܸALbB\~!""qW^޽{¢  ;;;tAAA(**8Ɣ)STωv 77*Ѿ}{ ::cUGb1k566]Wڄ1^ ejL"""Я_?r( l޼qĤk(v<ILB}U Փ_Ϻuзo_o8y$;~~~r204NjǧlՕ_E^PYY ())_!tM7oތ/RaaayKUUUI&z/F||YcM6aĉ XP[[+)V)$*d]LX ݢ[7 ۷n!clߺE[\t"~C35mewyITRii)ɓiҤImRRRӓRRR.^Hl2J_J,=zP\\ŋ)44`:KNNNT*޽{T*ɉbcc%š->>CTZZJ F<2OOO:z(UTTН;wߧw}WÃ233ҥK$ɨN:EmiʕTRRBJAAAzc.+X"RWL[kl>Ŷ&6z_1ysqqi>,)]YISL_ՕP~1rrrΝK]v%???eǏTP[+cƏSddF~-;߿OVVV:egg\.˗/Çߟ̷>RFvR>y$ѝ;wKrr2ܹvI~-u֍>S-u{+++X+?;٢dePvfϋYʣT >cOli,q٩^=N>M~~>NOdG(2___ڷo{ҳ>+)m~~~D"}5_FFcݽ{TiժUDDj*P} ^d ͞=[mN(?? }8Ԏ|SSl+8Ķyt֋P0ɛ/)]YISL_ՕP~?R?Q.))ѹk׮b@_9jBu%&/'Z:JOO{܇ƍ5-$$ONӦM1cPUUUt%fIɓi޼y~~~_7K,>|Hƍ`6K,qFzxa U J%>E1X2x`׎Mg,--aaa޽{?osrrﯱlȑ88eggcĈ˴'|Ru^^&L3x.]O~رP*㭷B@@jۙ3g 3f֭[5#P,`|muqMG^1WLt,I6?kؾM(bOΝCmm-ϟ%KںYb!"L6 ׯ_޽{:ϱf͚[h菾3kU7vvvyƲtDBBVVV?Tzxxرc˒пɱ4hWӧ` VVV8uz <-/wc񁍍Ogbɒ% 9mkɧ)ۀ8LEOXW{8ptbJLUω)qR26/lj'T*dp{\z .\й>)) ~)mۆm۶!//OTM %%%X|9jkkl|GHOOǁo4 .୷j-g'c1uK, eJ/c?Q^^JeQVV\M8r޻Ι3fBbb"ʐp̝;Wr,͛Yf!))IBݱqFTTTٳ1cFm@@`` "##1vXO?eeeG~DAL,MML[kl>M0U>aLS|A>|I .4B54ESB.Buel^0;V;v+ ATTx bH[mll0`|X|SM_|x>|]ttLccQW]];-sTRMc,&{u _'&&ҨQcǎԡC5j9rDtzEEEJ$iȐ!}vQ7n^g2drӧmڴIc+YZZݺuP(ʊ mذ`zBEFFR>}]vFׯ_ZZy{{\.'gggZfM5nuyFT?5SPP]|Yo" mg| alZ/D+7e M];bKLB}UWB)@8kjq=zǨA XZZnGDtmz'oj٩SH.~@())) n)e{]LB>>>Աtܙ~^bXUWWubYc&{t4&{T1qt)~5 &caLmS;c5V0Vp; K޵ #{VcyrqcLL&kk[G-vڵ [n 6l؀ѣGf\c]c…5jѹsgTTTW}{]ˡP(&SR?#f̘aK%vG OOԀ!#p˲ ֝.DƑ1c1Zׯc8t萤-[ӧUUU'ѣGUO> oXt)F`roX0u,ڵk˖-3:ւ'1cGL&Cǎ '''IN2SLi,--?w^y 6 QQQ)IE=Z'|c1k}KK-MP.i,4Powg1?d4w,LWǧ0)nבּPsnB&cEٱcammݻ#44Ūū GGGoCEttcd2DDD_~P(ؼyx"""\777lܸA,bDŰa`mm lڴI… t邠 i#T.bkll,`mm BKZ1QjI7** r3sH2 ЈPzj?kKy6lWWWr36S_n݂=߿}EEq-MC}NL;֎:f^옩L7u1㙘4Ŵ3C}P; ?b+eWϺ91[}E鉓'Oテ;lll+W-S^l>4TRfQvf&Enѭ[c1io"j-.Ek2NлT* h4i$z{{ʕ+*++)55 BTZZJ Ly{)Jw)JrrrX;pу⨴.^HtQ;wOr1&)))I)))T^^N/^Zl -1S>}o׉QFQ^^㚣-4-11\\\ [c륗^۷ks۶mK/ڿ>o _#ĴcLOcRL}뙣o3ISl;җq@踦u/1rrrΝK]v%???eǏ)3|żOlя_2(;3]ŬL:uBRnu'1fy|___ڷo{g}V0/|||(&&Ftw%'''4E=N>M~~>w}ބAWGωd|J:f M7Ĥ)IˍY8 t\SӺrrrTKJJt.ڵX֘1+f|Ǽ+JT1;=OIFkF,Cc1mE c]0g5'o㴾z}s IDATke2jjj#22&L/ƌ=zLڵj۷:eOtu릱B@IIk`kks}^^>#$''NT"(\ɫn߾ jjt1Cu'^ĤkggK.5`׉JrǬFhv`kk˗/K*Wee%^zڵkBAArUb< 91X;&SS%1SzƌgbΤeؤ,v:)i]Kl| .еL_91c)W>wbkjj@DHϐy%ugn]wd1RHmŊP*P(Àz&8:t0~ԩpwwǹsPUU7!??ըAmm-HF}jkk5^ ՋtibJ|hk.M[_۷Gpp0n غu+BBBT*i׃~PEkd|Jlo6a)5f1ij<ӧ:e8_h76v|jziw `1D'|={K,1}rr뤤$ 8P8vXzmee%A zן>} ,@^`eeSN馥7rrvv5k֘d/W"D5juؑ:t@F#G=nQQr2dm߾]rI722Cڵ#777Z~ >pZfL;X~=r3U}-]ڵkGK.mflgωiߘ|Jo_}ӘLlbڙP_Rb6v/cL|R'z3fL5U ,$*߰p8&nc-dy!cZ{9y$~m4w(5ޗYc֛Ytƺ7|c$44٨@jj*f̘~b1fVc13ѣGcҤI|2\\\0m47wX1 | cOdhm7ěoa0ⴶ̘1}c1c dc1c1ƌ * >c1c11c1k >c1c1M1c1X$C}|c1c /c1c֧~>3c1cmg1G޽!h8vɏknMQ6֜1ʪ)Rq,_Ǐ7kƤ{B7nKh)P_} >c1P#::D@lڵhYooѣӟ$iCq?ZGocXzus")`ժUXj߿$ie}b1Hz*|||L~۷o4ͭ?3,]TJ?|l.Mj{kP5!O>$ Qi7mOcL&Cmm-,,,~TUU+WbȑĉZU{¨Qm6@VVz 7O?4 aÆ...شiA. 7nl;v޽;BCCQ\\Z_.\@pp0ХKHbɓ>L~Xhu@T\򂵵5 .]FOW|R%Snn.^}U8::}:t$>W^޽{0A(( r B;C8Ɣ)STωv횤R6mذek̹><** Ç7P]7vo7i2& SRD\\BBB,@~ ˡP(yf^zRc28::Dg:B,=)t-74Fky,CnMc8)!Qt4*eefPoݺY(ؾu 1f-[:h4u;w.Qll,>|,X@DDtE3fP||>CTZZJ 鈉Ã233ҥK$ɨN:Eטg>QVw#''':v8q*]ևs)}}eMl߮'ԧ ... DD4~xowyGgbYjYIz… P(t:^kK\b~=-KVegKA \T >cO>͍Ju~~~4sLONÇj""zׯLJbbbKXw^zg5򒖖͍7Nc!w%'''ICuMK.(z}FMO&??$P7b&66`_eLСk,^(11|IUtige~N:t7>187|رcٙ+vj/BruK7nT%\kСcu֍JJJ4hLPMMM}{U "BגrU &///|M"ⲷ'KKK$ d,,,$:e%&y摽=M>l٢Dgee۷54ȿz:bb;x DT7ywT߰=3tAK+)mT}[ne˺uH&Ѯ] nG$>ԟk׍v 4N MMUzB}ʘ>amms^lmmUJ'V!~?3o c8KsL|c-Ξ={0k,ĠO>M0`/;;O=uVVx XZZܾC&טO:8wp}Ԙ4 u...oPڵ :ʐjԠD SĴb (J( a->r`#&6ƍ8s -[d"33ǓZWRۺMK7oބ%.\\և:L5N ZR۰P2Oׯ_7̙3_}`˖-9smԳ1/jkkcvuC~@KH1XӱcG|HMMٳ{n< <䓪eYYY鉄=<] ʃK, eJ/,O?eee7S\RӘr7of͚$(DLlD``*;vM~=SO?fBrr2ˑYf˘:u*v ///޽o\wcCv 4N MS1S^z wn>hP/WBxx80vXXYYMCL=P~ׯ  {<}`x饗-a,#g1k>ꫯL&=z t} %988PvhDD|r 8:K}CC !\N}M6i_n) "BA6lЛ/}CdiiZF$ٙ֬Y#JCΎ:wzݹsgrpp<+11FE;v:ШQȑ#0ƖPL?5SPP{HO1I}vڑ_^0؈  @SWR}h*$W^^N ۲e 25ԇŴC㔘i2b>Q^^NW#M6׉ݻG=#p=K- "~QTTD@r B۷oۦt_BoX*&bkD_uʼnjkO10& nc;ۊ]0g5'$颢"gϞ:w~7cLɓ'o#''Ca&b ~߁k.lݺ"k~/"Fy5w(;1S555 "dgHs(u37|c^Ν;<1BCC1w\YYY1c~b]~ǡC C?=X`2Twc1c=z4&M˗/ӦM|cDGG?:]Mc1Ss|(j4Mb۷/ݻş'k^=&<*ѦvU4wfǧ33(( re2V^޽{¢-… t邠 kcʔ)DGGG\vMu;v޽;BCCQ\\7fC777raƍ (& 6Ut}믿W^X^VVGGGUL}?׮Xxyy K.Euu1bcc1l0X[[6m8L&S=4ey{n_h߾=k!11A^WhuRWnn.^}U8::}:t(%.@~\( km.te~(}ɓw \"-\WGǺ hvѽ; m>+L&k*&ڏѐ p.] ۑ^B'1e.kԉwtdV'$*PvV&Enѭ[c1io"j-.Ek}(11JKK)!! j4j(S-GREEݹs}zwU=<<(33.]D2 ԩSqRR*((ɓ'ӤI-z{%'''R*t=R*Db(DrqqHK)22Rcٷ~K|uBBtE e˖9pу⨴.^H:ߔ)Օ?np16)ۛV\I%%%TYYI$D..DDD DDӳoy9ŋDDRJ= h8%ڕOs&Z(5H ߟHKhd" Gg~ŖPB񋉭m1yҜcIt(QEѝ;DO6\B'&e.fQYL;#=EsHcgz>[㗬 Ly1+3PHT*!$*xc(OL4`a8w%'''pZjZ,,,T%Kٳ5q7n|h/۷Oc{ҳ>+)#FP\\6z'ORmmj?͇P^7GӧOk쟟Onnn>>>7 SȾ}ޞBBB'8q5_11Ծ:uDzS^"}D=H+[O-SLsrx]R{Y׮ԩntݸA$̯2J[(~1r?G!9&ԝݻDjÅ~(]JGjkchLj}O"Y'Yu|YHT*{xr2_{ 5CLrc=*v|/wˆXrՎvvvtvZvmڪd\.Wm>ɸuRuC79r$pmٳ>>>XhUǯipڝL&{PҥK֭F Ty11J۰aðh"˸|2z-$%%_oPw)D55u׮]t{Spi?~wΝ;OίmIi_Gdd$&L___3=zPKLyiɀ۷f۷7?Nvp[V?@}d?V.L6HN~.`iibPIGjkC!bS?4)z23$}^}9:3780kjb'[oSN;Ν;*ܿ_パ?RSSq 9s˖-Crr2 IN(}c4u}sW_}زe fΜZ~{R&리 FMM jkkADeӡCc#)aaa׿4,[ jFb (J( a]w IDATXzu. ϯp_SS!Hlt]om~1qX(uEي-3/%1e_[p<\c!S]~PUܿo\??14E3׸&VJc4h5ӧ` VVV8uz <-/wc񁍍MJ_;,))  F~~>N8R :o'GCbDBBVVV?蚪< /b+fmRPW| bbbpY,YDjHJСlYYCظ<=O>bbg"3 ]Zf4uZJu7yySsYz\c!O zյ; Cgt 5Lه5{91c5ya֬YHJJBYY.;6n܈ ={3fhM@@"##U"22c f͙3fBbbFΝ+)O?fBrr2ˑYf  رcaeepzK, eJ/jŋ#<<DYYrsse#8rju}%ӕ'F]vƍŋ1sL˒+fmRW`` ~' ׯjuʀD <?Ua˖Siӗ-ggȑߴc+0駺uee@||]2J-3}ߚUH@ui%$iZ`;q#PQQ7)70\$TJGXNlMCR)! egMc=7#">}Pv͍֯_nۛr99;;Ӛ5klN(;?4ɜZ.&}}׭[G HPІ a*$IDt=zǨvԇiԨQԱcGСyXT, 悂bYejMsK3\2%2s7R~ebbenl30#ϰ~=3{gx9s*87 B bڵ:j֬)d26*Ocݻ WWW$j׮-DZZşל4yYk."EʕE=ĵkt3U^X\??!r!j"ϯ("4TeprR?ir?kk."^BT^)Q/o߾v|||0tPs% ʖ-xyyrTyAz +k؋slř{4ي(~|""bh0`Yik:dS\Fq8FwFc򈈈JuH'"皽!mO9وJ*uX"""*eq{%{qa@"""|""*W^E2eʠI&믿гgOB ѣ% /____)S8u{~1+WDڵP(h۷oG`` 3f ''1M6#|||vZ+WDZP(PV-^:_֭ j׮+W9ei&߿?--/s^yCeI~D罡s}xbx{{C*jc`>޽{]v?,_[lիFܼyիWGXXN7oݻΝ;sXf oߎDncƌ9fXf RRRvZ|gx L:K.EJJ ۇǏc޼y?׮]0|pL6 III8x =ݿuV̘1VBrr2VZӧcǎ4"%%WƬYl͜29s&,X$\p* G(6},)wceBh,c8q*ʪ2$""*I$֝#VAR)M}_w !D"ckL'[]6:ۏG(2+ǏQ~}PšnݺRJcoߎ7xCﯿ/GѦ4;vٳgiӦ  7֭[cٳmڴĉѭ[7[b…࣏>gmY4** 4Wߜ؞ei*üim{vD"ALL ا 0dR !bc,/iIr\"{p9>|86l؀;wqz-C"B ԩSGUﶇӮ];!!!ctt4Zl \LT ooo\v犎F CHHζ.]S5y3Dߜ܍-4_hci$ODDb8x cԯ_/8p qdgg###JH}zjj*㑓R J!D8rrr ;&6sT37ݖle2JoBо J5{`ĉ駟py|}ΝCxx8W\gǏyQ4h@o&M`۶mÇ/رcbW}Æ ikl(Ssbǒr7Ur<_# :ۢdM$lQԩߏ4b޽]v?V^t?ÇyGG"55G~o9?X~=K.bHMMիW}Ga̘18rN &MҦ2Q8C+`ܸq}6pahL斡=G&)ѣGc̙\2j֬謢vZpuuE=弓'OƐ!C>k7K/_~ׯT3gbo߾=,Ypcǎh߾v{x0e:u)S`TO>QĦ%n ϟ> B[g!иqcTT ǏGxxј)C""@ӤZwFl W'"*`*EJTXDDD~jV-dz'""""""*8J-/,w""%6={JgDODDDDDDTjODDDDDDTi㳁ODDDDDDT 䙃ODDDDDDD%yl`DDDDDDDѓ'oP7 4 p,4nʕsAhB@TP B@hP>'DDDDDDDDRi |FB@*t.)H KDDDDDDDTȸQ;DD!̿HKKCXXׯoy핏)㏱n:#|l+V>S(Jxyy\r6;k,mYu}})|7p6NDD۷ùs{fqfMo߾ .|"D"AV oժUJš5kЮ];TX ^^^ݻ7o!{5Ȱlܸwܱk>CE vZ{u>}쿍`ǎF۷믿OOOϟ9e˖A*_5y /6nhDDT 4^{yynQgC=z4#GѣG:rrrЭ[7رgFBBp tӧO/]~߿o|cccѰaCܹUV5gNЧO"u4h`LGÆ QbExyQ3y$/W^|=DDϡO?sͷ}ܹOu-]ضmڶm 8889bu۷oGӦM|+WDZP(PV-^ZgD"2e N8;;#88ׯ_阿 ={*T=z ))I'M6!((@uBڵkcʕVݣG0|p4nFJJvJҥKFO>t&Nݿyf3gԛvڵӧԩSO>N:yؼy3.^m4`֬Yر#0`T)))9s&X1 ;; .D>}ƍ/ @~퍘t-Z@DD2K "oppp3'Esݻ7nܸ/j >>oNcva׮]>|8M$>#GCϞ=QF|OMMuzz-xzzN۷c„ 3gjժY#^f͚A&aΜ9߿?޽ @ŋ1l0o ӧO 'qy_k>gXh]6{;#^.ƈ˾IĻ&6nX/277t_\|1ZiB!~Gѷo_>}4B$222|y3UV⧟~2ub֭:~ѦMiߧVbEy֣GNQQQ:iݻ'ܴulݺ5_* *^O>;wP+bbbĥK!˵iԨQxw~$ڵk'pqb4,ѹsgѳgO#e˖b޼y4{_7G ___E7xyO>-*WlpZ #GԻ͚5~L@ܾ};_ڏ?X4iOllϠѱcG|rQӏDG0%I$Ļ"q-qvpS$7n[\_#\&z;#ԫK$\H9ӫW/̞=[۫M6K';+oODGGC!$$Dg[1dmuѾvuuջÇ6s ?ǏQ k4jH罻K.]v:i|e9h ( tވGLL 2336m6~8w޼ܠP(...&T*J7nL&C\\w^m:WWW899p],\ϟsӣm* ѣGo߾^:8}4nj0aÆi P(pwwϗVkCDDd ML^qQJǂ )SŋѢE 횆 :99YuܳTL3p@lK,rrrohu k1YZKzzv|vv6iԩc:t(n߾}iBڵQBmڿՃT*EJJ Zh=z`ڴi\2ϟEŋ+=K.?cŊزe °b 2QQQ_>*Ud0͛kƢN:Nl5n8III{n-GDD.GDٳ'~w?o4fϞms /";ѣWc1ܹsG!qYhذ!?Mߓ u5kvԍ(\rW\A\\E4 uCƏhܹSKL)SF'm߱cxbB\|eb„ 8s Ǝ~ C_ܸq[y 5iGR QbEidJy~d 29d2%֝U NDFoCRkYZ_lݶ-R$ ԥ>t;rZ"2bhU P# ٶ0^XG"kY[۳k[1Bthȁ>!FUh]N>[naI*DDD`lR2}؃/}2<ݯO@{\YAϵL@f|<&OgsH~x&""blTB}@n_U1B轖~ƎŋS^XG"۔zD ч0!t)GDW)50>! _ DDDHdP4[{gX`L $s&aHkY|t4HdPӴcHHHȷOś k光M{+DDD#mJJqظiSśr{%!ts- Ļi"""֑Fżޗw=={5P۷!ͷ#"Iߪ軖k[Q~x&""blSR}o-]eYՙ R,PJ?+ea}s:MDD HdP=M=R̢ŠQ)  $EY!w=r J&M=DDDDDDDz>P.|yM2  ;m!Hr5|!TV!7t(QڵmS!Q)+v6 L.()BT\JIu@DDTȁi^K4E(HJEy@TZJI)oʅ SXf37^%)f, >wD_Je|R#(IGFDDTk[:XtE'#:v|٢cJk**U u۶zNr%f]inPHO##N=x@|-ԯg-nHqKw #RmŘ8x,/E|?~Xl1} ܽ{]9?C,;D_ -:ǂEs$@DDAa Mry>|8'&Ij*J%JOB.BŊR oVr~^k!GVMyW9$TBJDZqԯtѼ}ӧX[ڽ 7oCP !.B۷'(m,YiYchQC}ܹr"}La_y7o@VVteQn=Tq(CI/z$1c #=UTzT eN ͼs<}e˗!b͛(S ZjaCHm-\nUӯf1| ײI N.ÃȑAY3Qig0G%UB eeeaAY&|||j ##ᇍl?#1KO6߮̌ǐr[n!qceuq |kA&C.C&A*B"P Usg[s?/vQa?_Y~t)v'O'''dffB&CTBx1j6zǍCvV66_< "$$ĚxdA q( RusJZČjS|DTzL(*NYf5`wߡ[%̞5SEp|[\ʕ+m 0T*ֹ 9 GGGmiwFq&Λ x kCΝQlF*3oycWbEUڨb=5k۷age[4_?k. Kkߤ ۇBMbGʓR{eر:u 00uE`` иQ# h+g۶XhQ+{nعcN={"KZ ~sT˖/GVE-u߭GQ AMif5?m7_!OO"EZQA;ǏÇ@DTE8۞u<R^}`v;v3Μ+0q)l T*1*UBP` 8~ DJL?v84kAty|>3޳Y6߮ͷ؜ku%NzX|fLΜƌce8tͱXC  צ~&ժcЀ4`xOÉ sxϞi< ,DNMuR"÷vҥKѥKATBR LWWWO&S­ݺ-xreVǬq: Oү9]e196+ocoŧSe˖-[bjx8V^fSk:}7M x(|<Í-PԾg`X`ΝhǐJ0~޼,{""*8upXdggC*B&A!J%$ rrrPre899g֌/w]۶hٲ$(2LfE;w6^{oMXL'9f45iжm̝= -cO˾5oڵ Hs1- T*EFk4[oc9yNYQ7Y 2|56GwL?cn::zlw<< /Lz%9Ⱦ}(߶Ν 'a8;u1tE3F͙3K|@5z7uyQ^b<ܴK,AϞ=!ʖ- *!<~5}}s.wA֭oMģGvj4m~X'qF:%+WFNN6*xfaĈ4pbtL`*-X*+w)jgU @C qAvy x Ynb/]˯IB߬98 ]WW)V0:u BR#|PգsU}zou5~GS'NNN&,gϾחZƗ-[f͚ƍo߾4iX7pX\(>VyҶMk<}Qml?86 x)+c4s':|Kg^˖.5zn{\wIae믘7wEשSu?KBBޣPk?[p9KmΞ_Z6k}JeNDeZUu~Zj*.Fc`60H|_ݻyׯ_GŋXz5v7uC=@FK/ݻ6{)'Nދ='ZQ1b2225j ;;[+WhBF{pj|[~BFf&.>6P'bDe|=ؠ&ʰ|92^5B_n܇]l(5ݠq}OWANN?~cǏakլiqFB`wpIddd ==ǎ1&Cƌ3qYٳ1s& 5hbAx)#(ϜukqlY% %"{97nݻw[tQefgѣGZjF5իArJR`~]^nC$dk0aܩ6MI49 ?t\~0Bwy`Ǔy$y&Mip1Uĺy-[ eʔ [J]aJ ~zir>3}v4mF)."*Y"OD{KT_+F~$ЇTrz8I>6\YL|~=VQcƠQ`BBCnwiӽۛ`w{SgWyV}e_ĦDʃHcЫw U/ ""2C5k[HLLDٲeRp_b 7 4i"VZif&и;r/d}}`qAewz=6zL3ODD ۅo-(q#wT*U.\0vb\\o[y{ݰABz@q`QQh,a9PTfJhԤHŵ@DD$esWpٲeѺu+*LO=(cCqPZ>QiOS,{]VGѢis;cZ_ ""qW䖡J% ˑ%@.Cpq16<Rq])I4@GGG}rXw0CDD| O^駞7_oB@~uv.h{NN%R*,{<` /*AHHBUD*ŕHMM-ꨬgggxxu(DϽU=p޽])I45}Xyhʅu3ouz˹éSѺu+Hd2N5D!pis)jE2}~YY;l 4𽽽p3>wBrgʒqnnPΥ:""źiQa7wQADDD%DDDŃ """""""I@"+Qɤ^GK"""""""*i4mz'""""""*C: """""""$U|""""""R |""""""R |""""""R |""""""R |""""""R@"q(_U^ /AyDDDDDDD%Af{#@" |9H `;X{oTӃb㞈;,?k v/lODDDDDDT,2I!DDDDDDDT3D_HE!lї@nz$|""""""а%s e=QbhX~B;(|!DDDDDDDE˜ay_{L^b􉈈97M WsN N 2gX*P7=%.\r+󉈈J[i*|ջD R )ꘈ%($WON_wTYrEp+MN *8$۹@o:+r>Qq,W]V 4*IENDB`mathgl-2.4.4/website/udav/udav_main.png0000644000175000017500000041606313513030041020231 0ustar alastairalastairPNG  IHDR:sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwx̶@HM^X("bCEbE`+bWE@I ,im3,I؄dݙ3wfJZTpkZIB!B!8)scWs]F$", ~B!BQ|8]nqXyN &]GFצM`݉~n{+B!B29#ȶ ՝#@`x 꺎((_@!B!(LKFAA u]Gc] Qgx_4 ťpi:9ɽB!Bƙ-poFSZB:@Um(=?lkhZn%t:ͣEMU+EQpk:UAuRSٗHXh&Rm !盁/qONBBq&sm VѭiXn6 F+ ^YFf-9v GB+p8fЩsg&vth'YBذn-Jm,!B+VXQf34jԈW^I.} y. ȗ_|Nxx8?xh٢)xb5b)U_Y!gՙ-/nM;]6MGXay|dތٲFSjЊnhݪ56qnfCQU۶v˝B=Xi3ӦLdT/yZEpp0.Kxt-,Zy[o5Bqlm_m{AYjy010`6hL3wi_EA\Qt]E]/XBNn.Q5jb0(;dENn.x!HFF_}5[ljBmUV~y A׮]ygzf0 pKJ~'//ƍPnˍ}fϞCcԪU[n};w̙޽EQ_7p;>S]߾,]otjfymϙiHP@^8[?ϧYf\~et]g(o˂ fEgϞX,.M`]w]677ѣ.\B?ܲmA'1KǣT}9 3e8So[Ǜӗ{_Qt6lH]-1c2hJ`FQ守idffK-~ڿcB ,˯>[2y8p/G}^yuv{wr \ħ_|_K͛o֭mxg0wI%/^\ul_noELL.^ʧ_| +\u{Aǎλ`?K̳eV=%^JMK9r[n@s?`%KXvɒ%8 B/|%bZK䓹9ٽReyy?Ƚ#O?+oO>ɞ={x7de⋕j_CU< l ,=Eb<39;vvhh`A5䡪vnf3GW`/(^@%/';l+={3Kwȑҳǥ_>'2Ӳy3sc~4ڷk(ݛxr| iǖ#c`?}gEs9z1? Th+ע A^n.O{O>ReYy뼟{15k6|=yvML;d|,"#*vѠ|cL+9<;Z@)t鲉ӛٻ}2[|Ŏ8Aq{n_ư˅88_d -[b)yш8].BZjņ3f :uкu+^=QQQkcNV+zMlNi/brzLnly躎YX]&PLx+VXڷkK~^ڷ'&6{IDx85~ؿ;vЪU+o_>M7$?/_!D[>}Q7ƿt2w9a*[j{ѢEL#> ZnEf͸@kJm;Cҵ+?.GUt233Umq;]WIN~x>L^䐐tPut侈 ywA-nuqB!NʫraaIJJb޼_xy~{ +V=vϞ>ՋM+%WrfGQH_ (=_qy}h^mڶ`9ޱ|rZԟCzWj{E.J'vmRSSK<@:uNaÆ7['t}Yl9`Bo_ ˗/ѣ,_@~}+B! rl+'2mt܉?cɇZ3+[jéW7pI>zFw_۞1c֮'VM=`ڴ*i| Nө[.әItN׮Ѥ[cn+g_IKUmކ`: ~[@5Bq9ٸn YxFCǎy5$;VϿ_ǽ=rd?L&>svރ"==ZOsϨ¾~IKKϿE1|8?#Gp88r(Ms9ɾ$^{}2֭[nOl޼›JŞ%\ѣGټe &}p88q>}b2~BOYe +I{wg_x̌J疾NܽI%rգ{Ƕ*ݾ}{=}{fJ]pM3ٺu+5k 88ݻp6yxL.3 ctFDNpW^PfU%22cɬ߰mېsZa_K 'e՗_{GTTCO~N6'K/gʔDFF0rԽlذZqͷ29rZy7iҨy>珯?ŗ^"//:vƝ5jX7~)oŨ{GÇ /`8EW_MTT 5=8ѴY3&^ҍ%4x&HZjǟ}FvHM> j?x`t:#KN { Ny:HnaH!ąLJN 0D3c'BUsQ |S%53n-ʢŹydf~y >xM>FҾDiԸ1 X,;FbRaa4j܄:B!KE |u+0l'5-?Ɩ-[ꫴm\wO!3[^mO+t:]7viA'tt݈u#}{HB̧ML&ujDJJ iiؿT4.j҄X"#"0BjquCIJڏleV|0#ZjYbāBq!8vu+t R;~r0hBq>:ϤаpjldeB!.hg2dƍ|g X}/xO|[tVw޿i<1/MHۯdǖM<Yh!-\@Lt4oOy2? dzz2&8>W*1Ge岥W^هe?eo4+-?f݆ c:v_~fꕼ3_X5k/yN?z*n-MXǟ|ʤ'xLdLmVG!BqR}Fk0P5wG~֭ZzKIMλG2_~s]wsםwзwo﴿/G꼦cYbl۞gѬi2cеױew)Ռ3-۶gάhѼwL^s-+%x)Z[n;︝+g\ҝ_~ؘӮSex Ϗ]ЩCZnM61'Qٟ*z ~t;Gp]wҧw/GjZkqȑ>e>K&r1ܚVL&>hož$\.jդ[׮~f˿x{Eޚ25k0bp&J*1g_Orr2q<0z4=w]t'1wٷ/ZQr3}1[m'(0Ν;W?ev;111 F;OE'__u}z"--qO?CZZ:kqm[SmSQߪ{B!B]wi@#rw㿨[/suW"B!&b`R!B{&&RPPmxq\w5[B!B6D_Ku'#Ԯǰ[o9B!B}!B!u}FB!B!(|!B!_i;B!B!Xx7۽{9Bѽ+>G=B!Kc7(pBS̞59-B!b5>&OnBq.9-BxQn'B!B x|CCܹo M鸋V'eAHZVk9cU"u֊UlL܂dn ȳoڀ1qX[Q̈́* S%ZnNYɶnå1=ćVKdt]N:%?rRvۮDL֬Y~_zP/j[ر6 VAۧƭ}ka=^.u}ƭzUK,e͚55 yU `o1L(+( ogr{6+Tk IDATPIQQ-1F#4f]e_+I\[Rkk֘V_fѫseR:/3_|Λ[oœO>UnK1@"s@߮sy,k\ֹ=w,{{~'}EZаP@cÑ}au=M/yE-YSl"1e^*Mj4>c߈J?/)u^ujF3Ų喭U[䯿1L8NVZMAAz*W;2sꫯk׮gÆ Y~'rN=x⋫%nu'}lJ8u=h>Vd5kx+ϗ^z'hV1/ˁj0(ysss8x FO#!a})HHj3~}lw8a(X*YY &z huW˅l&+!7??]vUxN *v u( 1l04MCU˿׭q5MfnVҏgRF$M%&:ck}&elwt` bCtizpr}^kz4"4\Uu+b n/8%*aDS;.ZVՅ []$nŦ]Ht? #))eNRYc*dO4Gh"l69(˷Hܷn3Np&VlJEŵfYb\J;[_Mbʜ ̙sy++vKc+6A(=k߻3zP 'f*9:0k Fqq4s6y~̏Źnwu͓_ݻp²wJ-j'qTUEUUEQ_2)?NLL lْzꑑ?LHHp~ݺj[ڗ_}xgxc|F;8#q+kT:nگB?322[ΤĵZL&5 UQɵeJ'zx|(r L5c셹 k1^ O"BQ4݉F bGr]n=W\[?={zBdU tzuvkewXs`ŝ  aTmIu%.A\l٣b[2/ҳs#B@I3g^Guಎ[i3{#4MR"m8tjF \#1iS-{ fg uvv̈wpuC0QGq<[yW~%1Whiu&55BLL ĭ|Exݹs76[NӁppر8TUo(9AeTvۥ0Cu D:=3ɘ` 11ݻǹG4{'FK6GO_*aa5"?ϳLnv{Ge4yyy<8ܯҦUO0h. ͩv`O0G߄ԭ\>_{}&C ޗܼ95bT2TE;?qub g&'ӧo_t]/sGlܢv ƍ ;[,6mތl.йsgorWٸ8qO?|͝;Pm[\JJ 'Of:~+d\qƞlU_N]s>ܹD;VS4S"/Ѷv~V&8N:ě/~@^~8NQӉ}p.|*Vo\y6/^G7FP+ר9=~_-ں%FczpxtTŁ09hz5t:*: lSַcͱPPT@;Q 43C$zxtzAÆ L8eOr9*dDQ 'A(NF_NTdg{ 5I߬gPDFbTBiAYm;kV&q8-Aj)}i0oܠ`FŔ.szuu94lX{؟dh4W3?[z7 ~>SRۥ7EQ3SPBB&&`0C5C"yّ0:\q'7kWl4Kǵԉi@VV!1 uO)DI}IĆ/ Ad\gEA=}egv(XO iE5РQC; $"_q7[ޣG$祣xvj&Z]D1n(Ne-lXIwNbb"!eU6nQ6mbȐ!>߿s/+\.:uDf<#RLn'## +oeiӦۿ-诿x bdgg{w\$$$5\Ä J6Z׷0%(BW ԊٿS) YT\]'**z шi~׭[cɧ._խxw>&ЮMpp̜A㘱<$7mA`+N_W.*h$޳'mv^_-n]v-^{wSy٫_qxG:t(ϧ^z1d222HHH~0fFoًvCN֬'}= P(ZΥ"A[@OTwb6%/r45nk+OXp<¡6uҡz 5E&SϺY*D4:ĦMٸa3g4)* ZLk+7;9  7q⧩>ҟeM!.P}?QT[lTʖ\))9|?rQCS+"ۯl^%GK׵};o>!5 lFuѲ1ݨ ؗH|ʹ曒IRxа0r}/{ !arұZ&ӚIzqgdba4ij:w'mڴna קc˯ѣG_СCW6K.!//?kʸ;yPlYyʝg`L&ۍ(>Ft-˜9sxطo7 |T|fu:Xc@hXci9L-J7d mgg]2l 9q%wuj:mudoA.nHlP,5p 5`ubp(h޶D`4g1MDǔ\NERp/:*J!ѫ2**&$?d`0b0ChhhyIİgzŚ5k⋙5k 8GҫW/CLL &N?>f_>yNU}+Gr2۬;SV3fiӦ4jԈ?pӴiSn^Vϓsd2asgϞl0I,5ˡx" ˆnx֭{8>=oj(U4=nmF(v f)X##}7 GQ-&PtX7m05iڨMP"tŒj^3j({=@oDtfV1a:8Sق^XRUUVsa FX|%=111,MX?bԨ{Pw+7;;<n.^K@sskw?rl.ٗS/pb1vYmb 5Z`#w]Q[3;BCn=>! f35o47Lȑ{u6Pﱇyݴ^=W  k gt+[ " DGpI^~'rs26;IU/ر޽{}>##]שY&Ap0-ZĆС}5kJMIIAu c,[=WKܲ[L\_Yn?qu3h4b0p:\.nwD]ff6ĵÆL#nwPPP@AAbr\_VZѣ/޽;7Çve\*A_|CO~A>cF}w3>djk ( UEHr:t]fL]ܚ Ӎ5c)qƋl#<\Z8@yһ!Cw!(8m˟GAqclQ0Y"hΥ#01!Qͨ| =j4b"u+wuL9%di8h}k.ŭnw\__z)K,#P>>}TE-W-=.%yqEJ_m1U7Ixb&$p] ɉ'd2yExx8jr,-9sh"W"m(X=dOiQt,Ҏ/G^ f;`b6g mì,&MM7w}WxC8#otJ;+VU;nF4M/3gz+ZBezbZ%T۵^H#p,duU@r* %{rj1 ),wRk5¦~D_0STEcQăjPAmϏ4b)Qk/AJj*ǒˀHڿZ5kk:K.Sg~ׂjпC/,t`anІ10_T KDDD1X.Q~-YҦͨ5,=9 D伍5ͷGǖslIWn(  ,(qi>vYfFog͚hh^KiWV {]:M(=P⽓{4mt>k@DDD5+ttUǕJp P(PchPKJoLk!h2Ю P*m}Qٸ֭gMCة#GOw([ڷo_~i\y\ڣ{\~+j0btgs$Qn"_8jf5q4u-p9bŮsV$ezx+` u:碪& n7_"g1ի~'}u18(ӉQb.Rg;[xɧiݪ%ڷDVC. ta՚l߶]VBh$'']vqA򈌌vM ̤eՋ|bl\DNN ˖M|NfwZV+IIIߟ~:u0_,TɧW^<U[KwEEݎ .QyP*Rx#XO S!Yyjj*&ސykAdy J=/ocɑ,t&( jZ4w_n ,J!b'ysl3_q=5&:: i?`wѿwUU&//3S]iuсIQQTw~[v2YRqvHɳRQs㶈hA-zBh֨1SOzq7gύpnt4 o\_\.K_,gɻmrq>K'%dR7X)=Dh0`4< ~Y؞3ݟǩX@϶ 94$ "?%V6]ڀe[qd6W7(Pga|bKh?*sC &xq㈏/\jak(B`` |:) .籂Z1.: [hZۥd1wp0z GN'y7ڼ wNwQǿJ P$@ AA(M_E bCQqD*(z ҋҒФLRHyd6mipk.ٙ~fӹ.󭬊xxrB| +Ms_^ڴݍUՍZr4 w7Wۛ%VX{&TĉtTz:n5kaHIImtލmiܟLx&Nz+NģBb:?κų?rt7̙)nT̗&j)/}\s(j`=SܘoCQ|i%9111ͽPn]bb,Y#Un0ϲ#hekJ1`_繕fzh4e (c?%X"×=>&Sh؉m1III;*C5G\NEGg ZoJ& k+>DΝM:wÇСC6n.My+gdd-5PQϝ`YZ0(F66B~~.nrr2i$ݺHDj؁k{4X @pas1nfl SMzZu>Ϫ LPfgd-Q" wУGz ?K._ꊓ۷oI&E4qv/_nj*FcV J/ G cܹشNj'=߽qDSQ(a!n@EM;DƵ4l3P =Vz5U٦piZtodA<5TzF|[ *Kvvރvŗ_Rͅ'NFrI8F7ޜF||<أRvm+Ft ԕ+d[&7ob4> ql}-)⁣`ƚz\`cLy(gǼ+$RIL9;qZo+K7 Вo@ kצaטԈ#8=SAqQ?,?ʪx.Lm//JYqӛ}Mj̑p߲eK>"/m>Eĉ{ӧqvv6ԱV\MS䡇/`̘1ʢExꩧXdٹJڊ P޸V c먙컖=G̷XTQd{0nM-[51 f]2 MM`? z4 A!2F/dw8=)0''""[G4ʕlc3u5bС$''ӭk׬"9YRA}4o`QQ'!jS’&akXAjCN~jZ&O}'~6Uհ1X^! ّo1[GUUi\7[Ixy!.6TY`@ W;G  stAO q&&ҬY3j֬I\\;vdϮ]'$P^=j{xPn]z֭[18@]\?n5kq3NB&NFDן^5pw㧟~b_ѳGwT<V/Mܯߘ&3zy^Zh4sIOO#)9KmIOEZ-0^Yh\\gW EgPƲ5N:DGGӴiSӾh}NZrJwcs1\}Y]sdL#/S> z!ɓԪU 4 Ν;G˖-9v-[$::T`,k\W1`q- 0أ^35j2,hRЌv{V@d?I!,FEE1鱤p)nys09vǎiӦX&)mܶm۲gU?~(m@RRmf}7U9;;qugO7;vɯ{,L!9%_~o/Gm>}xcT1oLԩo0%4jÿ1ӛgJ?`qGTB8nn6_\>7R gij^QtRQU?UU')) ͞_UEuwsw9>)noP>I,WT(cHq`' /rcCᤪMI3z;ellnà=FJPff&-Z [O?0i$4a'Vˍ*+l]:w8~x_q+*^ly`qe η&qkT'%,qǕ?]``$$^ΨzzC,aApI~|<.!4m1sNr[Yթ[ }0Y}рMr,"Wgg'WږTۢ?G""ILL`0о}{BCCiߨ...\v GGGիGv8tnnh_{ͷ+Wqb5dv÷"''O5ݻ7Ý-Z)*K7oMg }ϩ%q5;!bLe"L-pwRquTMC4+\\E\U\25K.__|Ѵotբ[[徘?l B6`iII(qu@23ҳ0y`gȞ}nNN5jφiUk|^Ya8MӨ$b(\\oj)Q1 E?Dѣ;#a̙cf͜Ihh(uX[f~͚eqZj1l0{[m3Ah4~)%00L///ڵk pY;fzӻqdff̳XC4qss+ޞٳ?*|sV3ܒ_|T/5kҨQ4qdϖxb}Y4Mc…J!UUN ~1-/>;{'RۛMI NN =Ҋ 㪡3 롤Gw {QZpCmERCpRlM\OӸ \KqU;bU ky*VcQ(UUQf͚Һuk7E4IKM#{^g֊ۼ?͛녖<[G*0͒p=9-/x7v]bړp3i8ǹkВ!?CTg#+\p8՞?&eVVsnu'K}+"6MMHOK3ǒu!==CѺukׯ1\aÆddd;...:ufM nz>l(_5Ç aFy8| If͚<͛5+S\n|ij[oMCӴ"?eoXϔ tШbU']>/L4rp3gdW޲[/_bHQd}!OZs-#ӑttL + (hd3ĿiÜFJpAU5k&[u?GUU[@UUԭkz/K)dF53,H TT7L$nXX8O@lL,QQQ|8;qw` yjbcbiצ-?,2!e z<8*’%iP߇nݺ+6!ncǖ-y_(\rL7n`䈑L4MXzj̔k~^ cNhqo]oIҷ$̘13 jݪU~.6F#W^e…pBS%O?. $eyy;8vZ9WT(ㄢ$+I *6nFg2U{YJ/3`EF3ЀJ|O;/[l TΔ"*7vF[Ӹqc?LևT killlh׮[nٙY,j*}<P#Mkդtb.$--gG[ndxV-Z~q?T;;aƆ̌ PMbzȭTV&hORI6:*33*Rf C٠i6jYXN59} 23Snm/@T^1łE uy)SʧYװA8=c 0Lq325>ָ^@WJI#51[nq>_7 \ QU=naFaZrUjL{M_+y)lވb.9+S >jL-ҶI.$5vLN+ᐂLX$ hcȪ48Yf-=APpU+&Ӄv&&N() ͛qqB:v"VjI^^<US;q8gMw1h QC޵s 9T<7l˅\!\۵aV|#>q Mr [WtWW\__njѼygkĵv|I^8ss[-gjv{ok}& }_,.{z &*+@Ff&WJjWbӯ jqE)*H&OXcrON[':ըA琐R'c͊ISf*d[ kkTx0[*?\սB4x>u+bCڷ#}BO-4~5Z\kZnn-Sj+ =N,q"VJܪv%8z^*dɱ?U0G8p`?.[Lxxxhf+q%n[\U%U)UZNi&y%Eff&Nӳvq !+qW*b%ĭ:qx[%Ve+M@fF .2eiul];jfg !(7WGnyܵTq%1AEWTr$Z%g<]ʺ^+qcү*v{4( *1+pߠAEUUÏL@Pc侘/e?/vޓ FOV}A BQY/Bhd$WT^xyXqr_fo B!Ba%+i侔L1uB!Bq*3 !B!+iB!B!n6\Mn!_{+; B!v#mʒ#J^N!Bq.B!B!mL-B!ȈHJz^޸P12K!lJ7S#{|) !m*2"ܾEM+CB!Jؑ0qdlE){8h4BXCbb"AUUۭG6Ūi !B)dOÂiBTiqhu c_!B]v^&Bۘj._o 3S5%K !B'2pÛW6 ބ({P ƏoHZmP"zTTSx9}[Ʌ'B!`w7 ݜv9]diNrru'=懗WwqՏi%Vl{!]I/X!BQude2X6;'1ujiԩ;ҥB\GFFVBGӴb[54^Y*  lݒk1$TxkA: !BTEVJSudx{oBQyҥT&N<˯m׏9?3Sw7м|®ӯ>6;>Nrrf۷_&$d'/72x4k'5jlf_w=Ժu5=rG_fZ+KUV\!Di*j jԮAhoFsFVk}sk>!Ba 3avuzi׭.ڷEtt_n)vޮ!%%?•+Y5s5sdpL"#"(ȅcxMF8K/5&.^V̙m[N]v?gäI~̟_R!HGZN)Uu(*ʊ+~4U+t =ʀqru"dbbN&&- ?W!BT= IDATE?8ؕos1ن [ѡ{i=3f^̘qoॗ3a鸉z5#O3aʔbΜ@>w \WWv4țAD#{xdpJ~BGUUT3ׅdhN*ia-[+B!ri:*3fEԨEYo?5'8K7NizeK#Xس'!CgO®^8꫑\Z !D5euϿe\yC9‘G8ri.ztB!^ S}k_|7)Sq VjG89IMUqtܐ8__纹ْnzFݺԭkuTT ͛Y8!gk/GҴ|}kйc|kaw Bϵ !Ba5҂okk>~KжmM9T0S#:`{t<]]m߾h<[f 1~~5\:kO.n̜O??<S +XH@@BGC+Ok6=f͚Y6 m oB!DUr~!RR2qp[_,ʢd _RwڵEφ@֮׈__*AbG+Vx0dŴDeBT?Z8¶Z~_o|h h`ccS9-'B!*XVy.f<`/AL-n1{iΝK(gΜ3|9,8DZc7ל3N|y/ɖ- 阞=w7x1 [|z,Xmqb֬:$&IL42sf]s,BGӴb74wSYB<&œ.B!UK${6>.Ç׭l!DAFf&( 223lXB!(?V.$mBQ p03"KUU* !B-B! *#aa8 Y%=!Ba=Yc|! nݺ B!ʛ,AQo]Ç QQ͚Y9FʒYU!0 (K|2gߎCP6Ԭ ;Ú5s˒Oubǚz>xi;;W?/\K,}. s5!B!ʉJ nݼ {Cvpk}@rr<8̘Q=k(sBCx8 \˗[U[и1|Yξ^ >^/GGӧҥR[@/4ve${ ж-Y_wՏy !BaeETi%KFSMߦNҕ!ooxQnK44[h۷z/=]~j $oYFW_-[[7}ǎb?JF o{0aww~>ĺΟwkY}Da5!B!ʉ ӕ騙*;\߹cO.pXwe\}q/p|d4Cfzf'."|]t'₟:e kז,P<11ʜ0qb1/8P=p ߸6kjք}a4rwV[}}7 o\WTwGݴia [Q^<@dYs*.͇ɓ _#0@o_W.-%ϷuΰaddgsPwM!Br-i+†HOIg|e2 fD|a:&DGKy-5FΙ;9uZŞsI#$pr< @z~4o8sXE`^X w^(5W#%Ok9s <\ ֽד&ܹϙ?}Vf>Va5!B!Lz-e򜽝{ݦ׾|o}lvI) ~8!wνh7wvL[-9o/_S:_2ZzZ\rsٙ ҡC{"2Dݱ#$$={6mcyx/ȑz#ca* -}[)_޽oh6ݴ7l }7]]]a }+w z f3fG <:'O.*]\Z &M ӧ+.M?v>AkίO㒧_Y:Ao_4`{kz;00˗ OțVl¾k,2"Dbc7X%=!ѪU++;BJV.6O)ϧO'z9QFl~8?Iʕ=ztk˵klP+)r!KT>CV\Ʌ HIIp!rZ_{-O#VVkee*IUal}lO=;mު 9lz쫯ꓮկ_عcfN ÆW\A‘ߨQУx%Is`'Y.#>j>=5^#qq 3g›o,`{=~~,9fR{>WS|VMw$ weB orJΞ= ``͚5 RsV.U`#))ע1|+Mp#hv_3¾֏] ::)SgVZE||*;52kIk3\@t[w~t %*|[g+$,wv:ծmy_;-Ex`ksQWƽ6C[+^{zs׮{K<}6VfQg]@qhZ.[\u !(کSKF6l˖-},YM erքO<-[dԨQ,N !,^ilj'<._SsڟK=}:7qgm9lfr.)))888ٷl2zZA ^B_seȣ, ZpI]I,Ѷm0|˜_RlR CC}l٢_giUԽ.̞=ТEbǽ4 >\_BoCr>Vwif !'22/;Ν;;v,}l޼ [n;9(fѯ ]JdҒ8 t(}-?mꞟcb[ /HLL qqq̞=;Ϥ{GK.&F/= f ;V/̚bNLI+44 1fb9!J쭷(=./3YE|Y>, 6>}JLgp^#^Qƍ3%w_{8Ks>`̘M5@P^[z>hgs U0MUeBa]ߧAtڕ'Os֬YoCٓݚAlքvbL=aU|@/FmEG?b̝tyK<;g< iV?G-Q ԩzaP*\yvAv9ǹ+jہz#`ֈ2Z$xlڤ.fgoFOx/[^qw]/ŋn-[BL7c-1~>q\&9eƏ{%_ *^OW_{˗uIʆc>SwVkX !((mƋ/(1;;;֮]˵kѣK8In:uhuߟO>;we!e䲿C(3=v2Q'< Ȣ0f ^rtnڊR8򔜬;w/SWo F~\ݻٿs1jŶ:w'?{ CYD]<^1vrn} 9s~uƸq}JiРAk+۷s]woqBTcGrn:V.{pɲ*_r1}>}„ΉuMg]KU{}*|m~xHT"7.3v8ky}_n ף}]v1z2ҫW// O?TnqU T^VנB{YLߪvE6pT\FkhQ7#!)-ZM6޽Sry6o{GӲ.Z6lȦM|2 K,>} 4T(Cf&>1#0md@C3{bLMwr.\FJJ:Fcu{D1mZ͚5kXx1c^C)׭[2YBCC9rzj޽rif͚ee*1ȯ֍AVRtႧ IDAT}6`3V~QqMq? <⋿1{v? +8wj[km496w?ˆ |mc3Ϛ=[E>wGC!رc'N`tޝcrAYM6%88\gӦMiӆr#\vt̢oN׮ ;wͥQ̝e $$Kxۿg-o`gx-{ O bQ|}$~~]#f/wʵШ8/#l͛,^ wmB!UѣGY|9ݺuW^,^{ӧOsNF-b8;?,7nLdd$qqq<$rZ~x#C(DBq45kOխG?K@vhJ ^zw ȱ#YwR~zpa"( ,.(J\qArݮ&ޫF1&%x4^ h@ M\gQU=sr`Pf{k{a}߷hŇ]mJdzUpB>f̘駟΅^O?蠃x1b?8cƌL8z-}Q&NM7N;Tʕ+ax71b<'pBzke]xя~Ē%K{Kycr}=ih(Z/>}*)ך,3lu=VG=E1w\.2VZ9쳹[ٳ7jkw">|8o&Vj^{cX{f]vaȐ!̛7#GRUUĉ`/ҳgOz!رcyKcxl=̛7{SRUUO~N@n!cC1=sSL 89spGN;1rȒ{|L4c=Sҽ{ivhx<U|h a ZQ_CR j+]v٥x;|'<\plْqQ^^Ό3Xz5_=ƍ$q۷/˖-+Os]wn>x%^{<O3F)/Aa~P5_:T\w(A*˳da[x<2c NҧϮr[tڕ%KO>i "k4 ~)}3g;A#0xRwS":/ڵ=++i۶-H)멩z-k:}:](~_q2d^~eoRwjqμx<Ո_L&-8CdР=xѺukڶm?|i裏Xx1=> C ᬳbΜ9De(:ְ\]=+VDJ֚0ȇy|˸6ѣG3b}Y9Rw٪䕸,h~Cd #GĬp1Il*K,a?>c„ \}ΥD\whRHdҊʣCM.5d2A& $Bbp5JGDZHE}zwbԨQ̙3#F?;]x:|i(4[Nk׷o_a 2V祗^bԩ3cȑV8irA(Z 0]jtPABPiT6" dCHSڊ|+)M ƛo^{ɓ+J%g |x<OD)BG y<W^y%J)-Zpr>k2y1^d(Б&BT( =DUiXcѯJ.|`U/wc=x0a۷s-u<齃x<͔:FӧOZk.r1`RwS"9@"VZX].]@h@RHI% yN}xt/"Yrw=oŒz<бCGYȦ WJwԩS4.]oͽˬY8ꨣ8S9C͔)S8ꨣJM@(A $Pp>=`=d[}v> qs-|6wޙ3g2qDVXo~Rw#lw=2`Y7ߜ˿n6;vHǎؽ&iZYp!_=K,SO/;GKtܙ_|ߟYfqa5IDDhN=Ɖw'9sdӠAŢ^S`Ob ]s҉OziӸ9Ø={)5[%S|x< *uDwRwx<O3'K.{wޜs9̞=Apl}7 &l^{6Z2h@"0Sډ@Jd ُ4ƌW(mkOE<xW:iF([/ .䪫gի]xdL˱5ǫ>{x<` ,Y駟΅^H߾}Q[ bܹ;Mmf>Qoq%f4g32,LL&@"("R!aR}'xV軼tz\@(Z$rb}on3ܥ-ɓi߾=rO?7l+4_UUϵ׾㏿gUJ O?'7],<._~Y]Ϙ2e w:uOdɔo%{<يYhs;f\zoc 8`_~ׯߦvٳfW DdE6aF1_-E9TӢee: Cjꨭ%>! |H$tS8E:."ڵk:񏟠gJ{no߆ z, ڋ_`ڶm~믿˗ӟk)S|>y<ٺyXt)SNeڵ}|Nt֭laM"I=@J2"C&!--iݪ5ڶ]%URQQFFWWJHzP*B) /š?{ {H9I&1p@.rRwN~g]*8>J mnݚ;{x<6'||O<]wu]̙3s=K;O)fDM rU%[ߪeKڶiKԱ;uU۶ЪhJA]aVXA&A |"e,uT}S.~o̩OM~YY3nfc޼ywW^OuL2#<߿]x34m??nnr{cnz[]]կx?Im 4 x<[7.z+W_4I{uBmݚ=gsh"??ߟ3<>ۇoL !P"0^J}&KyrZV$¾sܹ3-;v}%j ,!YCfWt(Zjj4zLQLI %Ebv77K.'dԩ|L4k޽{;лwonV8y?RwN`~< \|,vVzdذwܮ׌T~tf%KCѧOZjE]]ܶ|Wywѻ ${\wewov=`7a̝;N: &p 700^(`& ȖQQ^AViצ-wCtn;dе+tw-͋ŠA+Dm P^QNY2eY\B S:ub^Oy.Xu8?M~˗SWWC=Đ!C=f_gĈ믿NIe˖mr]fʕ>f J&mwɿh6=Ma L:ڋ.Çٶ*0lr쭰 ٠<6mi׶t٥ t,u@BvBв(oAY22,A& aEPu/(߈Ks񢋶E_[/:t(o&x ˖-K/xXME ueР|?z9}tdΜO8] ι瞷 {{<—_|QzMZHUU5ݷߎ;lO.]rwӄ{<߆O?e˖1sLNڷoϹˣ>K=O< Duꅐ -%dk_ւ ZlM֭iӺ ڵ}ȎLH~ж-i T֌*˚PlY,lL6C&d$AF"" Ӷ{P')W@0 J7a̙3|rnRwXMˤI{3rdOvm5vp@.sO{=Ww+V6uw8# 馛Rrx<֠ĭ~;d,K>g_] 0h׮67nl>#/^ɓy7:t(gusaw.2yT`s(D(#B؊V 3} iD~6ȐUвel݊LVкL` Eyȸuh(P 2v -gCuN:g}{mEeW0/;ۻ+K,ᤓNꫯꫯ.]<cx''wЦu=D桇?\0OAeuYn}tSwn wߝ}xb{O4^p/ƕwܑYf1~xƍM7DnJ-gr=SzU_S.]rʳ2k)a@Yzޅ??(Neeen ?hvB 6B? /?ロaÆKfEo||wZQ_-ge]+:t.=陴}\{,_~ ={7g 3}t~ g7rt IDATB(@4Rq7sGpi1sLz].y</=/G|E-OnZ~_ ` )+ sa@jfgYt)SN_樣bĉ\~첋UgŔ1oo\"+#rӇP(ķָ)QFQ(@hIzd)0~E"9(/ |?F!JG&>VT2=q>ވCE󅫢oïI͛?v1l0^z% T.yAihw dkCڗՒC=u2w\f͚ԩSQJqr]w1|o΀x=z4W/L=l`Q5f5Y- 5H!)f6v\HQ(Qa  TAkȇBGÈuBGD ċ0)HET舌 2ד:22//G@ zGkN'4?aڴiyWg}J%g4cҨT}gVBf+d~P ̣q''K.W_۷/s>7v?~|ݷo_fϞSO=ln~3t ]@3haThha+*N- W;VɰaRwir\ qFO_x<͋F7plו7 t"7r$=;A2M(}c73ώT78״8>X`w3gCa̘1\r%~ߺ^zqM75wymj=[:mҺTVbU%zV#%ldLe{D Dqץs1vO6\Hؤ&*pI{mWm>v9gAA a4J)LT=1B au7Xl^@waƴiӘ0a;w樣*u<&%vx<]}QԪVTnMn vҖEa/l|G%6bZkk›} uBAA|~]޼qɄY3͞H!ךPDDI\aȞ/&%MaŕS%5w-'m d l Ǐg]weĈtIdzɸ">Dx1.1 Ɛ!f^\.W0>b3Oq6jպM϶yxg[/O-N;DnJ=O{-+,KYYZ;BBD7 1N~k`mTU5구\>G##[/~X^ص"VO"Sm)#u!Pd2Y A&c3 (py. ~sxE=.'D13!G83Hm7y{~{[3]`曌55kpgKOY~MM.z{<Ѓn:w߮น3痿|wp0zt~Gٳn8.{eV?6YUE&)8g,z]='c;o|'|<w[ns9<瞥D7q'LL6 ͒f̜Ҹˮ\BQ\>G\=0*)崆04Sj"ZSEUU55ԇ9Q|'*",G->级#ޛD8+'ׁ W U"uDPd tD8ʹD[!._(ƅsE$)qOo=q]xq}gŸl{<O7bcxf,8Vkć~=5k?gy&g}/zwt3U2nck}._OP sAm54F꡶kZKڵSϑJ+tjѹں^Z;_@xʽȟ"@n@^dt.[l/@@K"-|a]|E,bysoߗj{WBoҧOfϞ;(u.]Zx<ШF m, dٲeq;b!\Xx1owuseOoW^D.H)҄.q@JܧB? Ʌy2a WV9D& LW:uRWWG.gRϑ S"_ֹw ^ e:u9)?Ng]@k 6 6t_(/mv@ Zh"#Nd\I_"PBz7Vx/ӗ!MAmz2YsՇ[bvbŜs9}^{>\:?唁oֿ#7fL_nxc7<k֌߰}4R_;yJy:u*_}guSLwt޽ߞɈGi }.>\;|> ($f"tXZ+EFF!|\.O.gCUQt#νB>+knz+ - 7!M퍉RIT.<DF@F))m]0=|Bm5~0Q&^K+mDba9s&'N[nߍSE~6x/nV ҥڂ}_|?W׿*=gcЩ#a&RJ(cMҞgg}W^yEѵkW=\}Q\yJ-c!/R$R09ہ0޹z*q:>4ry'flnŲR0 (RaH"?ˑ0oɻl9?ЉsD>V wwXPNѶب2f#C@d*b{n 6`r3&^:'߆K!Fp}R'=+lv>g[3{/^z)r w%ijձY?s:wN}.jvء]q_~YM׮\{(/hx<O!;t ??lgF); ߡSNMҞi>}:1cH)9蠃ӟ1SyJc!UӮo 'SֽGynּ!vK7$WWI&2AĎ|\޺"@f…k3U Hƫ(F9+DZL}+8y_N2nFLСCyG9rdl4H|+8CI{̜sRp܌^ߋ{n~[o=5{nYA[iȀxg|s_/Iة#;vb=ϦsA!_$"9ꨣ;v,Ǐ/u<%ӣa*٧^ C#B[N+@DHe$vj+Q*" #0" C#Qh قzν`=.\{q2/%)ʅ7#F h3@ \h|RI?_L5؞yI ~d( 6ul{'jq2n8yvmRwYPq{+nuN:iwy]N+sqRYYΡ˸xidZ>/̚eq}̟?+6G=0`РRw7n/eeequQ392|ΩO;sSn %TxnQB#L|3:*4殃N++4QFQ>$Dvz9 64_vV^KRވ謹Mv:)V&-HW M=@f ג._G=_TlxCi3{+QXI߇rw2tP^~e?]g`: .xEC߿>#v޹C|̾=u׽g:$2޽vۭ3'$}c^ht`]|ܻ|i}xh5ZIT)8'e2K~wXِ(DGO< klA,i()2}Ia:9.tҜQ4hV3(@jH"RH2aZISlDػ@KH2B q>˽oD{ 9iݺ5W^adz^\k}5w=^ەuϯK}y<ܸ[oQx6#7[AuUS7}/.~tBQ8Q/ERފKec@\@OkP{ Rq{W |T)bauiA_-tQ~;/RUp5f͞1c0{lw_y:kw{<riӆ'ҧO.]Z.y[ƶwӸ{HD|%oSP"8\K RrV;_*eNgZYqo6^$}\ {4ʮtro6 %/{PX7XܻˊTTF/*FcE-'c?_*WJ\)KD0:H |aS߀O>!<|0sSN-u0^x?d…L6#GrgOs~q'O x<g+e.>y'ÐO?D|[ԙߞԉNhWW/gsջK9]_ՋCӋ* .۹uHCBpImoŽLGс{"LsKjfIwzY7p@[X\"Jl}ȌDfyld>20.2жqv/"^5y />.cq駳l2^xN9ZhӹK;J]>Dx1.z+W_4I{uBmw?]w>k2i$=X~߲;[Ftm'Nn}džXإ%}ah~n_ZOBn4JSFmOE2=q /EI7w!VƝODt\ n9mg+w8mQ7/u 9W.`piݓ`U0λHu(1 ŷC_ܫ"?i=jz̅4m]!<%ξ rν;׆0 ) F AjN (%:(I1 ]|m TS\/Zw~"m_+޽;| gucƌaԩ>-SR4KymJlu~32 C W^iPϳ|SYf5UUU)Sp--qc!WDu#$\R;F$"?/uƅ~ܦm; T^5)?k]/TO# uD:Aۍ8I޽s IDNKo7)LΉ}59pޅ0. IDAT m݁T"V6^;ޣW| Eb8N|WV$?_Խ'!AKa 楢,ŗRHi 20By"~\XkJ 3OB[F(HW/ۗC]s7뮻o?/ӧ]ldWx*XmZSFmg \{/^F?ψ#={6zh>_hj֮\a|'NHKs o̹덉z B?vߋE~wjm;Viz/" l@E{(5_NSo~uEHm+e 7#ڮB^oXa}%%"0Yq40.~A>F>(WQ_2/v{e?q {'=ߌK/J g8Rwɳ"x<8ÿ,b"O5TUTTgB| mVvz;W_}mF53j(̙È#袋JݥWA*XV|M_zjVz-5ב s䣐|'_š* я ݎdz=ݨO7tiAڊRɣse:'ߵQn8D{<@H#a)Ī.pվ ȏ/ tH[]"N-ʈ| |!Z H%:a@kh,T?5SDg+~wȏM,p=ߜ3kgذa̜9>N:]NߔU-!1B0Z구j Uk\=zr0G UR뾠;O|k7'گK7&)cfHrqEr^AE̶:"_D~O-ʳx1frTd~{NVfɈ Y7ENP%BѠcgĽNIܹeEA~ADqؾY:ǂ)S_&"_ hFG TnQV_5!Twi{W[РwѣG׿էEy(^{<O3]f@0sښl%ZBA-t 献q@i>׏_|\+]LXz_YR 2dYVgWSVVFYYٲ2 A&0 PhoJ0L(~>#C]h~,IajXCG=^]{wsy\wŽ+*J]{xg <6T>-9@AeѧM76kvYصO |{k7 }$yvImmXk@8/)tӹO>?z05"$lAˍHy=#Gdܹ~~L4]4s2gx<Z7'C|rLY'ɬΐѾe{M]SZvygfΜĉYboJݥ" E''.7tσ[ D a+K@"L&  AF"4lF4Co| wSvJC u7\|W.".'TUعTjH'=9=UZ$Pm;FZw缛AB$wHхt7u]"ھߧC6>0,v݇+'CU$1Q P})0~+E,ͤx 6AAƅ 3u^~۱>o{zj.Rw_fxO8T_&qsDDF|3VI"~n)gGȊz+ej%{ 5oϦү_?^x?xV\ɕW^Y.y!xv{p ]\ϳt֍~}هQFq}<-<x1Z9웤Mm+L8 o!CKRŎ=z 'j.g\痕QQQA6mо=;uCTTTPWWY|9rj( ہ.mނ?{o/Y2g$3!e!! !aMb D4(Ap WqxCѫ\P@2\d!H$EĈE5 $33gzg3$gfTj|tu *F*;}sߙ 2}|]{"6 _5S>u':mǾJ0od'`?OE4({i PߘW1*w`w4I,r})ڇiG4УR֍7aP[R 5P F,I#d(gR;%$K-_/g?|Ӣ:ySN`F#[%\gug9~сP|MUF!'|kMY6ofǎڵ۷S{eΝ9ֹΫr7p˵-E%:S^sS^n>̫s_io''ɟ8C Iݍ-P<]㐯ZG p.#qOfTڌ¥8O'4F9[^3M=TRO"BP}ာ(Ȋa:CtT5"#!r.~N}4j{+m۶ԧ>O}S|}Jc*rکSN@e={K/| 98syӟ>u뮻??SN / /K};b8;x^LŌ!ԛgsfgfؼ;۽5uVzE@].ED@~ ~`E8=V@lk:(!TS1;D(8<.. >]!4`?1ߓfӪ.,Էo9,4?Qg~/~|8rʗи+{C>6x$靈ŕ)u֑Q _LП}lìw@FU`!'V tQ e0Ȩ¨ 1{}u}JdR;2@蒒Z²N믟g˖-AWA>`wC'}Mo k@hSI}| [P o^)w#qUanFvܹ.tt-ܧwg/|s=7޽}Ct:yN?}d85soG[4o3BtxPW) s}cvs'aECBba; eJ]$Ihs sV ˒ EO+yrtV2aT) 6C87߆T*=rPJ6|.^Տȏ /ks9gOa;uO87~| qw1w;9xv}駟W\+^ ~'kM殉dM).o0(_Lap`u af`vvΝ{p0.KL]4-EoQ y#[`V շ/v'>*c W/OQ^P4qE߀q {Jr=*n1O|mN Z.F}f(p=WuL}. -,9}%k26Z@!Q(<ЙfF 3Yff瘙gfn%--W(]BY|Xh1TFTd2GAň:@26`"4ZeYΫ?O3?3z꩜{|SxFRH/jN:uz#ѧϫ^*zqWpf, %V ԡOyO Vu ,/?Yv6ofؾ{h8 scwXasd* }m|TByC88(v&::鷝9L.o-17}1 B|%C>h3t=&/|(4=O @>(^ PՆJ>'dEWP99Abu0diyٷ~z3K% j0a ~$ Ab$c૊X_{ATobg}ꊋ4T6U,(~oy6-pͯ>-[p֫?ѧ|@MKi|DRwԩSNR|#9:~ SniJ 5m!ʲdyi}wڳo`_03æy6o͛w睬./ۜF\͍7FX(@eXEĹ*bO1"xm =;H7L$.ZaX>|qo9Iwyc#]'_I,ܸgU(#[e\L 2꓾QmjCalȾ(rO zh3l[b}swGovy Wa8BJ[w*ԡV#M,Y%ym+Y*]olӨTе (9 sزy3 lٲ;sQG {?۞p0iQOzғЇ>UW]ѧ0P:uԩ+_ 83x+^S)὏<)>*|ŦV8Wέ=TMN@ ´G 7? طo{.۶mMv<37;˦yYe8PP~X'v\cp}cn~Bƍho}#޹ Gc:qރi~YjS{{ɣ mihʲi}ӵO)\8'`wL{wK ʹ 3i W5ym(j' Q s2f^2m?ž=oKv⎽d+!CUBUۻa(0%"^< F"7z3Y7m6mƶm62gQGîc`nl?W_ >z{6:검/>שSN:u:dկ~/}K//x3OOG>r>㊓5jXq F*ųc. S5;4I{[` IDAT_&H&rey;3;mn yQufff=,X :Ϊ 9B-{Թ7_aM'{<<4߅ԱxOY׆yq}:6گ-w!^yֽ~q]|s^gTeMVm)p?۝XeKlھ;[n۾wo; !ЕAׂrL8R̈)/{/L5jlڂQdE)M)~ضu;۶n㨣b]pc wk77N:83җ_W: h!;9:uԩaSN9%/.+x3AͳdC \دj;kjk޸5ٻg{nv< 2<~ q^z>[|?[n︃;geel8$sMEf 䪢'#47)F#E5{K5h[$V~GuN1ӟanv ٺe+۶m㨝;ٹk8888h`!CK`̡~yK_Ӟ4.b^Ws'J)w׿mot(+ ѧҩSN:u;zWu;Ө!֡/=\LYQ;8?\W $s\z`bh~XL kbb'qچW???OWwYF/)z=zEA5a⧒\۴o'TRKJR8b|"$FoBA[./y>PIK{@݄{טo;S ֲq~J8~0.7_b] oMxzŷڨذ88- 2,yIVdWR+flf~m7{=w Oɖ-[۾ebXڐ!CyVeSJ ů~kǟAuh(-S)\P !d쳌^sXشmwQGcXc%#7 !Hx#ln_zO: '0uc=-"0T DNToP QM9ɒ~oi} M@ۈUEeM12**P!?>sGBFç\zf2$s=%@-g@#4M>+=f4 lݺwsQpp0=!}eU` EXZ`_Zbii.27|[|&yC+t N:u:Bw^~gbvg擟ݻ_zmy'?IN:餱p^υ 6lGM/N?l>0ÏiB$<*Kؿ Z)zkYkMkƒkZ.TB}4*/あrHfaڻ 14 &I׆| ^TCi¾m9wpƝqoؽַ'n;n#/_`_C OCKtpk#2/mQ p gcAw31'Ć{W;gVͰiF![UBR*eX1(1(j^sorހ62f#͆Cl<ػ<{22Qd9Eѣ_up?fnmٺc۶ۢ(w%S.gii)%UIU|pd;{h赯}زümoO~29StwԩSCD߹6Dño]NWUlݺ'< ~ɮA|pBgX 򱛰2k!NHcڍc&9ƅ-F#ɳ1zm3nmttIB8}AP‚*S܃!0?Sg?B~C O!m7S\~RxؼH'~'n=qg{$!YG0 -o%D T@e||Q2ǐ3؜XW{߅^JT.Q% C֐iPZȱij05Ac{",K+J+g }}jLυBzl¶[ٲu;lbm  Vay9[dqq++e*+G/g˖-<1᳟Jv~N:x,_"ys1Z}wp%/Ꭻ+_x^ޣjbK`!=wbcB0~qZ'|ةoդv-5s,)LԕQ_F1\||RiwyRwGt>I'_2#XȷܠlËm 𮽢vC Y+C~w4k~ Ƿ۩>D7iJIpjHq5aOr#GO\ |f 0R;R6P buvDJDN  ²,>c,..p8*GoF!6D T+PWWhq:}/07M l޼-7`s^zu1PUP`0X^b?gyyhDY&`_WT~\W\[wnz ^~>c>N(uԩS[bT꯯ć+JߡU<]2[}2˞={s^Nn/34F2Bʑ#`{T`AXWrw+ Nպqި5<;/G#ʢ`yi k,.KTݴ7oZyӺ K3F+0w'_熚u{n+[} ٟ2o´GPqN|,P2nI~4UO~z8N8нdo7y>b6|?C?ЍJc^ 0* Q}it^, BUVWWXY^fei?K./12lQɺu'w[Z ރ} /._)R\=eO"93?M4,_V FVWaueX]]e41*Gv<9ꊺꚺM==uO}>\uUa7|`߀|rm1d@j#>QKܙc]W6Me8`8Xe0XaJ9RCrDU|SY^r/$zwmEȶWL箘-2;7ssқ;؞?½Y] ++ CS%6ʒr`o5NWPy?A粰n)uuߩSNG|U. }8's.w-<⁏X-!=9YufT+c[Ew=J{k{;"QPP?s.MCxk+ }3!2@:"um]|9 wCy>?Ik V =*WSdшv*Ylv>5'14CI\|& aͶFi֜w@uo{'M'@0&m}eoaZ?!mp9BYZ]2m{n19"SSW>B}]TՈau]"u>}t*{6J*{~^Lff?ӣ\2.adg hՕV%eUoW Իqޅik]tEVSN:V1). rr}> ~q?ɏݿN꛿qqrzXrֹ׭޲o^Ӛ3cxLՆ{R)vJ/~Y2G&9}~߮U/z` ^MMnhD*p}<'N> ԋƨ͞ ө#O :8qş33Ǩi9ma& nkO[<"[o9-'_Fk B&wm- EY]ԉv^ "KWn ïSTb=4gBW2 v{+ ~z>^AVLv%Cm*tYC UU1  6`zWL/},W)׶f{~x.o8 :'K_ҍ>N|.SN`jd ;c)c?+x%_67- Osm1$[Om\ ASz5k|-JCY\oUoeVm cWZeIe(0ͻ5.6p'o=zu1F5%u >ɏ0_k5OVh>^{B}wǚUK%.I;ɱoC34?vi2nX^\Va:{' ?زx5Dl6EeU^=w"ֽ9s b*Ʈ@oPvާއ'Ts!2(z=z~A/{9:йL!Jl8غ2ueCGphߪ_UιԋzzpEwvi|soFR{]B;uY#픪 2'[(_˜xW5/|翏rJ J&kIКkjcx,g;U;eɯ=:4b/nʆ7#V @݃P2JOO.~_'x~П[O~кvqqx% .Ly0F%C UUse*仦; `{e)շ ޸|;TaֲԵ\HNJL n: Sڹ.4_p=;z "#˵ ˷}%56@]הh`vu]O"{o_=Noi~՚kg ?5['4(Mu@fBy vx׮1Ív!_e^'.~p0[/dZ}HC~k>߈N~t6Lqw74${B$n.oDN?m|Ʋi%{͟WʅN~~8`jK։ o@jh7a[%eA!!+H 7ڻ4{odYF^>{E/`-Yb]t%jv S <P5P߆{?u$| 7p\r ?S?l)u~N:2F0SB( Cl]Ph;y3ld菌= z{wHkhqiI`^mk=d'e1|"j$5@ Up -R*s۹ZBh<>DsL|KEYd=V4{ЈpcENIސG荹u\ ;&з6[Øl?ٵ[>V`/a~F1W~q8qW_8;\AAlCR x!Z7fN{?6w!6Bv{ ; +-;ϋ )Daޔ P׆ETN{ڴ<ػT?r?q.bgַ;nOz˽])N:u:e 3q0Ym+0T}^\& E=~|/eWW1۬/qo:OV}n.J5(UuwHtZ! n;BCPR?GRoDg3'_~fAM=d^{o3,Wk5$K˚뒡rC-ӷY{ݾU<?w~Wuk-o~^?^r$=tNOm[WyW2>Ee U e-a,ܸ 0d\j2a!%)I䈸Tq"!|Up )TQZ2vCgdENV8/cd=+`0ba}XCzĨ1FaXjȨҔRaTQZ|e(A¼^{A=|M" IDAT!Ic^(WU8=B_$kBG~ύ'7}[H-+ud쮴5)T_u{՚Ozmn];e؜یwsukns];{Tӑ w%kUOr./ \ܞne,#l} 14ݣCM]BF$TuMU;E\{/>35|\~~OOOyѧidt!:utK|Ɠiзh]8?d쎩ۧthh+?~'sBamd]U\yʸ]u2s]m0W\|d; 'ο);7Zv.=-r2YV@סkjo|SE®.M w)Tv~#"ͻpo~OFҫ@0,/y'&~O`_5,\~\4zII!ipk0*\bw¼oh};b\Klɕ ɸyC#n}lx~g waI=ϋmnᾪ*WɏUueS5FI> MǢzG~~[o.??SOS괎~!;uԩӑ NwFjMޫs_6iX$@`;qCq=~)p֜|R(l>C|>/%KdHs8iy)ǯF;7v ꟡wbܣR4N~}^_޻eIx+}GB564gtFa>\~ǻ%7f`: -)$#/}cr [ކ)x :tqW֕uX?}sBO9`.߄#Uoy[8묳8묳kGm)uL9:utK ol~.gnN~OϘKA['.L78quoO!_'kSv}&akum핲 $Xz ʃ~R\/=JFAV{ }!dGN{Y}=c%IDVI?gk@>7ɝ7 ֽ. }q"~{wcIY*E& x*RDw, y'_reC]ؼxïS>ں5k?w@}TcH|83m)uZiGSN:2HWSn(K޿WG^$)}a߾}.k 9nƔ W4r=t=u"r^ /WoF4F27|̮K 鼱v]4p=~;_}mFEd{aM Q5 FPd[dL(j _mpN([QbnHBK]R3YɊ,TͷE,ۂ| nR_SSKEejʺ4nG҆E08dH-ƶ Jao} kx_ѧn+v59:ut$+k=/ـxzOZ6i,6ұ&I>Jvm$ Z:Z)|g9b 0/5xd>E3$~B/Yf]|B{i=ەYMHҜk  5}*U/'bUX!T_ ޽7OK2Ŗi1;K*ʁR\_>Pd5ۣDТ~3mEW?nMi}roνVξ N cEr#Hy(Mo:6Qذ[}P9x^\(x󵫜˽׮r~s:޺T&:_Km|eFh- 뵝{'G1CD:<ۿ<_'>ѧw:utiTu rFZkfrN_!oxZ<]d}?k >GBJ#y·0xdýGgY Na~,?HܷACo4H)⻆̃SzIЊbdDݸ-8T/'i~Ƚ BH!qvW/ߚ,0Z5.{7.;kfO]s;uՎ;7pO#;1xÍܹs]iu٧iPߞ>>q xV8/˸9Z)?'@̇P}MH˹)s|/VW8&:";jEFEWP&&o".>CF v鶉r6ħn*I3p/6ajwbwo %>܂-bBEy$}K}޾rs׍'~Ҁ`RO`}ƝLԢÕ*3ݹ74:ko+Q[1>o}f+`WRSIi{Sp? `J*g|բ/Ε7"np|8oABh~؃}8½_frHgy碵^4NK>1:uԩS\w^cgJ #&ocZcitف-q眤5,KOMx iwyÐv 4dHk yTZŽ^`=v SP!q,s}{|zݪ*߷_Y_D!;WA j;-bܱ~[{c?Zf̄6s7{ $fU@dec%%nлUw@[1Zu8Aޝ$&!i~P:}{/9m~l/5˻`_PO`?8B|{<W2XU}o:` N?t焴~}Z:ԩSN:5lei? ?X< ?69Mk9rI}ۑo mood]\3u*"|S|8kw-is ɐΛtS㦍A{W)!55xƇv~}Wp i.]M2O\)n5TƔП˻y*p\"r[ y*ֹO.\wRy o.|Q?b|$['vEj8apHmH`[/R0O 8Pt5\|O'ݛtEڣ%e-[B~gŮ]0`b+.Nn#'+G1'ۅK3|Ǻh'K* پ)lo{T}3~mkC;DLsV*Xh%0 ڦsL8s=ԧg< !1W={m<{{} E+Ar(j@iLD?2,+;-6*7oI_CZ_Wy{5\ _B7snut~N:ui e?5 c/{6H,33wu(C{=>i=ıM ׇf/w@Opm*d2W*l!3BQ)8,><ݯYigI; itp/ V K7Jޒ`qn6z4qJlGu +v ωwS`OH ?jGtp[K &:w b_'/>6p/TCm@i8J,Ͻg}~Tq`^@%Pz_$q}!> EEރ~ `٣1vNicO}o/~1^z)~ypٳgϽx[9SN:nػw/߹u9yة[uwo|N8'@=˃ܧ:V=++<<7 :~읆>Y/ɲ_xtQ՜E \|,lٷmYU!T?& x2c- DνdEa ڒ Tx^v] yZlX-?6XwQ)sR\w؞W3D|;DdpWA~X.~h~v*w "g6V]xֵ/3}~߅dYkBolXQֹ7P% qp/c/=>o&:*f\}ռoeyy.w<< ;N:u:Bu?Js.\7N=u]i}t7s\s5Mo╯|=>k>Skw7\_M6 8%,Gggjumy ۥqu)O[)| &rѮyp/¶&=8߭]!O n^|_ޔ ,pE$'JsoQνҙ׷p?3C13Cߣ(zy;"`e{Z_[`o4wp} >TqKô~ZgH7@7Ї>ĕW^ɉ'rrouwԩS#I{/x_擟= 7oE\z饼]_I?:Ka!$ &zV˼n;P)E9W.-3޴)Np$ތi~pmOA'9x5"@"]~;#6ȊWES h/Um%'~zncRc+&C& qזoН?PwCc cE7JYk݅xZY܇l]aAZBS+'x7Z7Dpw )7ueȽwQY} ^?Ko~fף(r̝-UJĹچ.7QFcĸq|>?8SOC^i47w]2et^yO\qTx>?N.ڹa'I?i{R4K IDATxK^YjOg醶EAF"1hh⽉TL?EMLj8$(N`MC3@UkXCOȥgQk׮Zg}]~CEviK>T?/@}zeǘɼ/Nq- Յ"=@ߏO9ڐ}9- 18}ׁ/(YSiPҸ!ZlPs>tï^Swh9!?˹w eW\}ZzAA^VRM=@;hH4ib]}*[O|U`/|S\Ouzݕ su:|._G>JWo ICn}N[j >p!uEAwt#/|Z}q'X׾C:n!?7 s5h\pa _dxIpU0$_wU_ggC"SsnD?TMA=oߠGzIA^VzJ) :դ:1R3%^:r>{/|>Ax҄stv}FrνaȻ fm_JC >&ć{,}~^l¦M'nwE/z-+*UTCUnawbÆ u.V\ 4Ml6f||WU4 6l]q!s9|;K.zH/6,{zmYhH[cڽ.\g|Gxsp&+Ћdq{"^n[B+/G68hx{~&] w]2ە 'WZkmFM(V֌Su5 ɲRfAwLdTv<\{ڡ{@_K-X'?2[ږjI$)~}u-eDsn")媫0?n&<9s1|s7ɟɟp_IKJ*U:;I^򒗰l2?)%7|36lRl6.crr;gJXy|o~n!?`B^v½!X2хEmNuv׏^9p,zg-08@cla7PE  Qz9]HYb,T[x ruYKz9EV®a 0=>߲} I,Vi5sMg6"W>COX973#X #kn86p_77p1Gi2L*4q´ oαLJ7߶':XzgP׉6`Kȷ<ۻ>eJDs 7{?q_VE/zsy衇g>_ڵk{%W.?2DTRciʌ>u+Ja* jni=\&&&'> I`Ŋj5ܺZI'͛ȹ#sBz݆&OfEкBKFq*Uyϣ,W{.NYq?ǹ@V8.bk!Ď lhYV 0/u4vm+B>4y@VwJ.B`y_\clp[s OZ4B֘}m,`τ}X P|WN؄ ܜ#:k]*[7Hjj͸fFFa:L?MT̰XTg}wRßR?r}TU=!fM}}ݺu|K_ oxoy[?#<–-[?qǹ+iơ+W.T~RJRJqغ~OSnV:<|R򗿜jl?SU^N|(,C.,^Rx_X1м'?A@{˱ugm[^`_ps0h\wn4-[2,MZԈUTFhv MsھoYWh8:/Y!^WS{o:*PK;gER)=K>Raal^{+0Z0`fb*WMF_́AFǗdF(C  ۟ %DNY&kiJn{l3or텇lZw}6 Z{!Y}k/娣⬳~6ozӛwA.U)?pƔ*U(ԧi֚J!⋹իQJg>17*u(C.MxrR $/_'ȉCW|-9 2I5Zl[ C_:SmLRmcB0+:%VZQiC텍A[w+fHINuW2 '.Z (vE<[ʿ|A$!2""b ZzKt2>F&P_r.M}GC;Q:VJRډ\>sOV9_}~q׾X@C^ͷ>gyַBkkl޼uQ'~RJRʄ4Z͛7tPX^}{_~9o}[KI;v`ڵ89/2?柳0d}D HR4?ct"+D jF_#c,YeVX 5Z8O 턅vJm`(BS|w96tQw@.@ԣݶ<^qmE^ tv ] CGG>d/ܓ[{7L'Qdsc**}~FF_e+V# qq!/ E@}ˀ|;aIhuRZO{{A))}C{.@}g[`a<~k3{~F#{4'9 CoJ,*RJ:SN=x#_8c/)|cZr)'㈮KZ\oN{Gh1Ra=uaGsA_v םq*onZ6ƛ֮1v\2\:*P;H~nvӟB1-̰Q d C]"bW[: 8({g @V@>dGj>pm<.Zgҝ\wRd0AsW- OD87^d Wt?:Tj4 0>eW#Xqja3,0;bn\B+aա6NIjUW~,{Dg0>t{AͰGqCfU,;.?EoퟋOaRD%*Ua,~8\|1s\\ve4 e/a\lٲ߸ReROTn!h^P|GoǜIjrα҂}꓎M?fyELa:EMBAؗ0܇!?b0틄R#џ̰< 1U$b{.l+sW->\OwQq&oU_g`]u>b?˟۝|.tva1L}/vʽg ɉ|m"%:Bxw.M5I;0iVc:Bkb]UWBp_k?0K,cy&+U@4@Y1,3s-07fajtsha T.,_rs)}R{=bd=nN_@}|+!HH9] R J*u+pٿ½wz!~~+VPV}uݻwsuױeN9d>Wr(ROF!_Ŧ ˑ &<؂}ӗy2t/S6\1!3ގb$.~2tm}h~mqK҈ѬͲD?.J?BH'$"L0$5rCvo]~Dv^@> Gm,6M^8_Pm1' Lr"tϳy!I >C[ La(6 U4MI;T5 <'HW*j5>  1aet= 0n5)&gcvB;Ɋ%½ͽY,4 Yn_̵/B}Ln#w3 {fYgDZgReӟtY1UYETRciN7p˷ſp5088Ȋ+R}v&''ꕯcgeROR9ȇn b.~%zaDƶE7"'Ç~|?|p;1n"UHIxhmS ܷu{"?~]\R*43<>Fvtd% fΓwS7;p}~ K]n]k s~p۝Ȼx^0O( +~;a_.MWcs[ρy^$VA)(EǦE#kTK59h#Ldf[βyu Cq ?pt`op|H(Kzu!1*DIJ%9^yY%7Vc Y}cWr Ɋ a?̽Md.v_>\p o@YvZG.#Vl24<0>N={g@[OYǷ2 c:F U_fK.vwvg$fcv~6 )ױ~y^Ӭ^V`O#| @??1λav>voz:\+.>^o@aUV.d璕J*Ua#ЪFE/>bKzZSH(o,{ W"d%"%Q$BzS=_(c܃|__/Kgp }}?>dCW~8iӟ{hHzE64߹\˗fl}Ծ}fV\w0h[os̀f2MS3I}h3,L3ǾigcaEݡ$$(YX/;ޅb8~=}w;&+:U/ށXynM>?{܀+EZ_144ڵk]k4Z& SiJG);S7ߌϾi4;w#RXhcfn9f昝gnnZNB'IIo A̽w=.wlbC{-ǒSdYrN62?:%zA~7'?kJzuycKK*U:YDh=9)M?%+i۶m ?ߜޞN>yw^&oۂzW$Q%".qBB D TЗL7[YZ>tpsN\M qBGŠ"VDa&Yru IDATcxq'l.Goyd:@g蓃|{\377;]8sk=AVPo>G?^=~=N!;ލ,:~݁w|]$]YXXυKI$%JzF^V72|&Y&IjnIme}W uv.0}wS7jDQF$v]VmNH"I ϚsMQ+C `{v(HQ/=\>}~mz?^~{RO~ XrpOB׋TRJr:t|c=O1g=)9^O+W<]xJtUC'Xw0:v?aq ˗jZpfh.9+Fp +қO/}&r.~P}C.l^DkTP;4gT:wuZir.K;7=>H#pnuU=03@Bh~W~{=9v?A\kPS;aum 8Vh4hal c;w235EݦRHxC'T+UB#4&IRn=?mV@uIkxƯIG q0/upkb^4&/UTZ'|BROHWݜy)!7ay7az%6KiBRhHD*a+,oOqQ}2Rp/ȅ4ĕ#*3r=QdK!m 審oмTڄ/>a׻\E_{] }D$Y{#_Uv zh9%$='!$jv:fVfźuqڵ9SQ}6W8iCna{NEȂ}Ȍ BwW՟gqۧ627a+vәsϣ >c XDz~!?-!"߹7w羷^ȝ:|׼5z藣MJ*UTV !>{||3ͯD՘Wb@-RID*M(N񪤏Ood@`M$+WtH,l‚H# jaz;INiDwy@sn<{w0!| tK:y?웰\m>t)"xl`+ t_3Dwko(LP{{J N˳+Yj?&'i-,&I $s0l e @Dna߬G8Ncn'>ٻAS{xGnm,9e KXǚ@=_O-E7硞`K䛇CX/~oO}S+~F-_TRJ*u`u;JC9G9oDXՈSUT*6NӅB~k$?Y'gx1 99R4 rp$EVH",Td_4dmV()3w &Fo/Y.tExB!?Z{̥^^]/h}հ`pt1w \!MMKHSt`~h06:(;wdvvӡnf54٭OaZhE [Wn@ki#58 fg>`I&۶̵Yu䗩 Pj<4XnڻSdKmiX!}so梋.8W>]*eB'bRJ:Hu9(UiU7u "_[s! zjJ^5_}辴"hkmP[SsD>6YXE׾bѐ}@JKD~DB6̲,I2#+*;VQ9,fTMsIp0uR;-Z Yi eaY\Kmd99` #zҹhֵ]j}oB^O׷Z`fA)٤^Qcܶ,O m6*&mc S-c$$t"QfZ$D.=Qo\%~F!8׾5/ek jIJDb[6[n?~lMzxtd0vY?CCG9_u~(z;n/UTCBgqƁBROßW1k3Ss n{aZJV#c(e>!%J%2~=R@ X=Y\-ޏx- ]H|&@!;cRjGGxd˺;|1?|6 K[Ά5 w QZZ?8]6Q= Ggcs ?/{gչaep~r8BG5ZkT:_X`nv}|V !%F>qL"%/$su%L2pKkcYvl|?xFN<ˆjEμXyP{O$? 6HCTCkCKTRjMMN.*Oogatœ|M,?%Z֨Q{TL"d|VwufpVG\yr4Ϗ'$Pb_\_+giZZFP]#,G 0UVЗ.wdq?,> ;XY)\HZss-Km >+ܨ BGi"zEşۻd :7)"(ns昞b$㓓+G% qQVUT*Qd<~ªlѷiheX}Me~ SM#Ln`ɳVլ9xXu/Q[:!+h]\}Z;Hwp"`+rϵ 8urwpswf͚ݥRQOw_TR|ߓr=LLLΝOI?.[(ǟpSrRO| _y A3}|?AQ<z7IB/.p_Vȹ{%"Edz!3אjW/n'??_`= \e/CJgCnl 4 {>!B{`~ȧ?i?x or'pWz2h*U!'?11K.y)Jg>ǗczrEʋ| z`~\g&>k1zjFQWѬSQJ! k޽^I~*vO"' ҝoZpP,pXJsPgxz?}|GkB.~l.,_|{iN?\csɅж.s%Z||2;ή].Cw,=>1d@Ν7܋֞cBv:şejj{i6D,,n")8HDY_>FCfO'={ h4 IIh'-3^[<ZGڇakc?W'lIgp)1E _Z~^wl_m‡g"/aJ1p$a!_.~^gZvӿҺn*; Z+WZ"BZ(󀯱Sex/׾8%^Hݽ _Lիa޹nq= 3Rx_],33=$f4E)eH!/%RJ{ޟWnllCmXo{y8ᜣ ҡB )z[7m{@:=Ch®˷p8*7ʄƨr/`!BK3 /?c>tE.zU:J*uVw!m}{|_gff)%f;3[nqSuRO~<q=JJ33LGIEH)IĺxȗR ALý+r @BB* JzSC+UT_@=*Zk~M6Q׹ Yt)F)%Vm۶qM7q 7yf~կC} 6o]wE<,??sKua\Ƃ(ĕSUm:fA!́@%T+z]VA/b{3mh,~I1zg,$8` wP|M/Bh"SkL JY7زA`{k %Ә!fxoػ{[d5B99>Rw[4>X: }v߅ ?Znh ]/;03=mj$|ԇi.=/ "6cG~A:=q}[>L_D^<|;7bޭ /b=O.E V/Z GvQHD+ {~ftK*UГƍYn>K,f !PJtR֭[E6nȑGYgqp\֦M[я~_^ݭg_/y_5u Qa4ĕXBETU":AWyyȴ Ѷ_=>ft0o$ܘc@~/"̜dPo/ 0Kr`cF("ةYG`e;s{ \,_I?|{rDdoRJ;e0)θ1@hp&]x^n- k-'c;S4d)n5aΏ |uȞ wVyfgi4%iis'Z-~) R!Au0Bs$:&o]7Â^ :z л>s{F.ϹҜ=Xylzו(i@߲+L޶mi!?GJ*U]O>D_)={a:\p˗/hpM7>4 jzիЇ>Ć 83=D "k#N+뮻>[OߧGmaJRGoJ",p_kBw!'7G @yCL P6iHvOm.+Ɩk&Ra]ci EUVتtJ?]q 醹:'읥_u{W4o1ݿHdp@/N}{ކ2W֤iJl{rhnu '1gF [Q>D tV|e;T UH<~{{=`#(>]K7X`di\{k0v隷h ,>lsP]igtK*UГ eSN&''yk_˲e޸.7p*}w< aAHIѦ͒Fڪm0)!(i\MҦ ٴ!=yȗڮ6m%4ĭ6ɚaamwA\C]u0M7U|]B@c^Spwd!:":&':C}>ﮊbD".}xD|_#{ۖ_s;}pWDHKhRЩ_m^yT~RJz!ZiK}pV* T**RJ&''ٹs'{xh4XZƃ[YN>dos7>/?I*NGr؆揍Bup>"+ReCԹ#G:n֭W4CpQr<|{_5Us3r ЄKthԂ||<OBZJ=wU\`DeEaCUk]]muϜcIP W}5Occ9YP΍w{/6 IDAT`4{m#њ ׮'K291$333!DVVVOn2dѱTtT3dHW"pVwSϪDn*[ w9/=t?mY^;| t/ߌw^ӀNL3IjA[<:02_V+UTZO6D_):~`VRm;wd׮]LLL/}7r)TUx`gJr~k_կ~5\{WN|'PUk5jЀ)WƁ:ƖN cT{ )A؝rlq'#eIʞ.Ϸ xeМA~sݔ_hWq2PqN~Z5Zkm"Sir`0o{!٧Bbrl6wAVuGyMD`Teg훿}X)߻zŜ^'Ç&VhW75_(^R1澇Ϳ,u6Z)~45ӌW\jמ~:'\I$I%&u=K~]iw=SƵGa { Z,5J5&&j6\s[&R*U!ɉ'N5J`1Svm~<Κ[[Ja?8/uPE>8g)HE'erUG%[n֖ʤT!SJ6mU6D_EJLZV3FjծWc[gDpaP_rtn]`&Ҡ)ms :GخB-2ذDq)a0!mLs15Pt:|vvMNa>Xv-?.Z5vAEf&b6H `@C`Y "Eꂋo_J&H$f\( :5ySN} Mzl+~.N+G-Na{*4ZScjlpXA2TTRz18<3N)۪Uػw/NLWTcddK.O~~ȕRرUVUիٰa\z;T/[fJ  @C. yh--I$ꔮ0}zO2X \}"w[Hoɸ /&ŷP٠@Є|aQ|-\fi.D?PL_M֡|Fځs- R@Jm7CRBT jU*k}1 edLE~ 6d k`on>ȶ Uk|%]dQ ҚӔo?J~RMR1Z)tt:$|7maBO}i_P$Eh7:bHs=kR"^/Š>W? C5w^c@JMQ0]%NrM_TRt}wWq7ndǎXQ144o{8gR޽I֬^SR>O|@w+  O$iXh-N:&4b|a]|lls:X/.]Qe/W~EV>Aoχ6۩d&}6_D EM>~{J|-]?|rfpD@|h!jL&lwt:Ҥ,h3HŵE-RZVWǮVˤpSjN{ Q' Gǯ{/b!Ǯy { {p$l%`;0Hr^3E GQű($|׊.O4,uA,!E6\d`2aiȊiSx,U ,پC][4?ӧ^"`=Ejq?}JNAS$\WY/ݘRJ:9z _F/p1PבRrE׾A4McjO9Ǎ:x׼@wPE]I_. `jf9Z:I4MP6\4?{Ww'80#nEqWS~%1!%jQTnnρ󃇐<7X`f k󼋯3'W`g(J u𕭪sJ8lJ)⸃{ƥYW?Ku8:(CPYBFR,,[XH/{^/w)ٛO͝Mj^^UYaG ?ιMGw >uFyƅ^zzF;{4YKγ '"GJ*.l#:L`C_lojE?w/A|4"F S%~~/UTX~iY2>%_Ν;ٷoolt:r׳e.bU!㯀av;p?t޳ gnI|,TmG>`ʈ~M8|>ab:p4$%Nɭ<`Ą92.Oȧ&+ӡ,I\~f0M{Z2E?`\|R FFF__fFZg9˽77f@A 7YbDq/3qߑA_2.3n (60"a dk:YTuM >:}<ϩP*EJR\|¾H 90iƇJ)MH(C֥oEn摦Wo+nl(v#=CʂT$3#H!,'v7.C׵=ܓ 4*OUrx`H@Nɛi;' OTu!- Pޮkl 5u)&eS}| j(wlw x}0qOo6J;e$_d!wK \AB۸U*Tv,W:GN?n+ŋ̙3Rb ֯_OWW'=`ApcG-Tٟ|fSשըF18qb}=[I?䇐:Iv ?B΁/#1]Ǽ {! '7[]9DQEI%Ti0~D}bz}k7k֌CMxsc]UC?i3m}W_HYEԊeF_FEPqLuM~B7lZOMĉ]TP.c5e*~8]"(`/|P4Z?KR U`%UHm 8Bf0<ܷ w;X=,\( s+j_X߯Ӑm=yct9[ aeN^SeZŐ]| H |aDk?|{wCǾ]Z; r$R'_d]|wxw(_~Y^}}"L{af=Gm_*Tv)Ӧ' ɡI)Ӧn4[ ]^{-G}~Yl^z)]t;goZ^·35pmp>?ip{^}/|tks-i! ܵu:1[79\ A_b}}JQVMRD2)0p, 9׀roߠl Ň  K &'z?I?8$(r0ֲ!$~`-SXkp7)*Z*TA}2pzDb-ܽ^7N9dh8ʵ8Efg&Dߍ1m^;paC%,qg k\1z5+g`; zH-L&؛[r]vpUF3HԆSst:JC ͏)&Kv*TPBlM2ٛHnzӦM,+T(C=)?QGUW]QG駟I'ͥkڢ |a I `BNXP/s[@Cv:ҵ `몼Ó8zmO ZzOp8U ɏU"$RF@YK$1No Hl6u1 h*5PEC{{J^vl}֮^R 3!J&Ako W3!, iC5+Vß#p.pp>Ԯ lÚoK*aeǒ|B"ȅ_PB۩w>֬^Y9uTNƼ,+T+/{O36syߎU!N]x o߇{^mQ=囹0-Bc[dtMXx -'/} /Mc09eՠQ$`o l='эwdIbDZٔcj5jcc5PZ>RBa? I&h {iӵ\X=H} B+_<接(xL8$-&[5?z7Kss>ýVk¼w݈v 촍D6 E)¸u3  Ђ&(8݀ kF:0fC sHZtd\K_ 9x`a o#+a̫]i87\WÅ8M$ -&zbY蕫lxPB 2OB^i۹ X~= .cv,i ?]6 ,l>_D/)t1s[²DD0c4~.]ixzUyPۧ[A_gS'p!g EI$k~&\_h dacFZmaFF%{)߄a`attZF>fzNkNAR1Su4wyCCkbadx^:75޸\x@ssL6S[BjE8]!AD Xlf[W@CЫٍ'XFE7R)%!suB ?y@hv}D/.wSܛIYz.+p]|BwR*TPB)=d~Gzjȉlt9eKbSW.ݹZd2;S oy}?sǛut<#QM^N> )-I%2?~޿8'r J2}.)" 088  'Bql81.34]]T*jZVk=` 3uTS"AĆkڄg[ hv `Zv DŸg` ߐz(boBH n`*| l?@"?cDz=jG!(4`4HLCk 3I kE|tLGPƸ]|50w@&>yЉ[T/׌BJHG֮眯;cٛL~kB *TPM?8wYr%gf|#{҆/^)ԁuʻE "l 8R<#wauC!4B$"`69- Ռ BB)Ilp( ~}^&MĴiә1wwC1@WWjJշ3m̎B5֬ΚGx!ּ3o2~)Ǻ=6/ŽfWvx-l6 |P{)`7q]SS=DD؅F(ɹ}X~>)KKvk>v!>יcixft?lO/AVATYڢ CobN;mcrU PB *UCqsEqmqI'1{lw_~l6}s$]:Ds,䭥 IDATH y7t;-Z2aJ?+YjW?Ǿoߵ;3mp6\_gA!"I)BWknT ``8DBz*==M>2qEz;t8V=3\ȤI'T/J%(¾F)ePBH$ <3Qf'`DfiRIհ}!wnp[vpbzw%tV7t \|{7wLII :t1&c>b.i{@oc.yֽ|S:HFO G|/K7)Ҧ^RR Ŝo0PB *Thu]wq7rzj8 կ3k,>OpBmгoH8 P =5z?G}\;*iH-4d_ӌ*BE]!5)2V M-gKױ/)JT*eϥT1LdZ,:4 $&IJ%y_jw"J[7EU1Xڵ<˼NHpn3>rxHYuD[Ϗ\D$4e&M\,4tFJ)(Y5#`> {G|I/~;ɇJ_H#Pל ?*@M$D$@Ew7.c}i^2U*TPBP=s[ 3<_~o|wܑ|3\vetAmsyq9ps饗̭o46(ps0#Hen |x?}\iB}cGv.>.anILH RkTIg GjxF½N̛8KnJ;fX3?6k1C0ccc4 &#֭==bGs<{ 9LfA3i=in 4q]aM"{wdvol-@5 ^KRnt: O{<,~7 A? nP $cݪ ~bʔzT%*upйw'o?|Nνo$U=?]X: ȷch{eD("K%*&%O);w.]v&UZE?+TPBx-}p)֭c /laL^,+iV"x .]OS.7rgprQGm1>l&O-(9VCte99)$4_A;)20?>޿ᮟ}Nڛ) 󐟶ێ^Xsw@*z.\ O>KfIVcpp+g2c &NEJcլ\5k288H h6#KiXU3ǼKThRM A#Vj Rwn- }ćQ~Myw],}hb)Vgy#x^Ȕ]gl+Lb#JDDHZy3a i~Ϲ-a> rHνf!Fz/mwHPeI\-gW_zn7n ̲%_PB۩>zn.ey6q ur=nw]||_~?[:w+6Y7 8Oaik ]˾D@ݢ~;lrAGt 8Zk:I2P;댌 vyf===DQD7144CCfz1^PW$y; L/QAB}{ QRl3(ƹG#e^]!['~pee;._|sHv@Gϑ{{!ߜˤ8HJ+]1ub2(Q423xKB~4T?pdi"83~vŁ}P}g31{8qK|8>~!6U~+yӛM7Ă 6^~PB n:NU[ZmKs7|3\pO=rg}6se]v,8S87˱6EgN@$?pHkOBs׏PV13f}mc9ok>/l:B ([NB`rN(PoubzP'O,+IQgddkQVT*J'l'4 W2:CC0:zO,B~֬wt*44|tA^y֍U1iz7śMWmpCAixp}Ͻ?3u4}O8R Ϟ\O{_ykj zsRө)1QH⇃F{p}:M7TyG与}0Vp@љ|/S008mFe S4cofwl- ~B mZ h׭[ҥb ˽N;1sLۋɓ'w>'+Oo['?I~op5XZ||;M nmpJ]48nn4I eB)h}( f/7b3&"$L.wDB=3WgOܠm2;H;[;c? L{¿o:YvC6v99! |I7A$F TөUv j&ְUz|N::t qνȂ~._O9ʽ#Bk=fe\bk +'-!cMI2VXhщdZ ~49OF`61QP2J"AR8o%DW$+@€:Q[^Xohƕ0.wjh;mX)  ;:``ICUG0)`JS)5bCnAMnN_Bkc;^N͌û~Ol{ԌH%e@q5E驧bٲe?!{gy&o8#6^>_PB۱[{}Yp!ӧOZEBR̘1wߝ+{]wݕ>S?r ^x!˖-0u]v9-J8 , j;G 8fazE|=g^{<׳;oA_sZSwlkBf-lZRDסג<0[ڍNDٜXHL62Elܷ^+F!B/Z [ ps[*g#,ظi ι" 'rnwz̘D0@hO+0}e#D$4e&t0N:x7i8f\0u,kHr>Mx x?g>V3}Fo: rww|B[OVnEB "Zm5kpW1Î;Hww7r[o-hZr'o}}-S">]`W?q5pç?i.̀NZ|b;k$"em{mַN sP`Oo8\?:ks>'z`܋ܔy䖋%!RH "uRHk$4VƖE};Swuw4*JG(>R)8B˺c3h4V5,kvSY9;-*n\­"ö&봴 wKhL1Bi*4GXdM2DFD$hu\vkw cadD ˟?}sKkVhp p ̙3gUh9_PB۱V( f|?rW3|LwvG};:۟˯뮻E~<#\z?`=9cP+o-bB>O(,)10Sđp Vv̓nf-|S5:Ҏ.GxdD)*4rDTf# =x}^ϤA,<?f'1J'$Z,#7a 򏅐Hl7;[{.&0iŸ knP@s!qD:>xArF(3Xźx2Ӊ؇2.~:02!Z9~-Ƕ_0*uy6DB{ҽ&h<u~LzYr dQ *J۰W|r̤I(T*.J֬Y`ϱKww73gΤZԓOmFSLkn&n*.\iYg^ۿZi@$$%2Y^}Bw٩ A#|tݕ8U?w9l-,2{B!2"rL\EwW]4⑫~O1M8{`hp!؅; *G,2tЗ6ArǔΜ5npAd[" j#;~rg@ 䛪Oo,YXoƽ BSM+Th0ǒMs5|xob{NG3\ߠ\>&D?S'O|oڠu ϶U7 1yxOƻB^2\*Tv,ʆ?L8)%J)?< p7e˖ R0uTxIB۾;<.n6|+_vl!-\Ng _Htd@PAx.~Ru7wLfκWDqGf|.;Ԉh RH"QQT(*tw]?WT >?{3R@yaJ*+vAM"q` }+21pԵ-Ƥ c:]No:5/rodkwI^ovavS@hdaFcLg>VW!,{p-OOV;A^J]{8ƄvV:hNA~xA40b_hQ *Kk!I\.#ddd~￟~}cXGy0΄&ּWcnSh}_K.`w欳3 ;VnݫC/S,91/#S̈́ Aߘ%,; | d_}BGBd-$B[Cլ4Vwē9gc=06 +z 1FGG#&;wGLԻ-)yoe#LjmI0‚B{Mny>t  :[dݟ25Sa;x'^&L_ B[?%B*PPL`1fsϺv` =kg@^W_\tpA(3h! 2~3):Ӧ#!&~/B:B ڎlj0裏l6QJh":<'OchhTVvWP-7>ù?ܢWRdDNKdyeLf͚.=30jR.W L'D&=x ;o-I춃{E@oos;9y`osC>܆?3oRݶ=ofT7T_K !5QZ%ƘW3:Y h$x^@Iøˆ~@z<ԻkMz>$ËF K#8j }e* 'Ŝƅ *]JˬYs=<̜9'x"###| I^3{]R|˨N8aK.OM*,NIW%TQ5Fj;qw%:Uor7&\l}t^+> r"|@~[{Q؈b0skq i5R*; I$r && I% =^P;jW7- Vfmh{_݆F0 >V<^nXٳg-"ep *Th;r?`˙;w.]]]H)9SV='|2IPw* ?());w.'t###z[IſW,ygQ2tss)vyς}'#> ~c_kT=7zg [ q=0wDלKUv7zzO$%5Y~" IDATG1?<8DGZÛ-n9βL!{^R>,V^O揓 3,-G=ᓟnR!`Պ%$zbdE{VvZZs|߃A<3?NIߒԛ yh)ɣfR]C$&G _)Ut^&tCPTƽ_ zfI$IJTp¦~N%]0ϺwN}+C~o}oƇS6H۱b⻷:G^j{_lOz.^i3]mp quNE$h),ԛ!5ZJ{j?!!((&= s./_4Le=jEpm2 .Ds|e ߇\dh `rf#z#5 ڐ /TPXa}nc|g̙T*_]|;gcC3(mSwy' .SE6ſU,9N2OQ5At%T:yh.~>>S粧 ]~%?C]w-ի!AHĜPsbA^"H ETѯ wWTSa׃z`h:FLLL|phn×~ogg\ k"iY8oh-s3e\Npž Pkj%me]j1%+}hMK.~Ża~ˏ _@/lW m+B'߁|.?j/G >'*1*PBci#M7̕W]ŋc̙H)Ybׯ[I6QmF]wx;[V>ݤB+K)ݿDŽyǜ󷑐S?`tHkPy7#cOJbl}]$"B ?,K2ɷ0p?l QFGQ7hM1P)\ÐjKV7EM.#0Ƿ9:{|av Yw msE [v!f0ApE"B,p7Y{UIzOi{--HV- A _Me 5Uǹij w}=d0~. F\s>޷%Xg\|'0&4U_ ^B~nYPBۥ:-X0=ܓ˗.C8蠃>})7B [WhUvCn#M*,b_K""m!?b!?g|lso *~. #n~)2i x 0֯!FG#n4JJ jq _>u Z }䷅wS]!~J(7Ž]VcxY'KBmlw1_`+0}moL468w.d%Z F`$8 gSa5C4,} 7xM)3("m1B;уn|d黑{@bf 6GW/TPYʺm4m9zaǷvzfdq衇rWpqm&_Xr8QGȷKBؠ# %dχ1g;Z/M 7X3 dtdfJ½Ntl wE`!|viovNy? J3\Cs~x Ox_H?\S.Ko E&J@jև uI]0 K%T:@eS _'"ͳm)D]}˿ڿ.{1w=H-c^.$ƒxE U[PB m2m*qM8I:w[w>TX|bɻ$+j "zڸyw> 8\q,৤ ՗9>XЬX5e1`] 02%*ԙdue:JwvLپp"_౿)\_ٛyL \?ui!=wҸܴ} rNDž!1B)'{Lh֛kUϜ:$2:R>:FVh7bT\4ϰt ;w C>hSu<zlG"1B}ߙA iMGC| t뜯?ty$!|"ߤ\i()B?W6n|0ሉy͕6|! ;k޻Ú3Sf,zEÚK^boo^͜9sk7ЋP_PB 4g~ӟcqim_LjgE{h)tMnA \?i(χc@'hDӰ >x>1G+!]qp!֌Ԩ 26Zc6FcA\o4cT ѐhj0f|Ⱦx~sn,l̶ idƆ φs.?m*ܓ i ϾVw w!|s m1ܚ-xu"\ѿŏij5 M/93)h9>L]GaqEc]-qѬ0,&GzB/MŝSPB J4k,~_Q.y;vzB[O_Foɐ|By Slρv6O}v#z5~ \V4ccM:c (Qjc&<֠QolĹ{:SM<s`)p`A]MMuK50$P/W*SQaB *T.ٳgOl1z';7Y{C0),xji Pm3}ף5Ȱwέ"h{.k7 FXXLPq0=^b> (h+m腇KIw 終}zy.~YoT=dTc=oM׾4h>`hH8_S01"\{<_~~Xdڋ"I$"¿? wi>~ d6i4+n@KX%zM(r$_PB uc9e˖mo$̀z]"q><lUT[|;8rt_\{7߽8pp+*q#9ְ.~ucuz׋w}h8)-P K<߾b~*-| a~@U*k[@n8[}sLE}Dhk .huma?l5o\{IQ*Ewc ׷mT5ɘFͱ2 nrwqǭ݄B/BAB *Tգ /}s-oy+cxNB?m?M^z3`<& _>+_h1֤Q3SX/O+tۖp@G~@]4ރsCwQV:S` \ _ڭ*>d?p3ʖW .L? 5X @+,x%yOMHRɹBć;>Q 4?נѬ"4pٶ^9rwz*TPBb} oxwunΫ^kS3L7?܂0}[tì{6 =|^1} [w?R \O/Ydx^8a=A}O}߾lE滗.u0}ex/~vN!N(C$ .^6);wKJRJ#Z5޿OH"*&QtOz5+_PB :餓Ky/~ݜWu*W&'a~\OV'Syv ԚQkk`+\|ubin54ƚ½susϐ7B* L?ؒB}['?[t @8N}ܻ :|CN׮<:FU$(kHld )w_ CZ5_KfIM |mᾂU0½/)2L_8 *TP!-ZOSN:$ݜW5 TQSMu4kׂn|Q=,,quyٿ#wjs@_{_mI#&n&ͺ>n$͘y3t:i}4xÜg`\754_e ?[/NȸfȄ7-w/ nI 1}PfIN ߍ_h/uMA0~$ty|~ṺD(F%=_~*콲T~B *T}Oc+ m1}+kL1?ąc]vU|{1g\pj" RZ  }~S7F>I3ximR lׄe-d2`Aͻۅﻜlc}xKݚ[\}O_{VJ*F%Jv0_ UA!xO_Zd!ۄg*"%@ uw;b)Bdo *TPB^ozӛ;9Sя~ʮ 'E0>zwps0w>o9A{m>^%LC [of*p[su '3 y3.~Psoi!-;rʳoç[@:IwDi_ SQ\|Hth"]~ϹqK%*2R:k5*e=|nַ}ok7g*3 ZE@?D@E,ZVEĊKiQT@Vj,UQ"XpaSY ;Zgs~YL& ɐu^3"ļuב㤀/"""QZjŲex衇x]Noؓr2jPP# Nusهo;P/ ⣺~A ءpY.wm^@{{í@N1>'~0i $2p/t pOC#K#K?ha{~RSSHNN3dzï 5psA`L~9}Wo<䓌3&ѥq a@ӦM?>?۷o}/ zKtST{۵PuNWlps P)k7z;ŷP>cL#<O`URbϳ[5jի2dH,xVV:2I'qПN^Z*vﻧq_wt;NcS6zbrx;.>BsB ׋(=&괁&c}nwB<\E;GKt#{?Hpa  \>dqL ).~(]%@~TjH'##jb^{8 >{_w`ʕr-e, 0eK?p'*9 """Rgӯ_=g֭ر+ZbR &n}aK#`E$?nP{)cчo7=e!| Z#{x]BA:!6ezNޏcE?@: p7n'{cobX9|Fp߀m,d@ŷ<{+Gw~`P>--5ҩY35IMMc zNeӱײeK>s~a7֭ˬYؾ}{Kc/"""UN~m222իw.owy={ҠA>TZy1}9O?i; _={R$;qzH!L ѳKmOw;E{M"! f06.׏]*p-n IDAT/E<~hϩ񪀵 |Bg|8'`;p:`|ً5l/^?r1gY[38|DZm;A0ُ}jڴ) ,W^n+wKۙ;w.wy')))dee{Js' 9⋴o>lsڵ7s=͛3w\>nʀ\m3sr~tNa:ѨzqS΅ s}?` qv1<!?Wx볝C{1{ҋ/D?{% {dž/7'bH]|u|$z!{ސp2$''^53Y3T,}L PH Pmp@8?s9h &4" 2c fΜY$tMe:u*o_>O<;wfڵlذONhB:"""Rb#GΣ] &τ ޽;+#`w(IOO:w=ZtKa]kLB~^ P|ʂH& yC¾u8۱?pׯի9t7tS|͜9ӧ3h ;w.iҤIGx~1}ұcDTLVT_j䦦}/f}|c%c~P6}q_䏥yw~="4y[~ib{ǾoUw^Tv!O${χB~+o $''sIiԮk!//‚pϙĽ~.8--f͚իL{シ\ve4hРGʏ:"""r&O?OڴiÊ+]N#:CW#'9iN^8ӌ?Lω ?jEC>mO>j~p~=%gOs_%vLxD{_._t~*_? @qW Ї!.~t3߶5jSy&|rII~yy9czvCpށ};t|mQW_}}J .|9:}ߧ]v|駉.JY2b6pNI OAR}'Ng;>|w'P~p7=1+`FNry<1uwN@~Fb'@yp{{Ԋdz?zI~lt򝢵yu/1a?4^;=b.w#?FO1X`HҀNmۋQ|TFZZ*)ddI'AZ|VpI?v%so+Ά x7ܹ3 6d߾}\xᅌ1k7|rBDDDK.]6mwy'׿]Nو'C~*y)cG.}8vGZS">n(0ńd~ Sۅ;|/B~qA?͏,?ڥ!{"{d[T2#(Hlq~*c('2Xq=~III&9~?8ضͮsan{w^!yyhԨ[fʕ6e0g3<2ҳqy~'4I #spCn mFxw v)>XƉ^]Zj,z*hnC] D-?bGȦRyʬG epC~F~Ќm\:ڻ{^˂Bχ={fiw9! 9k[m?uĺ7mDnn.'Om۶qӷo_fΜIvXp!]t)oT" """R*Zh%KKٷo]R͈h6wn vs׎%uH`˘&7bl =h6]2:,eh{wXߑ·É7I }pEck;qG|`JtM:~F17[@qRݐ~ B )((/ͅ.}nqy@p2I4&By0{ sz=|w\sp7]6ع{)[Dެ%,w6eB{= +x$9Oԏ~^ddww|]?3] c8ƀ$)ҁ  J1*MAA>999:tlʂs0~]<s܀_X)q?Z;wfr-7LC*PW_DDDJUff&SNoߞe˖%*a9gN~omQcA0jcnN;_;l|Z;翐#= [z&ɵ:Q3Itym.~.7`lwJ~ԩ /h\◤u}&Ӆw{/Ewx+MWCj7?6 emBsp9Qฝw/ `+?W۶mۢҴ-JEDDիWs1cPNDU)NR"`|~_Tbv{aX1˞r7o_; c2ZT5ɿ?6Y>w={-b: ل;hW@0&?6܇{C>߉ eIļmnD/E>8vzP Jqo0n8;N o >aoݽ@!nu_;`8ԢE .]ʥ^޽{2dHEDD,Z!Cp73qDׯ*ݣSAY>^ ;ϐ*ᵇ-0I02cL2p7OGxIL`7.~pw~o_Vps_/x'>?זbo 8{ypC}`v!3gϞ=ܥ,v_/89.؁{ŽNW0D~^调bX{آ#pp FAAAN/ /›8γ !c|\ڵ^{ݥZR)jߋH뮻{h֬_~e˩dp Ԉ oy+ؽ%e@mH@/.|$:>1XE^?Arb]1yg=z4W\qSNն*&DDDDN Сϧ[n.3Լ8Ir'b}!~ S@Id/%J"8Ц$;igst 'O!>S l$;z߅w0ozO v.ZoB&CP" G7nIF~<`,nȇ{Br##Rr+`ѢEt!%IY 2R_DDDuL6>}pg2pDTi̫s؀'lHJ'd!o >_?己RlP&,2P1>|/zJu҉ENG ; :U[B̩oiS bqo0E ah3d7oNǎ7o]tQK2uh̑>)}zbڵ<<Ӊ. }$rSJna*9vMu\գn϶cU#חF?S)HM}Ee᳂].?3=R8(TyžЉ!xf6=S۬`n;"e%-/42oIƍ2m4zDSi8j槑[@9v9C!FFF'祤PD;ݢufGZv>ˇϸg?T?6P6")@ԋc}'CMxATw9A?b"p힯,BۢyD#eD_DDDN 4w᫯bРA.*|q$9~a 9TrT4 8`uv!ߗF?TS(HM®#Pݢ"gCo}{;8+&&;C:G@|ϥ7};ܩ"a+|xy+uW֭Yb<O=T{2JJ0֭Ϟ={[.;w ߷i&ڶm*#O%/s4욧˨A6ǡo<Tr|~2I&Qn3m}`~e<KC]{HbCz/ Q!|H>[}XK=4__ٰa'N,Ѷ38o9\xp lݺ@ ͛[Xe!7/r S vd{us}RPn~u-O8#ގCu)0GT'?Nȷ+/[$Zƍ3gӦMcС.GJ}&Oe]e]ƦM؝;w駟W_SȕL^A*y)o'c;9Nh_H#4rb~Th)CK} {Z8{=K W\HC?'쳷—.u']ǕߵHছn^zO b -H!0R'wOVL'?苆G7|#>  Pd,>>xKCA?:xBT{.'u2c ̚5+%q f)ɉBEDDDw1c7䢋."33W^y}i&-[;_9hK&pJZH!N%4r"]ac5Xij~ |Oѥ%ޡ{4(ۛ ѧ ϕ߬Hɽ+~Ô)S/T nn#;;S2l0oԩSꪫhذaKng?ع B~Nzh e|&:½{B>D8K>c1N5> ]^D?z8[{'wB݂'vlX&PRBKKco'r4iӦM7|>uF `ɉ.OJDCDDDk֬'O'Lt9.cs}n7?OA$ ξ>rTg~qV$SG̐b'{إE&QIX͜9ݻׯ~!W]uo6|'̟??eQCN[n,_/ӚN^Z#9H'?Ž }7n'28mYؖ26e/C|Q]CG˰,m{ vCxn m ~h:p½V\ɼy;v,?͛7箻{\~.OC脂# IDATסZ1$"""YgśoIVVzk˩KVXaf"cs,|> Bd͏ɏ'N>/3oB{ #kS^ntcg%qv… Lzz:^{-e1uT/x+8. - 3#%%+;v$ UVm6N`/CN.QwC~g~0)00_4g{׿k{ a{C{1Gq=DYVVǏuԫWCr|rl}G֭]|4^z%ԩCfزeK˩4mNCc,<@<]{'ܘθguNM>vܩ%xa:Qսax tBÆ yի6mbɒ%r-4k,eJ9'K/Qzuz|@ƍ]R`U;':S$(48I_~9B/:ڵE1tP,ˢW^[o?E]p_ŹOAEDDD*pI'ѦM-ZD6m] VZ|G/<3@x {Y#!p' )x$'>7u}` s;O}]|ǝ_q;&79_}FyL\xU^J֭[ٰao6&MUVq̚5., ŤTZ]wSN]vL4)pׯϛoɶm۸[·qqsN,X;pp:O |9&%CI!\RFA&6./rvP|7xC^߇~ /@iРǏ+dƍ| 8P^e;DDDD2xWׯ}Q9ԩS)S_Ώ?uVV3g믧nݺ<ٳgW0#z¾7{þ'C8B~ CGAAOyv I>DMݑOG$^t}p@-_$+++m%fƎ9C޽5k<۶mߧo߾4jԨJJ fzuEDD߿?9{fڴi.4~xZj駟xܹ3 67od,^-Z8$ĄC " |#09g?5$?~oGs_ܲ|k,p_ӣG6nmҤIK.eĈԪUݻ?+PXXG}%\Bzʪ|<{_DDD*۳rJt] g,XŋӱcGFEÆ K45S{'?=}8>wO fp|@!n;^|>c `sC9c{qB`/iu({S?\ 8sm۶pBƏ_|A&M;7o^ԇf"$O*e˖|ٓ}qw'?O?~LPC||‡1 r!e C3, 8-ָz8x6ԋyXԲY kIOOm۶Wo>㥗^bݺu|s=;:+J%e_DDD 2qDvDS)9{Gb` ȴ}q#0GN`Z8e G$>K=-"a?סB8Ip/N9n6~nFo΋/Haa!'NgϞ R.EDDJС~!馛] cܹ֭T^_m8A?4qz^MIw:x݉]{P$=o8½;v`޼yu]ү_?Zhc=ơCxԩS˔*]$"""RթSɓ'swӳgOVՖeޘ&~>=YDR.ُw{~Zo'Ջ<8E ՙ }UpBk>cMFn0`wug}v4dODDD<\uU4l0;vh|eP^=~_:q|I ހ/,?RǂgpD}~8؟(Tׯgٲe`ŊmۖÇ3f4hDp1T>(999}٬[.ܑ[v-W]u7oNpm?no %= .ƳZbև>dR[r%cرٳAOəgD yuEDDDz)jժEǎYpa=7unnnc _/> %8}^q19ԡvҥKΪU]6fԩn:|￟LڴiâEHMM-+VO>k׮\pXe/Yn]od 8> ,=]8#z 8_+ dee~z|M}]:t9K/Df]1p?Tѷo_fΜI8qb;vyfO΄ 83᭷b{:upꩧ& rssСk֬ {k֬_YfhтO?|m۶ap/U%EDDD233yX`QwEo^{6mڰlٲ=gҥtޝZjѣG2qD?~<\r +E*|P^=>SN?tzvڕJ]NNNKJꪫ>C,\۶m㣏>b$%%qSvm͛FAPHŠ/"""r >CԩC~ضm[)5k֬a.C*=zgѭ[7~'vɔ)Sݻ7gu>,\r ׯgݺu[Z1#RBn&|+.唊-[ҦMD!\FFCeժUtM̞={-[0gz7n2E*W_DDD8<# 4nݺ1o޼D#rZlGOk׮cxGm'ҳgO:D)R4y""""iٳݻ_ЪUD$p۷og,__~3x`fϞGDʈH)xGh޼9mڴaѢEvw}֭[]TP}֭_gԩSz>;T^ }-)-}aΜ9tؑ'cRZ5W2Y~='N}4nܘ{Ν;Eʉ:""""K.aѢEtܙ3gһwDtT8 j׮2rJFɚ5kػw/wq< ԩS'TY """"SNXN:q=׿5%;wyff̘ 8Siٲ%ӦMu։.OD܀$ Ju_w5oOtI%y7ywر#~;˗/Yf.OD^|2r嗳j* ߟ蒎h͚5lذ!eHlذ+V0tPv5\C~xiذa#""""eq̙3n_~'|2%V˖-亊Yj .dر޽Oӹsg֭DLRSEDDDX xwO , 337&)Gvblܸ_~мy*_D@_DDDM8/K/M6%f̘Avرc5koaҤIt֍L^}UZ?W\5\y|G\p̛7DYf _=͚5E|{n[aO_r!:umɒ%ٳ޽{kڵ-[0k,ƎKnn.Fbɴm۶K) """"mF5h۶--M6.鄰~vʇ~H=ؼy36m*Q߲e 6l7gРA,]͛u""݃""""u]ԩSi۶-J9!t҅?޽{3mڴ=gƍ}tԉLЧO6nȊ+0`½`W_DDD˘0a nݺoظqc)T۷gʕt҅`BS=֬Yg}رcʢ]vqLDT6mė_~ɫٳիw}7z*)sTM6e޼yݛӧ3o޼czreeg̙޽dz~znf^ƏO]HEDDD* ꫯ~ޣ~W_}Ŗ-[ʠҳl2FEڵoˎ;7n+S^D7[ BDDDDJYǎYr%?7xQ=y'۷3w\Ljj*f͚|ضѣ ]H¹_ |J筷SNGl߾=Cҽ{wׯ?NN/oiժU913:"""" /\@>}ؼys9+Ю];4ikb޼yp }ى.SD䄥!{""""ܣ>ʞ={h޼9W>lH˭+W2w\Ǝ޽{;3f ԩS -Ğy?|:t… iٲeծ]LΝ;x9s&ueL>?WD23ƽT_DDD߿?5jԠM6,^vyLڵ(bL4w} .kn޽{{Te~P^DDD꫙5k۷gtڵLgΜ9L0ŋsrM7OY&)"RU9THӳgO>StB^={v%KzczUV`^xmƽѣiذ!u-EDHѹsg^̙_}%z]vgo[2e nݺ)܋1㸙^|*oO^x!-N/6mbŊ̚5?;%Kp9c""+A;EDDD!CPF H͹袋<_waR^=nƌCFPD| @jׯ۶m੧bɬYO>[oK/*劈H1EDDDnt~ҠA~aFDDpBEDDD+qhٲes/""^hED*HX| (T n| pPH%/""""""R X:DDDDDDDXhȞH '""""""R!iȞH7ڃ/""""""R/""""""R X="""""""Q(ҫ/""""""R _{EDDDDDD*\=uwKIDATEDDDDDD*|J^ې3)rL'"G?RFz˨8ﳈ L?w~ymE04?DQmڴ~~ތiˠ`?ֳ9m%~eY<)cR>wH ?c8v⫯?x9Dgur,.ߠJy%""""Uq|qرc'?9D8rw/c׮]<Se CLe{DDDDd3Kԃ/A(uduDdgJ.3yAS"""""h|?ZyU" =Ur#'u=DDDDDDDj>S.|.L cT c"Ddvӥy B֊ܓ$ dPb.}DDDT^Bzmk@DDfԡcGZ;2gNF`=uykBDDvDDD \/x"""$9djz[{%#"Kb.}uE]X?DDdY3rkY?BoˌkhETF].B4l- Q ?F|RK<^,33y/''ޚ ///kQ7?3٪?z UB7/$\ĤaF]x6(7vUnӖܹQה'GDdL{..իW7蚫m`o#a_> LQ-ä㐙yǩȳQ`'a߷o?f͛WEs%\/rrr =]%5 EרL1T ,P.ZÇǝ۷#( HJ%lrd=~ LժյHksvqEzڝR/5%$\$&&eŞ𱈨p/[^M2K#g7-[έiwM.򸱍y eK`5Ix5h\L(($Aig v""z" k41c +3Y(B[[ͷDĖ~իWagg֡:tڷkgDdEj.k'"K2&O žq6rO,~+uv\rvhÆK (I^c=ٔmJp'_R%G\>|Igⶫ }h;@"=Qpjyf#Pʕѫ=|T\ِP(ۻ{?9osC9z/AMy_dP{'"K22O X ߟÐV]C=,?A^}nX#++ 111XZtʍR̰q|aEX~=.]JD*UжMLd*U?|uF@Ӌy])))!C[!@H<ؾ-FD ֶm86wCz`ED憾}zcСdkYĺuq=%9#۬1hƎE@@4o Ճf^Z˯Xt1|||`gg5\лW/:_B-w4oAss DZ&UO7EA掀ظqq?DDՁ9ܫ(ŋk X___ڢjժԩfy7>Wo.4ǫ;?oE;||0lGHOOGjj ;;[YYYj4'%]Ơ߁/jym֖ylJqŦjjMmP*5;8޽j5g}'>sāK)ƃ;;1 vơ?}ro݆3Μ9/g3f &$֯[SNkf͚0gN8NE9X"G/&"""sR5~`ʕ~:.\󱱈qqE\|lXW.a7<{驚SꄈEwu"'Os642޺ cnj{{ ƇC>@߱;<1kVN\d)gBҥ$S s.2w܅ p[>@>WtbIJkhO7 ˃R\^pBBB`oo5kⓩa6>׭_OOGHHӦ᫯nZҥ86 yCJKC;wBq>Μ2,Fh[r% G`` *W9غu[Θ1AAG`L6 W)&""2/ jϗ1yjcǍCnn.DQL&$I$  //5j@ʕ-gnlxm[B``Z [d),<4ի"uʙ?w<==ϢѦMk@۶m`\,Y ;t0 ʜnt5%~ECe0y|[ݰ@Rb"|wJ*aihF眯֬SΙV.| da6#p. \e@ ׮]'ӦHMUd:=y׮5]v '͛pwwGJJ b?t8d^h=zVxËf~&ԪF߈k($ j @kK"33kɧGE>:lq̘1憦M ׇbccr:␖AP˭V8;cXpqΘѣhW\Yo6&M`n78|/Xht #<|NFG#33'>g~8*4h,\WgLGmغBH8Y8 l;z4.w{OaÊfpDװCyۧviѣGunݺAڵwxj Q=T!1) 'MFW^ќ35l MŞ˗1CF.[{Ip?ǎaJTL0^s'qJI2N؇ODdl>zp Í"V r8C6^24HEˆ^ jE7rHܼu njEo{漆 bw#+;;&_{I 8xdfe!#3i9ļTdsoΝ;aذ6}ZcGV[34xkXlggv{ \[[4 Av|2۷@*5V^_5C~OMG`LdFv//&"""s*ȞC#""зo_ܾ}P*q^z:؎\|)S&᫯b x ڵѫgL&ڶ…1{v8/\@Z0e$ {&Qڵk]6MAN/i'LDrr2 K7.ؼ'"K2&Om7nLAl98,gS%T"jaap^ykZ©seVd];/XyW [[[Ĉ5}rF3?G͚51v(L7W?쳙2YgŋSpppD݆֭&u*1\Q;g8`QIBp98[JMߒEѠtEEaǂ]1->}~/"""=׿9)n g!=Ք=n_*ܼ\ -dL ٹ9C/ys.5vKľ%_P@ɠ|'d-&Ll['N 8$z;w`0xKǯQ_C]WM7KyDDDjJHq*9QU=IIIhРx2 ?o.F [;;0z'"K26OH>{Ht xzkגQ'P===$dz zy:9&u潱dv67Y-oU(WDDDϸno1c7ÞP*vqcFƦ7&8g䰮/nt˝58q>>pv.~>SЩ{Lj|[; {ODDdiBÂ=Frpp@֡%4=!Yū^ѻҪTc*Wi`:""RPp=_b돈,yR)A.#/%rJJ*^PוC!"*{BWw%ÏDdIӥOׯ\ND^,Rˉ۰^UW֎*8U_ pqq$I(FLZD$ŅsW@+ #kGeuGƭ[bͭC!"*u*Up n A&t1#  IyUX;"Ky!I""A_'^vBZ_8cԩiPb.}DDDT^_NkADDb&"""ˆJNA⊷DDDDDDDja&&76=U!֎L"كODDDDDDTODDDDDDTODDDDDDTODDDDDDTODDDDDDTa!.Zuk(AyDDDDDDDApPГAR5 HJ@󉈈ʴ>y!I|%DDDDDDDe|mL;$aے$A&h ї'""""""G{X}%!$lE /@nj$ʎko 9r{ODDDDDDT5,_{[C݃%8DȺ ]1yODDDDDDde z @n/FedȰ|Uj{ Wgpx>Qyt=ClDRaOIwo5"X->"""""""* 72HT^&`\k -=}""""""^:m!zIENDB`mathgl-2.4.4/website/udav/udav_mask.png0000644000175000017500000006462113513030041020237 0ustar alastairalastairPNG  IHDRh\)sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxy|T B&3,TIH(ZZn._նVVKZֶ.@.uEDT@$D!`21@&s1I I&px9̽9|͐iY;`Cuq۳ AO(5 (&ŚS?oHgء{kܠf 䓝ٵ G|UmOǧa$iа n֞֌m۲m[a0?ȸt^s 3$|{io5ɯޞ32 KaWJTw},Rkkl*_ O VM--e[|><&\-0 5 h ` #&o _f}ڤȶʲʶknkkS*CmkC]jkj4t=קiO$=g2&xqQ:ݹ\!Ky>P, 0zje"Q~g7ohCj90͐0Y I6$Y?IvYw$B +?L`O; 邷{`0aÆ)'>L_pG4l0IWP+V[g]}5*<@}]iV/pz2wy>C=]]k7eKL-*W`p X=GoIM+8#kȫϷ% 1MS6nPIql[ںebbj-2 Tud /ծлPAnFw]f)kȐ!zm֬oH^yn?ˉ׿o:H'۶h"}ᤓ2*׭ׅR]pZz.]ә,1M]٭[*Z_ߧqa7)ؠklk/Pm}?ɶ}l;(v@M*G--=.)/8@ ԼikTU2 C{nY[ZO/xbrm_a;uw_|Igq ɓ5`l]tc=:?i&͞=[ԤI:5˟֊+4`zη/ȑ#%IzWEE{T_T\\Y￯\K.a=z}u4q;ż暫<+Wj֮5SNeXޕW]kkѤI;Y=}Nnc}lrEQy}VONג%Kܤ[_Wu1t)[oxz,3U__}GjWs=͛7P?~y_']757M[o]]w/e۶.ZRw}we=֜ _k"9}uzmo;N WЄ *8`򂫕Nd7IJ,54kQںeb^mm٬K ߰m[[jݚպ $I/re***vZu:uQGk͚5$Yf\|b]>;k,b1renˌ3uM7k޻ u%hCF-Zg{^'?\J?z5{Λ3`]Ízvэ7ݬ**|GZv;SοBIҜ7Rޓ$=uj}/uA/_~c-[\wu.}_-i]z;^}=+*fMouAgGTx 7,UշijnjV0-[u7պ뭭[5p@575sk6TbŊ.~zԩܤ-Izve:$I/;>d{qM7+4lO[JgLIԦ>pi555ʚejijI\'iujkէutWHf1}BԊKJK:N;j ׼y,)Cߖ1;Rwe,X&nG*ѿC/>Ҁ`@vkKzz,яYç[tHk_CE7nPyY 5\~ڽy&x?n&t)}vwWc=R56v5?Ӄ>ebz?{mwܩg#=x@=Z^S .@o{r B}*;dm2V|[U^^/O?b-_~?&Lha0$L4Nr--)ֺUkٳf0r ˶rjݚƶ߃;wFRlެ5r(͝;W^z ShZGVqq,ʕ+5zh)<@-7'[i?Sk-7IJ40X }W_~ }G%%Śz*(($-[LtYgT'|kÆsWNٺEgO|PszK_<hƍ:Smϥ} Q-[L_e7Ie]?ISK1hmպ5wڒnlz,ʌev4MmټImm}ޮkuI'nSvwW/~K]u啺kn]6}=a~WtƖC75'y晻Uv1!C#S3g a>} im'4cF{zrY~=f_577kɒm$H;$jmTs?*uy͌UV)w>_k㯼;,I::_{U~N8Dvp [>0ߖuvuG+gO11;Ōo_:{9kڪ+VgݺVѿq޻ ;o#wpnbޭT֩;mSOaz9w.$}_61KoߢE^ާu(uk O{;^}=wfnCv=]Ϟ:U9Vׯۥke756ꁿY0ec4glT[\/:Zv@J;ِm烺R 6Lyy|R(tNWQ@%)/An's=ozzZn@/}8n5kTWW޻Kg^˘>c$sΑ쥗ef~Cok׬_|Igy Љ{[s9L՜9su Kvv|6twޞo~3 Ytw?T30abe7d@szclmؠwޙy+zGnilqIe]ojL-CoȉcSvMZB~߶ʎZQL?/wܥuMͻ]矯VJ\>YZ#Fo{Z|nӵ`=1cOkӦK.ײ;(cȶOo[jkkЈ_+4lh|~UFZw֬]X,5k< Iַsmmm]B6-X@_7tܱJ/^Ol|湴J-uQGkڵZ\Q!I uq)oQ,q<ޕĜkL`VT-?s?K)kƍztפgիw+딬XLg}l3T[[NI<==e-)gL[o/5eꫝ)S\3+У>m޼Yz4]$Iw䌙{tÍ7j\Ӕ+u{}_RSY+)}W/$%Zк4VKK?:jH|ߺ{tmY領#gBoo{>T~_=][;UvwvIQKs6ԭ$խ_x\ǟp6nKlG+M+M[?FeqG5mZlkLs^@z[q*+?-מ{$eu} :T%JS-&2 UQQM6xkoyC*ЀeZ[1ڠm_CumYZlQcv$h9t֭YnN׾3}:z=jGw.U~vJw԰w;r Q~AXkMt.? 4x|>L3͛Р- Ŕa!EFRvXOwRY{e;TPP3kk˶>ݭgo_Yf'87`@\-S ߡTT_K&nʖJc|tYmr|o"×ed[A`YzM AzLROiEmt`aF֭0p֯[+?t,}ދVڀZ[[uϽ_WPtbϻe?.BnK;srNۻU0LIl; ko'hϡ^sxIgo"91$g<#q_ $Ύ 910~5c gxad9իi&7dzUGpcO߾^#9^}ceC#/ǫWk*U@]__-[i&')RcwuM6K_>F$fW }iQgzMĖD]9__'˶UtX|N:ŶeYVG+Wjl1vv!QcLver.'-[:/(xuy@@;PK*uHс,1vW]\9~7m%Mn>Rcwuo)as#nRq .}:-8{q~F?r6H\lqWTrmĭѡjjN)'.:4ӫgq‹usx|ēNN'.r5烋ղ?p3dx}RڪzX=>xJKnJ:q>xڕr?3͙;W&Norkxm35gU,\5kwݭE 믽.@|LvuNk޻λu?Rn} ~uRv?,@3fcӈ{iA,ݺlzoqzaz衇TZv'?BF/}TZ2x+jW/|ƖN>Eӧޖ?P=׿!AW_{M_9{JJt'huy߉E _8IJuڔ3hb=gt)_Tiaƹj͚5}*+R9V=·9%I_9,^Z՝-YDk׮Yge.P߾}R{n];toG5ٲ,K?}ZTḑ4sƓZF'|U=㏩fGk~r .HGu.W^O=t}ywz/.vgN>H&צ~5?%˲to|]wA/`<=Ѓz݅˃&-?R?^ ZBp IGcHر3R Ngӥ\r/uӍ7hwtӍ7?Q͚[Ϛ5KO<~~t $g뗿^?wW-X0KN}7}9=`;:ct鷿3g?Q5Wv~}}.7R=V=·s?I2|>]}Otǝww~ǝw"R7Фɓ4p@9t~+v)c&k!5jnf6kVeK_Mw}: 2D?r}g;;v:L W^0?vZ|H7=34yRr:3wti„ j*x.] &hȐ!0a~qz/_R]ڟL{WҸ?~qݵ:4x`u)éM7ިmolWCܺuW&iۈ?mK{o~Cgr:4q>|x?^ kfNիeVQQNdRmm9kG#kݭ{a1uԄ =wcðC}庡g̩c*9+-m[>Џt^ٶ'=O˾G[ >\qԨӗbu%Y!NOit~wWNS>K6K/?g??.:4qza:/$]3ĬT:-Uvgx!яJz^5K7r.2]xI?sE։'?o8>0zhXBg$~^^^v  k F7#FuZ_/Qϩ]5ڱ)St=In.t{-?!CHZ"/ IDAT_8ڰS |jcqk[\Œw9x}o=}8ڶh6˕C[ٌǝZl%8{q3^r,Oȓ |}?ًc._Ԁrr;*8qea%9Bs$-]vxC"YV$g<=9{dD> Ǵ'gIԙ91PAn<rC{rNٶ-Y7f1v r l˶ ،lyגeYr م֚m9GFqpAeٲDŽ5G@nhąaO'# e`1r _pni<<_?r w?g_-G@npm0K#bA# 7Vse9?&01 p9!1+U+)c|>⦩p$tPHi*(;74M B%q3up $Ⴐ**U2D~f,KUUD"ê՘1 5MS555Dy}9̳5~}ڨR5>͹:m,Li 5D~W׵p$p8q%=.Wxm:7TR$ѸR:5yĔ?_|U=sWVV.JˉKܬlu4Ц&$CaF8aԜd3gɵ]Ot=UVs%ՊFPWH#G@cy]SFi^bb557H~ߑ2MTmM*+*T{Ij3t$f9gj-.&.q]{:fr[A2 CX̑apLFuĉ9ojB\#n#svc4*߯X,Xx\`6vxβ'I\#n#.jެTbے '.q@nlY_DśMC\!듳epK yXYǶm'Oa>7q䆬9۶%;~ 7drlٖWT;%.q@nhO{_)q qd'_s-MG\a[,eY,o?ÈKtrfpRB\#.d`J#Hi 3gH<7q䆬OhUJ MG\!sZKܜ 7d}rd;>4%n: ²e9?r* =q 4MqG 2MSPe "aMS2 Ǟ|>MSHu5n# HEUSS1c  )4M(5(RysN&2SZrb74(݅Y H8qe=.WUQhT;7 +d\ qzLGkv;vAx<`0HId;/o/we0˖m9{ճl7dj{஬9[xT/9YmrOej{Nhq[BIercڇT ^՞`vN/^ezw{a}*l٠Grw?9aGrPL @rNGZ/p2஬Oijxe?;PݒHN;b\+ dYΏ'2gGɥ 4MqG 2MSPe "aMS2 Ǟ|>MSH82>Ws8VMMƌ)T0tL4USSHdxaUUTd\cY*D͵e?6/o/<2Ͼ`(RysN&2SZrb74(u"TR$ѸPC4OGT2rm{ϻ o|>fNɓ&S~}Wo9hiyy#to\YYFݑh Ǵ'gWYۦ ǐ$2 3ڇsmE. QgB *+ljEQms$#UPPcK\f<஀8>*-VSs)4MԪBIT/ N?LGbv3{ޯb׵:cL30 b1G1O>D4'vNԿ' q:ϕڍѨ~bceqGJPW'ᙃ:^v&q:WJeےm;{>s%n: ٟ-Rxi 7d}rlq]⺒ٶmٖS&MG\! #k׶mKÍw|)+7qd\ifٲ-gz '.q@nH$gxHGR7rv4%n: 9[c RqB2MS@@xܑ2LT tHXqӔ ñ>OqT8&.q]\IpX553P`Б2MTMM"UUQq%;4eYR$!.qݍsg_p~T~^ \M6Me|ŪohP!E H8qe=.WUQhT;7 +d\ qzLGk7oqםN mY' J\H )#se뙸N$4m[ u'.f\dۖ,+R םN⦩p$L ͵32v8VMMƌ)T0tL4USSHdUUQq%;4ÑeYR$!nKm<2ϾpϪ_>9WSMe)-_xm*$TR$ѸROƭPC4OGT2kg}5stM41Ϙk@/Xޕ*mMiy Qw\Yq8n}fx Ib2n۴;Ԝ3a]@tUVsk%ՊFPWH#G@c\͵w$ɐ>UYEEEijkjUYQ$iTKOq#1;̙=[WWklqqgj{N\^pR74Ha(9Rf PB-]aeѨN=}S Ns"lےp_/hdٲe[^l5N9gE,|$kζxT{ >9[-ۏY){ >9۲%Nٟl @:J4 Pw^H Y2)jtjJ=TN_sHNf1NYeYΏ{ YW~($4)34M BI)7M0{>7M#dj{N\^pOG6vUSS1c  )4M(v9WSMeŋUРhCtW׵PAHpDJ{\B Ѩ?w$n8V8Qɸם7>_3OIS) Ђ=s.-/w+T27SK\w h )c @f%QscHx io]@tUVs%ՊFPWH#G@cyTYEEEijkjUYQ$ZTKOq#1;̙=[WWklq1qZLGm0 b1G1O>D4'vNԿ' q:/Qs{c1W,sx<`0HId;PHi*(;Rf i .S +na8|)n G%q3up+ jjj5fL#eE"Ó-R%Jwh˲TUYH$B\7C7%q#ﭽJ0͹:m,LiŋUРhCtVwG"ƕ\UEQZHp$p8q%%q3uϯӧk)4׃ >qsiy[WVF\fMLG$aȸ|L <'e`LI0 b1Gb)ҥyEnN3t>hT~߱ $qGh".q7Sٶ%: ِk8^r,/*⢂yWf$˶hiqY̖d$ookONt}@y䆀x/lےpc"pgζl٫ͨ1G@np-9[xL p! ٶ-hys8lr0˲e9|;.k8Оߙ–/~: p٭q8k8n?gn9>RqG@n׭ŏ\y?r ]\87-َlda[8lr0Yc3r \ V4%pyS4. 4MqGPAu5n#nrqpAXU*W"C3X*E"qaj̘BAG⚦E"ÉK\wf<>C2 IDATG[XLsޜӦɲRLUEQZE8V8Qɸ\X 6D*)h\Y)qzLGkYiȴ hԜO:E|n.w( L64~PbAjx ggQ:15g#jx C: ǐ3$0Dm2` $!6ב91ə3ǬTxhMrcHxLa^ 1-5g< ǐ3h2! oJJ91Ϝy @fhF!91$g< $Rt :15g< ǐ $A@I$g<}V*Ritړ3-4Ql3֞91$g<39 'PscHxI$g<&1e$#Y6#Yə<I$xϜ$3C0<axFljx I4 lmԜ3`$g<&m:y B'%!aV*26 O3ϝ(gxi dA0} Ԝ3HΌ@?e ǐ FZb< ǴƝm2#Ssc O; ǐ3CrcgZ`lm< W03DrcHx 9i, s Y$3Ӟm1LŻ= C4}PUK6q a<+x12ͽ/7M2.J!BXr'e{]euT.4)&fH_}a.Ip/920naܵߏ&Yn cvvܠÓdܲO&YM[;>@uwu~;_vtꬑۍIⓆv~vx$9ۻ3>`*""^qC.UjZ^ͥ*FYu]2 ԴTDdZ0cf }߯y9=3s6~wBi=QM\68 !|5\z.'ˊ`;`|qtx0(PմVs !qR7[M7㐠TvTM܆f3!m`[,.w',Pgδ0 Qu뙛(;o[DWk8{iAL KalX3A1*8@Z F4Q̖U0RgIa\QRWN*QLڭ]"7R7QwI@Rud 9 k-'c8 [;L!0Җ3#=gqB{j6(s63Ne:59#u-КթyϹ)1`mlp;-U5J=g# czldq W[[m}Fv۔q\n˲`ե-_Dc;0GQnmybWV֖/eqC8Er6+vG,y7eqGkʮm@ʹG//ş`ccÇaάj6yʭE!e1 O'|aWty8>}rq_`ko/^{s4Ʃͥ+ `HxlBid h%%%?_ȝb2DGw"K3_?^Y-ouNKU,|>pBNH1b<)bæ ~ٷsuu啔ĭ_n4[f+VMg”3uWT֯]=NNXv y=aV^9ڵx>UjDl{333-Y7V?, }}}}}}, s_^GؒŰجBZ&!f9N]:t/bvo-0@PmL$ÇWo kk+j nT---3{G%ƧzM^3)s%<3EhlhmxkU1qCP=,'q҉HjDl4T0}#bE\:<),WvY.#/vGUwo TeBUZV]]]q=7E]u"/]J!eW:Co01hk.  ccc:];!s❩Sǫ7cEt8@pG`an6;[[\G _V7=q_uSu"/]Jih053)k‚푘47D~ ~&0{¬)'bb~f)×-ŇmExQT.]\0kL, [{ax$?'.ǟ>-OmݧE^ʕ a4Ct t<&ٮS/iXj5>SWkʕݳwc[,}RYR[+ E Gr5@8p?Map7c:q.֮߀qc֔+!& +&#ǯ. CvNl4~<=YijMBQ)3cnjw Қr%'Cbl>D$GX yOD"-㟈D(UڊPb|@:CD$Gޕ-'"=J;ҲJSw"TE㝈D({-,C !!L6nA!-t@JsGp\68 !|5\z.'ˊ`d#5A0DKj;JsXǫz>P*Wq+͉f~DCRQ5qa~m&f丠W\_kX(!Xc"mOcOyԭM!4ILE!ᘴ.{΄҄ӭITtB;y}L !*gB!`B^)̦3!hVb=aJBHeems9:Q4=!&!;'q,1QN!YCDqWsnl6ueB!iROр0B!V4A!_Ju^[έe3 Q5B!o>}BifRiK/;TSSStGAA҆r^&&&puuEXXb}-[]vTs)/VVV:Γ'O0k,8:: 'OT{i\W$%%a„ СD"ܰ|r<{LEWפ[111XjUqWk!D&k93Kaa!QZZI&5)qI>Pc9BP(/3gĒ%Kuz !%%ϟ?GJJbu!""QnH%<<GFZZ>}"00Pck-' 1b<~XmLYYw^Ai\aifZݻ2VT⢣+344d...;uaɉݻΎľxY[[|m۶9880斛lllxsz޽ƎˬfGU{{1&k]366f...lBQ.Xaa>ܼQ޹s?YZZvڱqƱ'OԻ2]ZBfjjr~\\\!suue*yi}7|c7okh]Wo ,,KKKp 0@,""{EAAۇիWٳx̞=k֬A^^Ο?dt8rbcc1fXZZ+\xukqI&as^x(?5k 44fffm/^ʕ+sN !!)))زe"Ñ <|˗/Ǹq꼦0w\ ++ XlJLǎall L4 *EG" ;;WƨQIHHu~ &&6mjkI&[*'Oxb$@j9+tYeeeĝ>}Ze/+Xll,yXݙD"Qlg/r+++clȑ,00YLL sww=V)usrrb%%%*ۇ ~'mU Y"s-gϞ11c؅ XII {1;tcNy.u}5/ݻwg*e~ WS||5V^^ؖ<==Ai>ZbSVVV[n +VP={6:G4UV!,, &&&*SSSѿ@(B PXZZ֭[())͛7Ѿ}{=bxWq^z%O:6662e ߯ҺU.u}c(//Gzz:pB~?7oQkR]ڵk###Ŷ)S`Ν6#Tq>\Ё+}_kX"Pwׯ."dοx85rwwGaa"۷W:ݻnꚎ=]v!%%W&N6mHOOǻヒ \R%{ATTnݺ{4$$$ի8@1o<ؠr/^tK}+G ϟ?Wߏ%233kXZZ*5i}9sTuĮ+7BH lpp"9ysf,+={*{Dǜ0aq%?QyMLLзo_zh$&&B,ٳg8}4MKJk :!f@t /KtwϹ}8~8:$ԩكaÆ5z"B4UUUgbx!4fͱ'Ϲe˖oislܸfBnn.***<(344DǎqF}Bif@})qD8v<n§s!m>n-gF#S !A9S%G!|!u'5E渐 !*91" =srp"8i!ҖXY[Bd;Հ0Gi77mC!%nmC}Bi 8NZ7/!R?٣Tz΂B! r&BZ !`!+'bl #?pp3?_Y͔Yet2dW4[Z깵 !D.+'&" SiURShl o {I5qpcqoV3!#ͫ1 'T[~?D" ww7UZ΄6!// U{v2B0&}#Y:irO6.+IDATЫdf\5sKE-gBH$DI ϵ9O3!͐0E"bVhH"an4*3v'I$Z/%ň,--ѱcG8sNEW\A"ey)V,[ /z^ݱry={gy}o\n]wOr3Җ|7!b Leeeht JJJpU|^9B֣ӹha? <{/O'۳011Q+瘜ECdTm9MTYW !m0Y+Oeǎ®;ѭ aa> x;x :u&O~O)-ڽcǎc~.]\嫜3<V֯}Px͛BQ@HXZxڞCeWd$lmmNtvv];v~'j2?q-mPLi3haM6 3{޾[7akk5k(`֭ذ~2CʅdHxbE̷ b… [pI\E/cÆ -A&N|K/ퟪGknH[_]_:_[68}Kź<Ϙ(a8.z]h@!жr}vq).(lddp _tt4z055Æ秈ٺc|1\U޹3vޭ((1c`E*׬&~ ׮]yݵ[7 Slǧp%( OR)PLi3Fk7Xr%~|yPʺU(((PlKOOǠAԞ͛1bJN1}tq (xu߇|rC/f%|l9&K% U 222зoqs̓"6m5`rn%fjjZgEEEH%66fVGa C䣵['ggd|Vٝ_E*yy=wޞb ߜ骐ht~!tϙfHvƎHAF7n`ႅ@&==pwGJjѻwo9Mʹ7FGԮ5zLϢ;Ö.IST9B-F͞? -; O>[o)tqÇQ\,F/]Xzzj)o ?ǹΡ23c%Cq&=vpB2&OahȀ0٣Tͽ̘GEx x a?cEr]q-mzę6h;!Ng g.Att4"n#6.]axgTEy_ذ~="6E;&N??Eq`^;v >pO>f4$$L?MLpXD"sOݺ`ʤ D8|,FFFX@uT#s<Gۛ? +gy}%+iBH+E DUUSiUB!N8g>J\@7} 8v/dBHihKTkۓ$eL4kLo"9z{R#5dI]LWCB c Tc?/&ϵr&Z>ԀϋQ˹ѴB3!Mh߾=*+pT4@ @ee^~ژTA k P!BOvCB޴@zZzzPHS84D"AzZ:YDYaWo Bhq}*;)ݭEEV9Ks(9Bi^:9+?i^~=,,QmT_;\?^4cvWO[ b`ܓ'{ H!]ΝBN_{}46 uTB!8=8Q˙B`YI!N, !l 3h^hB!h "BJ|ϙ'BOn'4IENDB`mathgl-2.4.4/website/udav/udav_pen.png0000644000175000017500000007775713513030041020104 0ustar alastairalastairPNG  IHDRh\)sBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwXGwG MEc(`b{714K|1 $֘{/Qb *EA;8g؝wޝyoޝ220Rd Z1H PRƢO_ӜyN*a_2e *k(A1" *H˷ߐAs\%#寶@ e$-S!|vc@ ;'V J$Id2d2@ w.-$Jp/)qпJT"Q(04,!T!R$&&%IJN&..IF. G-llLFMYʷ1"2Y zIdIHq$?5W$ j dEvtrr21ԨUr圑d I ݻ-ed ;+ NEllj,,BVc-ӷK\"% E4a3Z>OBSֻJ*ju @nԍ$%%caiIbRH)s2NNxؖ¹8aee} ^ưsLvvvT^.;ӤIc_|I~Q*XXXf*3f,3g6˔L8իp<ׂ7o/̞ e-dC ZmȓJ XXcek@mns|CT%ce pxnDR,n $H')1WGb" dNhX(*XA^X}//pptgҟt=tJRJT*9|&Ӟ=8xδ\W/߁ /$/ұSVE t!!Oww˓y);ŋd'&$"<<[-Z-)Q(1VVOxFpHA%Q*#KJBHj+$ I?SY$鍛5vD`ڣln\E&a[>3fϞ{S;tē$}!ɘ7>ÿ}޻"hժ=zStiMژ; -[DhHY~dmN`` ԫW/ |ڵ\|HJ.;o&nnnyׯ_uu62*U^㓏?qƙ4i";v̓HH^iLאNi227~DGB\,*V "" I ?_~@+Wx ^ԫ]//o?~̕+WPtڕ$=ȑ#$%%ѥKW*e˦Mgg_`A={^9y~:t}ϥ{n:wsU2‚w؉Y6ӿÇgs|3._N}ׄe<ׅ!׷_N =z/;w%J,IZ.;w0˯}~ p/eP}e..]¶3o>V̞;7s٥hWvb_29\=f,/L&Ν9_Ȫ펍l\>>t%m.Ǎed&'}s-;9)w%K77?Lw6nwޥ_~_ڰGlɶ_jdddD<=Ch"ӧeʔKܹCi<,,dEY '+H@RbIə{G[}'%dR.$&42٫HNtͮLiM9tLJ=zrrN:E.]{.Ϟ=ۻV(33""^pm>3E3z TL\Z$&8(S~+!.6Wv RZ]DR$I$+/ jySMC΄?\7%1q$-sC9y+dϿrj7pN:S{w+II*U&Mu&ڵ\&nTYՒ$Sk6mj]atC֕رV 9$IcN#g299SyҟPȵ$&&h9Ea3vGPv-͵CT* }t{;۷'4$$eaX_|\ݣNqaT^Il3gQB aWϜFN;n޾# .$Iݐd?~.7u:f0.^LogtM`xᩡn]H!7‚=hպ BsvgɯAĚk$%+Vj*ܿ{G;k2dܹs9q޽;|7ace[@Vo'ː$KvbRw찴@.Сvv6ܸY}>vͻ IYJ !O-2Y~Rqx+K+B)aξTX'JŊ5CBBjPM裏ԅ` 8r8*i>yvmZo~=d2ڵc…8q>'P(o$2օ8=je2_ORJ#G7f0~CwwΞ9۶ռyduɎNY+U҆mp1B8} 6664kD3c憍ct䴿?W^iaLQȮ€[TA ض[줤D'5b8~~ ~DlLte޷/I=Li> ٥C #έ\ްa#ΞcMXY |q-AG. Ie+WFPDӦ<{Ʉ u+ܸ{9 I6sr2\t eII ._]{ E* >}oy III<~_~޽L̽@fϙ˹sgOڶiKx,1.V3y+*qxyy.] 6mےČ?DvTl &Mfw A25qF%+W֭(J={ơC8qQsv ((PnNtJ^rR~!$q&ݻGz1J%ϟeVl#Gښ_~Wē'O ﷛.S~~`vrC;+Q/# s+W4ȈpȾ{:jCn\͵lOOO6lLrb<&2< 7Ѣwd톪VQ\re(Uʆ[U3:u0~3 x7h&K {?pwoH,㗱 XX`ˆ!Ti8::k˯KYi[s}j΋Zi.888P͍VÃЧ)sQiݻw'9UrrΩS'9p <=Q*tޝÇi;ݻk51c}/YJll,cN\t\+af.YwOll,L4٨|Ǝ߼y >?nN5pkJ۷ eUե_@@qqq4m$ۺ/Xx1s#::J :Ԩˮ!FsiNJJqn٪5qQLRIxjlGHT: cy n|Lre5-|q2ʎ={m37ʕ=jO ]24h؀$I*rVVVXXYqebbbqsO 2;8bmm\@R@"_z%JEb|s?2ol޿Ƕ-9Eop O2ח۷Eodl۾슃ZG'Gf85k`iiI2nݚw t܅ ұs6f׌_n=V^CSN=bȑ4n[CwCvޣ|a{ж]{6mޢΝ4pEK&LDddd&> =Щ3?3t;ծ[֭}N5t[wxwM.]qlD?ْ[P0cZvzCSې%#..-xe&Gί-tߖ3rpk<`14i֜7aĨQxBn"uC#'o(?c~t2-ZuӐrH@C_2hպ%KŅ#G4qfΚ͒ŋh֬6%JPz5,^eago:k_~F`%%Isu2dp9ǘ.A ;p ? ܙ|K~G*#GX/neIرhFcå.oٽc5Yf5ΝՒeL8ٱm+jф,XosgϰrrΟo˵םv_8w4m۴f!lڼe?S'yQ#~muzzS ?Z2KӺ^7'ܺuKs͛]3^zrQ9LyӊcȆ|]7vz<1c7}.ꤵVz5Juu(OY}=T}aND?C.gFښ'ʹP$IB.Lg}]KЬiSڶkK-t׶]{&Mțov 1ݻ1>/:u24n$ =}9Fݻ^:/hҴYk:vٳF=}͛g 9јbCQs߷ٳk'.0m֭ 7ؽ{wN;֛o-Ǐig7 g-_۰,^Wiްȅ L}y980^?]zWݻGM5m֔)S*~;+>Փw.;zFhMr47nīys2vNNNZC7nO>2?(Zjf2^ζ\si[W gF6iB%8|ڷ'(( uf[k.,WP{)ޓO9s/\ "umBЊc7&}d g-,^'Oa_*U*w[rY*vXPOOvޓm껹1jHV^#5{&J{wx gΞtͤzXJ*0uzVGXz&`縸8=kܼ׹}7hœiH׵-,O] 0+Vmvz3^A+o\ΰ_bJXaCu_SZUvlʍk\|)(1#o(?cliӦ<|/gqCkι0I3uA\\ǎ'm]=J\\:t5^*UrcZ? aоrO^Q2>=w5j4I|}ԩSAhm’K5au3ٖ777:+kjLUW ¨^_}ѵkBENK:ڥ Wp- K#Q IDAT\ʰC)_< +Wf;{{{õnܼi|1fM/˘2mvS} ;)9ݴX6ӑ5dަu+֮YͺuiIcaYAQF-<<q1VX |W8J/I}Tx~<{Ӧq=J%QQ?qAC8`>>38s,qqq9{32XbϊAp)SzF'NPJMȑ##ǎ'..1qҤl1f(/`DFFi Ԙ*V)J է. >}0qdZlPlA,oLؼqCjժa&Ov>-[Ǚ #>>g0aD ghРkVbμ߰!Ou.6f݄$QRj..{fǎm:ct1ݺu[n{~riέ>󒵵5k׬+9z4AA)xzxзOMN:<9S}Ó'OpuueaoNϊޟ?/+,Y&h|MxMfT{8;;G=Xh|qȏ>3:m|})W,Zl f?ΜI'::5k0lPjI3d Y **:GH7B5uXWk٧Z] iz*Vh|r9֭jmA!GeϞ=̙=ly.JXYOp9;udɒX*T0roco*ACMܽJU *EuQD Ο 9^@ 0bp&Y&׼b=uPIWQAwѠԝ.ਔJJe~!^ulDy mRιR WG~c ʻh ;gB d2\ޙG:W*U/jM)TW ZU^1}c۶b?qA@qS&߰ysne*(P< YXGӞ$%%]6Nc$@ʇMH]FROd\vM+ ˖g#Wtƚ5Ӥis*VI]&ɓwk%w%In=7> ֩{?`ԥzZ7~i]ܿ}S*ӡc'oߡW|*ct)XYYZv 2M2Wilٲ:Z5o#xB9ky&TtLf^Y{,).m޽h׾#^qfGTjݫ1uӸI3ߓ 9n@^=u>Yۿ];w|͟C:tvmfg?(B ֽПv;ՄlظPi7cYE[PSnnnZe˖47oޤYZq5kf 4ũz]| ws xx6ÇZ=5oxs9_ jelݺ봇} ;sc…x.]fꔯ?}0_+˴FF9|৏yʸс4MʶZ*e,[4䛓(L\vիk 1,gij_ H8q\!O yj yI5$<{l'(6Ã={үo_)+իgOʕ̢Bc,o7!ټy ;w2Z[[[:w[5b0LɓSL:ѣFjkۮ-':CǟkN5jvs0A+ՕǏVg=?ɧ=9zqqqraWW|ua.dٹs'MqC 7T&9/5r$_Oӧ|=ej)(6nҤ LoHċq >3z4_OʩSZZI3޺Ot}'zb̘ь70vxƏо][j5:tCjڵmW~lڼjӯ>}j$*V52jשo4X^Յ1D҆U[owcM П JP*缠sN5GRVFC)~[׺U+VZņ h ԭ 6ls{?FSv]ƍcdKFQ%uvt@PT9wrJs j BNzWlAQO>O>o5AF k @P0a@ C@ (`|Jt@ $3nB"xsaW"a!?((|8nv (lv;$h9\ wgĉcǸ@ pMC؁"l[,Ky0ŋtI*_OG֭Y ;Vm Y>af9V%}Czao@2&$xgH#3rva†moA23V -aa0WՒ[T)bcc͞`ٚ z]R~EbۂŜpLdd-KØҶZ1yG~-EA+SWH`"NE&csN|HzW2ږt-Q/MCt\+1 3!;0L_A"l;:ꥦKsԦlyv`*̖Pgqriؖ2cݴj݆圩Wߍk~',Nz7Ȕw-LCwfϞCRRrt-jdjU}v`#c]XwOɪU3߆ iѲe9SFM ZV\[8:ó+V4hZiwz}ޛתTk%zųg5wzRz ʖel޼E^]Ƕ_FFfjm KvMW;g75ki;p`*jk|h&5 9gI呛鏽2nX&ODཻc;'W+ٳ""<[iOܹsxp?[6s .0Zעz.sC7se5{6{֊?o<|~{w9qj &hٻ_??~i)xB|={6K,@-\<__4}eܸ@TPMׄ///Ο;Gu۶l.gۑ/"2^o:C]xnob 8p IRs~ 6m"8)ё \N  -K} :GkϛˬYܩ3UV㧟~7?ΘAŊRΜ9ESwEtޝqc V:Ú5kF>}t_]vu^ gK={6-[eV̚5 ҹsMe˖@%1/// 1{,fY+Kc̙4-9s&{֤9q&5SN[~=}]ʤ.5jԈ5WkiHw6iƐsC횮sc~ڵȑԭ[]v#ؿ9}޾Ls1,eիlRo>j֬9Nk׮ѹsg͵C. #$4 +Ww:Ә{e7YpmҴfZܴ:9v 5kYfzq͛7 JĴoᴿ?ScB 4p mڶnhڴ)m۶|Z]M~vzʖy=-< hk΍Mk׎+V0tPvMϞ=zLBo_ye"eX^y9J(a0[ZZ(mLL W._"4$Ya!>bc %@2iRSent/L9^vd>$iFI9r0!Oy8J 6m*[njժݻ-矲82mۺga<7!{خeҶ3_'N7]g7w 8|||PX`G|#فuUV-N ?ykt][.h>s6˴jDz8:S\xcR r/dYn=9xs˖(X]s6vΐdw]v`oچnn̜9&MT777f͚Mƍ+v`*6А`ʻTt=;O*_}%G Ϗ%R#g' _1hmܩ\pe~?0Z‚ɔ&;x5o?0Ǚܺ}Ə%'eZy~~L5j7xc !$c7j0Cf.1nx?~BJ;N;fi tЁO2bHBCCZ>Ym߶-Ǝa1SɵcFbɚ4~+~ٙÆ2u70B?J*W˲l.=m\Nǐ蒛D6mڷkVӾ][>6[[2rMjV4yg(0O{Z2w-T / [Au5;pcG[ASl[Cv\iղy(ǚR{xL=&AQzy1c>|U^{7o2qd>B{?)-0S?|1"3vL!-[0|H=z+={~ ۶8Sa_HfLoHr#-vAz?)-0c טZ+G_aˆmg&, RP9"\.GTT6  #¶`8g'''^B P(-P\rYlIa0LYsC\|G N)5heaˆmg$uAXOr7<amIH]/_@ (`_@iX@ (`,A#9-@ wdwo0*Q8n[A1B8g29t/UʼncǸ@}7lݺyQ B9gx-Z@J݃X(,G֭x¬% ,0aW{1#0'`H H ZJ^bBB 6R`&,MfER39gS\8]$9iIqbQr.< jI2sVWK*Elll~!!lܛbe HmDϹȒ%Kٶ};?ښ5bȐt)wϹ)A1\ (=W~*䖤$5k`TV8Οo˗猄$IZ^^QX@V|_l'""wJe0~Vؾ} (Q -ҾY|-(W,.NXYYbggGY/kNͩZ&Mvze_مe~ó+%%ܒQm;/YJ(cg)Cvݢ%e9݃ٳ琔Gxx6bŊ:G9$u:+y Ze<9z&ev"֭k0ޮݻ?%Ө'/^bQ8;;ӥK߷?vR%W7jJt۳gRJ/;wwjdr_C={6?OOO.^aóSP80-~>|𨢵@o'$qEd2IIIJ.m C;[=q.HbιhH [gfVZЪUK~q/霍?^M.y?ΘAŊ+3gh"yzPj5-\D7v~~̚9//o[0sLzmUVqya͚5O>:B Oo`ݠn%EjmR PAV깹aogꙕWҡ|%s1Νx:4Zx`lsiF<@;&_C^͚5MOz9׮]sΚ<\s 7oWz O~ %((Hzʕݻz2"b+t-(-AjڨE2yl%VyYyiĂ"BչsM7Η,gamKK -=4Yxp%ʗ/)[_a¤2e*QQ-ä#cBiu*L'@4H*j#<-*Zlysc⥬YJoZjڟ7v\;ڵ$!ԒaܠK>>Ljn,:/La@;N9g)uLܙEjFfO8"°aCy;n<Æzjq~mfØ2e*elK:uf)7 bH/gℯ4x6t kkk.\e)+GɤI)]A IDAT\|)ST'Q7aty)*PDDDp*Q  ݺc+X5پ}+/<|++kC {xcǍTT\ ʮLcVv-Xb9K|>@a# r%7\ P(ؾuks9?v* z#ɑX.!#9)][7(; 6oH-NB#,shа!W\СÄ?e<Δ/R)Y`VԒ?TQ>|!(ȄݝEAl)0+b#\C&?ru3g^9MWT25,0/yZ[ s L&$F& G''J 3 Q*U8uoUŁTw,z+Whа Qj5W\lٲf7'+sܜ C^f{C^FT '5hAW B ,0+ =<[@ (E@  ,^ I{kO@ (`:go yY*s!Vk J^D ,$4U٥<wߪ);!C&mAp-dr^~"dǎq= nkKEE9 Ƌ/ֽ[[Phٺ;;#,$ePjak‰5[Gs߳ɕ\ ! ̋p"Y~7>..[J,))9 DڃpsvYX%Dɒ%TRRT)Y8D F8BH9g{os…ߩf͚}ժU+{y\.[ z@\!Z0oǴ3r)1$B6'x9_]/DݻߨI Iڳ'6L$&gӆ|HHOZjg:WkUTdI}}פֿ:EA*Tȱf6{ʟ{OuՍݺe˖?֭[׶ML.fh3h :}x\Z?wڵ/-o2ڹsbbbe$ٳGm۴֮m[ 8л-1NիW/:|X{'OO `L9z.K=iӦk2xP% 0P5kЊJ<|{<-vmjڸqS}#G' ZjZKŴJ3gc6MʅhM:r~;r-\U%Kmv>cz2fiig|z_W|Cos"EB?:uJ;u!%9IGt\WXXXݱqeܞדO SRD_Rr|``ыBi钤^em{sTD I7dݥwvܫQyA7`E] j==TSx| >}9|Xup):_thE׋֭Sz!nZab%k{s)SFG$)<<[fǎ>emۦ}_7mڜ>ݸqc}bw}Y3n5k֪[nٞck׮7t[^u){џN6zh >\֭3 q99/ k„9-g"0)U_@jQ޽#Un}E6}&O*Iz>81NuFiZjzeݙ^WXIe9֡BJY~MzռEK^Z6ӻSl=|LuC>3zB\.u|ԭg}N?6Ч̫&h]z_guiNzSsUf]&U}iZG1cU^zvu?"=$k -gif 1_wM/Lӈ,.>.Or惇 QF|f4V>匠)[ΜIddp*˥3gT.UE䌠)Wvء*$P8nܱgBY0$2(`h۷k˖oѬq\x9+ ]\ ϐ0ZF]p<p VH8K p Z8'93CNT+~C'$ yՏTwmwmpLBbs-pQ'#vn 76-Y.=aHB][zVIi9#hv:W{_"!!*[IR2.<_TO-$4SJ񱃽\,rY1N}G F/$ #L}NW6xض!m FHs76#0Y2E*}JfLWy s(_*>9q56M!Cti>}Z ɴ?-m π0s\*XֲzgC}5J'Oi2MS'OԨQ|ʘ$g#쮂'Cmhien=m%$*WB¯z7`1+zbD9cMQKVX~qʖ)=fɒzWgUTI=CPhh_oT];O3Od7˗)2O}$?҄W'R}ԧ/M0ȍq@^Lt߽?^3Z``N{~A+^&O߼yƎ{I/?>ƍ4u,WrʔL?$_/ԡCV߮r*2RcWXWOIqinM|u&MOOIGy_^d-ܼf q3OS1*Q*Vѣ+VzxM-[*,,LիWW\D}Gٞ366VV$-^Dah%I˗/WǎZN8Yn[`/4nX,1aaajؠƽZh5l@/Z4o,ƍ|߰P"=g3+T: X0uE.D[V3fԇqc5zz$I;w/G<32c8PÞxRJRW(>~F-_re^Z:t Fzy׮tp֏V%1Z~ QbW^\վfϚs+n81N>y1Vn[;w$uYn[c;d{LΝ4d 0PӠCcyg5tؓUl;I!E\~},Yꜧ%K^t=Fk6sMq_v޶m}\աA>Svv]=u]=}w߽wu#g P2ΕݬY3_N$hѢj֬OZ6Z.:ΛݺM[. K۴ʹ` ࢓*S1bhm9#x pܮ2eg<73y uX-n};f}**e B9G. #//h͕p S"6STԐ^G"IZ;̕{4x2mٟķBؤgE iղjYF.jTֱ x֒v< Ðp3؍Up(3CraH85 `EfxgraLy1-g%}F!90$g xV3Y G83CraH8 I*a8RLB#pkHzp Z8 !90!nm>*pڴpbaŵ_ғ3 gei Ц ø`;*8 -g 0 0J ~tL!90̭ Sx1-gƓg 0 `zW ÐpRѳ x gb@0%1 N$$8qI ns1-gf0$ b@$$8HgGks{1 Dra<93 [cZ8 0p=gkCh90$g3 jH8 !90VrfDcH Ðps)Xg"90.#pZ8 pCҧ Ðp3$0ĘmeDraIHv阖3I4RH$gӑMraH8g0җ Ðp3Craav`0ZZ/Z83wQ`p3CraH8(T-=raH8 &!algLB#pϪTPDu7d5C6LBrϓZ~C֭ן̪\P jr:d&Oi)S5tm?zԭ5kWu1 թsURUo:vOdܞS|Gjޢ"+Ge6zwsu}V\%JO?]s\?$5m§\3xf ΂7/%&&n۵k>e[;+~۷TF~ѧĸ8sZ2M~zxOXBɓӞݚM?Cjݺ6nX镗_֢EuT/Rܤɚ:e~ڳ[q_դIf@IFYGWPyBr׬]v4G#駋x6s$顇 _LV/ŴJyԨQ#oG]|bfWdWnR}u5]۾XXWQK֮Qdd,:)ci@ڵҥ_{ тy>Ǥɥ$fl9UwQ?G JHHО=?{3;޽^tE5k#>e4hsxxxۜ';wV֭|m6WsouYC=Ù:s*{njҧLV6;'Xr\@cIqjUz޽zcǎQ+D;vz4sN2xui!zru裉Tn6kի7F׮]4p@_jTѢE 4.?FYG[TP`GkپٲE=֯[kwUhmCGCJk#m9`_?ޭT}u}B={Z4 UzG˯**n=ЃvW .nlEofw5Y[!90A[i90$gZ*R,?J]:~d4b^PAe˖UE,bX*Xdۼ͂sw$åRj\.~uE,bX T5mK<~ڶk'WuqbX" $V[2MwoE,bXlVr6L2$x6M pք&E,b+P:L;odv͉E,bX T` zrvfX"U)-gӔ=WڈE,bX T` $#sk[weSbX"+(Zt2݁r3糉E,bX T` =gsd"E,bX*wHtX"Xچ)w zA,bX"Vb2-'"E,b*V3e$$?1"E,b(V0s;;E,bXLhX"Xta<,*"E,b*V0Y3 ڀ0̀bd,5E,bXU σE,bX T sZeLZdGrt&-MX"U %},ZPʖ;d q2n߮pbX" $V=fm2(p_rok֮ӿoMnwZܾ]ǎGm]T.ʕ WF E,bX*Xrhyjcr騫}s8 ]~խmqaxq-3㒬U=ݬ|La@Na$$ g[ D=gU*#O] t}h{U&M. P)oJ,pq3y grI{VicZ8 $gSLݬ\IHًncvnqtk}$g&=g`3CraHqvI"\gQ*23-Gh3&3gdR཮}0_Wz͜\q]'`fZ**sPR"'OK))--*u\.ŋ(R$MgY$i3-M:}}\R"iJߕL˹M,U&+ժ#-M:yR\TꪀuϹM&[nԫq^Nz0$%tnc5k$k[Hٗ$%%Yw-.s9c.O\\gαvU?&G$ ӧ˯Wg H0D S]B?9 /Tw ѭVd/s^bE+IɨUKСRDUv̲eå+wޑ9#^--Z$K5j6|ǠH"]FzAWٷbJrVnJK.)!<>H1:qwjٵ8ڞ-cܲh}Xv4oNzr8q\|.^+6׵nԼ =u^yO\ Z] \.+;*J޽2jՒ?n%{(\VSKB1S'iG[!m,͚%͙#]vYXyw2vkoSkOkzc }uޚ5[f'ԬiS}"mٸ^=3BK2O[o艡~J-?WۭǾݿrj[3z6]Q?z뼱wUhmA+BɭtaݓXQ2;eDEѽ4e5lX #=v+WN>yu]wKm2MS ]=]]]\+4Vm n:>?-[V'N޽jJ2ͮ\yիů?K"ycn¥7ߴY]ْ͛}=컷 &.[&M&wo76,|ӻh}I>x_ʖ SRSW_jgV}Uo;]VoA oQQZrn3usw:$~D]24ARnlCp-ںUZʞ=[~)9 l~]r%jذL{ޥ{K%JPz ~[_No 1tku=V.ձcTlYo?BBBv+$IvZv6vʻm붜GQ:Q@5JJ:;Lk_2AbNxJʹ|-}EXeKG:q(|~xdQUeŒ}UܔĉJMMMHczoبThuڴո_ё$jo!R%mظ1_>{i̸֭JMMշ[j̸{LNzlwNe4R?1C?o[sC?ޚ݂Nq옌Cv>FhϚ%g5ɓҾ}@fq-8inonJ'3gjԋcdj =wSvNԼy3:O?q-M:5kO=e?^4;O vJGѓGȑ$EFV=wW=&DUW6IMk"?Vq+am;7QEDlޚ! j5!4Ժ}Gm\c݋.]:`Ì6[W9rރ.~|9o'vW%G,Qcs5d֖skK=G^9sksIcFiMr%##޽?عS/[nje0!!V̙ 9#X1'fIV-Yj=I\f/Y94^7BBd+歳|MŊY9_ziĜnmZYiӺ>$&*2zzRa+pϘ̭/^x{]'nsE6عڸ[nI 5.90$g c \dȰV1L+KnYR|33 3pk@cUƁٴp|JdM:*PxGdR9{qJHLTXjѪM^Oi:*Ut|srrCl.s۱MW6KLƀ0JL2BrfQĻ*U~e@LN</WѢEukȐ!?]t´{nIRLL|@[f̘ٳglOIIQt -[LNҲet *555 7mڤ.LSJJkU*S%KW^2 C}ǏW*Uov*Zj׮zK0aBLMMUӦM3~g͚-ZdJVR$IׯWUV-2ahĉU(z(ӓ ,͞=[}$ǧ<|=SYOj޼ ӧ~^xAk֬$mذAG֢Ex!0jܹ2 C]tQbbw_F}֭['+ MlZ|nVI]wݥ Ӓ{~YAڻwoqV>@wy֭[[Sdd$I&2MS'NP"E믿4M5mTLdZj@ȪTwﮢEJʔ)}95rHo^ƍSf2YtիUСCڹs,W^ y|fϞEi̘1>SRRtM7VZ]ve/#G($$D{~nuƟ˖-+Iڹs6lݞ%'=礤$\R'Ov!'OjʕJJJR=4nܸ,饗tm7ŋok͚>}.]ݗ/W_}%4uw˘p'_ݺuSҥ}.]Zݺu￯!CӧݫӧOk޽ztA 2$۷Oz҇~+R ,P޽~o_~ET۶m%~yիWzٳgDZjJ.;xԩJ.+W*,,,SRRt7멧R6RmڴѸqt-(%%ErJ5kLŋuan:p @c&s`qK?Jf:=h߂0A (T^1]c]-%5eKR[5Cݵ|\(Zti.&I~-}|v[ <'%Jjʕy jՊ*UTQU*@b.IG\.$*UT95vT*?i@Va)ðrqx Q*kh90$g&Tb< CBbyO#?%UJ󖛳m ǃTʪeT;z6)dG)U,zU)T֬Zg=ǜmG.Z\w!4,ô mutP~ɧչKWC'h+M IZ}/3 ѣGv>hl'?p\om i[1IxOr]pa`1M7kn~Y1jUGWtλmjtEcun)ӏ^~c5mdUW'MU5ZDժЄISTBEM2%bzvӚSŴ`[ a|/X ̱ܽݧߥ]TJ {K5zZzii6l̒K4SOj{Ejڵ6nѣ+/Za&5KEDz老履xN3gh?W5l{za.mϪUVXzE^#FM۶>͜9SW\q$),Fڴi-3~7N]X]ժUӽǎɓ'&M'Oݻk|9h9O6y}Uvkש_7%UmX^|BCCms<>IErp00Z۟s8p@#yF7l?$נA˕ӱcǼvܩlc}wڵOLӔ9&G!FgHߖq_W7^WKoZZR\N5gh͛i4U0-,,=uvlW fxL~CGkիkj޲U}?.Vݧ^h9Uz*%%E7rk0Ý禳 3 ज़nY3 2m6=P\m?Z׏֚5kѸqc}{9oQӧf1mn{Nh7w^>x=^"9ps`#?ÇA㏻?ĉZ|No5khΜ9JIIVx 6 @ۇ#Ge_ԩo׿wÆ1c܏tJN>իWgϞ&y ӓCi}?ڿ6XRXj5y 4cdzu.G\;G"Ep|EVQ5մY3͜9S{{u_@U}Ϯ.iZG1cU^zvڶiӮfΝ͚+~M?IHL{F;_R]%Juj{D3w--+*\%J[yGӧL ~c&s@p5OEPHYN7rJO.TvYmbpW>EBCt_ 3Jhʖ?< z<q?'MӖ 3ƬJ6I4Tb$$aMGLW}ͭ_$g|>|Q2i9Z~o\.29& r̙4)sYeV*4BBt̙ ֮ iwF9XMRs5lP!!Lۭ;vtH⚶bPG!.18'h=Q"g$gw\sW/͛6vWP(S2*UZUFe[摚oX«aR[nV1G2<4JR)1 ®ZjvWԫEepq0$anmCn:*i sIːLZ4@{FMYI=\Fs`+exƀs6< ϔLele xϙ+hmCiL@LSFn)nt6!JTСFk`C)gYܐk-ߒn%5K -;R`4Z7<^RdqJ~\~K6{[)n1 )9`ts MO>LD,I&IENDB`mathgl-2.4.4/website/udav/udav_arg.png0000644000175000017500000004412213513030041020047 0ustar alastairalastairPNG  IHDRX=CsBIT|d pHYs~tEXtDescription????? ????: udavFw9 IDATxwXTҤ( `%F j57SliFW Fcƚhz3vc;B47l`(Q?VV) <<{ξ̙3GrT GypBQGizZ:6Jp %BT iؐݻwQK}[֭7OT6 %ڲ-RؠVěV&O8EQjhZ   KcUFZ_G-\Pц^xsōhQ(4(9d/h$=#-QgeVATJ#ƒXUV(uv$g)UAb- 22m=bנ.ZZV>B|hu*#Kc[ h4Z ll>{s6̜k_.$t~i2QgfVdfB>܊EN寜S,_ 7wwM'|Z`={ݷOAؽ{w^~Tʽi6m#Fp"48ŒpK%ʬxy&C ח! &5ђnͼ/̌ $%we((#PdR&[XⰱI3tn#ٗPhJ;Z;ڢmRRp֖"fS՝{)) ,3( \13Err2δ駟Gʕ+|u'˛{ҹ'pe222,*(Sݥmv̛u>s&,09-Ehqܗ4ST) JBղxb\%K;oBpl}9 z NԢ `kw [&REPh4nNv:dVgo'„DVKfF7b1dv Q'yhIbcc9Zf۷ZMPP49٥RL]ovZ~wo=TDGG3qR(* |JӦ1ut d .bϞL6?ݧ6o8Ν?Ϣŋ9'˖sTC}LQ G/:>nn<Ӝ?x,(/l))8JwΝ;y]ڬ¹s>mii,\Ci&]DAPTREeso7ogζ& ۨTPRQ*3]999ܻ{;;;23R ~~=+gff`ҭϵFubbb %ϓr.ܮ&'~U)gsvɌ3+̛?ѧ0), MV&n0jhGt<6x] .JsMSǎls} 7)ShX>qW.aogop! Ԕb^f>s&Lǂ޲e cnjdq&Od%;K曯ᓏ?fٶ-7J9󭜿p!Cۯe6\MEa4(Y((ݤMSL&Er'$%Evi((Y 2+;-@pkh߾}4iVKVvUXefZ 999ÇSNZJ+??jשÇyqQ&ѰaC._ę3g?pe6lH&HKM-6PtUK_z'N#"=!558w{<_nɧ'gԨQSn]ZcH '-5uf&7b=_dfXgNXqlrBBѫ7n7& {)3 |0[@vVK-%{,_>y 5k/JxgK:Y3mn{Th};ɤsR%%Vlނۦrhtǽ{8phV ZEM] &쬬Z8K?ཛྷ,233Qg6֡T~kܼyۋrU}Q{{%;;[7oҽ{ݻsMqn$=-|ZF|+1_כ~xm`ԧ˛/q }w)Λus0xyyILL |-so73 9٥4VQ8Թ 7o}79^'+KHKW⼳٬3iԐKV[>Gy33?> ˯x<Lwn:h|^e.,^Ҏ+33)_kϿnhh65jܸyMC5g$##=M7nP[bOV/oonݺe͛7[gZ\pA!|#ǎpE2uݡV[ӌ9{{{VX(j5qqq|sJx^luYXXwI&߬^T*y_,Wb.5>]AVf:.#9)۶ӡÓ&m<hPGMDv.G;6a߅vwOBR*qss?q_'Orp;ʈnP~}^-6#-- GGGk֌ dvIJ4ا3777jZZu]=k3ϐ@?+K3~~;/즕<3ݳGg.nC y.6oBFGzxX^xa tb>x)ӦO'55WWWZn}~â xwǏF͆Y'_w!]ԮM/xR_{W.#zTσA_gV>kSⱨj5k.HIة3in +;n{ؼuG/>B[pu^J:˖_BM:< /d8Sr`,wg3k+.΅74 o\̙Ԩ^O +SMvMJ ;;;l8}4))4ۨqꊫ;(U*499dff|6w@|r4srLO'mRSyoK܈>5\W{w5Ku6hOw )nccc"}NL08TFMZTstBTMZj*ɷoWG:6ja9:9^GG'*9٤Ӡbwpg-},xy :փۊ{m Kƣ Ycs+6 E6Je JU *e j8qaF;~g-qoswޥq&ԩŠLybbp^MRKcxy?TsQyO6y EEA(Vrz.튭ldggs'97oOJJ (gZԩS7WW7bxyg+l`+T8Re)^OKK###C#j,U5N S ( lmQ,|űd 豬{Tv  jV^CCvؙ#GiI`!lϳ#G+sRZ$ }}ڴ{>̙7XSMsXp!z~O?Ͳ+M|-| StܕQcrIt._ѣJĂ1ن cM$&&>gn<ʭpR S'Ѹq#pwsOPo֯]Fk{~& §e+y‹ұkw'lXm;i|[Ч_m([ lAP o~ABqqvf維|#}ᒥ֯]C`Oj%cL,^N;舧C'gOr}c-yxxpb ZlT$} [6˫NX!<Ѣ),Xs?wvYz f9 -kAeٽg/VbN Z3Nã&riLY#OGd"W٣T6 :;wRD7hlf 'x8F͘qٴy lL_0o,H-OOB&鷯YCh#m Rh~Y~=aChm fu&կ/ /&6.ΤW& :ǟ.?=kRy+Kգ{7+v̕W>'*6nԨ{ൻ;_pֆZV7s s1m l1&u0d`V]nU cj,lشw&BѢk Žm_0zH¦L-vg#}-~`f|DkܐX0-֭/tT*PX :t >!AZRݴ6ţMr)N2Fƍ8~Jұ'hڤqߺ53Ǒ%ʧX(<[v,DǨHJ4g.mJϦ{l^^hJ9І¬9s9q$8yY&^Z:x0spq8z8e۷GǑs)trZ>aR>Ă1GVV.'''rTTf4~7L1uf&k&w/>͸c>#7nє]:OPW`b٣;IIIL:ׯ[#F\0ư!ClNW |%:<ٞ =x3$t{))`#RIV͠6 yD ܵQMPإ_a] G*$6*ܝU rc̺=IMM%詾V,(+]veg6⟉ SWoΑʦswv@SdYQUKI>|%A-slULBXMQB12GayҥBXT8BR ‚JAxBQ:&*T9BQXɛBQ]J. !,(jd geI]y.[8Ba ҥBXMZ8y;kOVI3XHgV ܱvJFL;wpUBxxzXDy+ DQԣɻA~\I+PVBJޖ~:I3B9;9sp~:wjq`>\\ g_-6Řu{TX4pE?BԯWk& Wb8Py(NQC *s5+ۂIVBX‘!?!ՙ}Y\!s"n1 yTb[O+-!]d GaqnM~?ƞ+ȢDzQI,T^f4P|a#~=qqױ#5 zvm~6*T [R,dykic=v-c̤NՓÆl6\rŋ1XFAcsק2m:;ǒ ׃{iXir^8qׯҷMLL$$4NzСsWFˉ'i,]J׮]jv+V,㟻wR/OYX1&j&LČSKO.K S'Ѹq#pwsOPo֯]oR6^qzӲAڼÏ xEص;BINN684ӯ?۶GڌmFe+4۶GԷ?۟;v>߃e}PP\ٹm+_툠߾|d> yԮU z{3v(N>]$t<."W/T|NnJ0k*.,=Yh3zlٰ/:b*&D`"geٹd5̚9s_L +e,[93hßg:tFbɢE8;;A=ճG5 ]Ν;ZDbAXسwW2)$rVF%4?F3fx6mB(r4 0 `Y ёZLo_3B'&GGG:1Ĥ[! ɉf:җW1¯5{~gڔ0*cb͛,S̚Y囇czGn|Wtҙ+W2#|OOTtt6nԨ{ൻ;_pֆZV7s s1m l1&u0d`V]GFË$qA:=oIe.$tIM դ2Vd<[\]]wN aǶ/=j$aSmەrsžز~`f|hӦ̞9={zyˊĂqp ^:'oLN:RnZѦM9q{'OvuIF?ax4mҸDeoݚ"өږhfB&Pp,|'f9 租wDvvvnSz6ݻd?@Sʁ6|f͙ˉ;l IDAT'IOOɓ̚3פ<L9=v4;άs>lI===Fzz: |l9-}Чy18y ҈<ń 0cW :BUw/U^yM6SgDIڵ ݋FO3nƍh4Vwҙx'2GIJJbi\~ooo1઄1 g7p:wb/̝O3p~)QQ;8Р~}^x~yYU^I, Ub#!ioZS(¦|w_Yfe(Oi2#%qʚ=͛ӏ? ⟇.,=Yh3zlٰ/:b*&D`"geٹd5̚9s_L +e,[93hßg:tFbɢE8;;A=ճANzp]jתE>>r{$cL,Wh*#Ep2?F3fx6mB(r4 0 `Y ёZLo_3B'&GGG:1Ĥ[! ɉf:җWhn]x|+o@Νyݑ$:H, W^Zl,}Vmҧ_\EvvIe8gߕ^ݻ7_ѵKg\ʌY<շ?Q۸Q"7{1$'}[6k[-ŘK 7x/M.ƘTbccÐkYv4|֭f͚<ӿ3gLcђL*sy%cL,,^?~=Ksq>$P gYՕOvlѣF6ej],?s++!Gƾ?hƇL,rV-[rR+gYX0.<==9}M4ޞM0k LYjyN:RnZѦM9q{'OvuIF?qcOдIͿukgL#GLw_E6+:c_+|?*Q3xp~yIIIdgg6gӽA6o//~4hÇa֜8ytN<ɬ9sMcϙcIKK̚;Æ#cȧ˖ }wOs/%}31,M6cB'OS}L:VETy8&?3f̤v[#Ч7v gs r4RcѵKg J||^ ,Zlt={t'))Squyk6d/D'3wV>͋/+ё&MAX;u4XĂ1Т^?pe<=໯,2ٴUBJ7V^  *:i3f-b2 P1kMv7!kx{{1p^}yPIʆByKz`]+AJQҍUK%Xt6T(ŅTf?!DeMoV ]*!ՔhM㫱XZ匇NԯWt P梁K5GgڴmoEŵX׫WvX(6S uNjj*AO5m'Q!uڕ .Pu Q<|YܴGUKQBb}#.F|jncBQpHdº #M^Bܹ}j.^BTf'ᒮ}.8B+u̹,.ƸsITBa!Ǐ⒑K%!TM G !Dq8TBk0|ԯpPB+Ac!isH#1m#V{jCYBQ\R/3=<=J<(XZX637y?Qط'BK,TB=Zl,;#"ڕ.N.ԫ]hX( =fMӬĂ( Z6BX}cBJ& !FBX6TңBXK%2YXaymſ~?ƞ+ȢDzQI,T^%zZ yeKkНQRؒ`!ϣ_KsuoX4ObxᣥsЯܹs777:wQfX1sߔib…ԫWT=Ʋ+Af,kb-|Yb;:w߿5_}֭MA^ cL,Bٴ~<=OH`ՌU+JLB^ߵNqFFެ_OzMtOVi?2 cO %99"vЫOlQhK lAP o~ABqqvf維|#}ᒥk׮qüҋH$tQQ֖wDEG+p<<{. Va43gbbXXe-,eU A !AZRݴ6ţMr)N2Fƍ8~{ǎi%*քϘG>?oB`kgP:V]%j>()sO?"))ܦlw?m!̚3'OΉ'5gIy <9s8z8iii=vYs2|Py{{9zttrZ>aTi._³~Ƥ+cbWMcB'OW/2T|%\bd_0uLԙԮ]޽xk4ƎapnܸAFSjs,vL||\\ .Pu =J0y~\eg6YDɅz M#P5 ʭ_J 9OSN Y4g"~쬬,>t_@ =>lrXĂivMg=-rXnħLNVVK.^r1XImM|-|Yb;:w߿5_}֭Xx ,]Bz,f͚<zMbAǘX<Ŵ3>V8u*aԪOzʅh S'Ѹq#pwsOPo֯]Fk{~& §e+y‹ұkw'lpm;i|[Ч_m([ lAP o~ABqqvf維|#}ᒥ4#ghӦhӦLo(DW :†Mxstgg:wț#`ş r961kYQ4+klٰ/:b*&D`"geٹd5̚9s_L +e,[93hßg:tFbɢE8;;A=ճAWVT( nb%& cL*ysax^ }M+??5:1jX\(,cbJ*ƮB'c5)SֶrX\Y\] fO?0DEG3>d>#yG# -ZvkX0.<<<j&$$Q \Δ'٩CU*MkS<ڴ)'N>I'ū bFѳGwSLsp_(;}'{()5E"l|eV. X(?r x|B9DEG3mLܳe],Q$*-^ڷkǸ !\ۋ˃ʴLV6$*uGﶩw%J>9/ !,Okp'?[\!L%]*!>Jj!%_D]!%念APU\%55JxNԯWt Po̾jl,iӶ{$:*kԯW UGqPagT_swH] UGqPf'M窥[bj1Vh hc!ȣ~Vל Ga5TBa i!,Mi!,D )te} !%BkAc!t̘i,ҭr 4B+]D]TBy`uR !,)ߠ !,*%c8B+)VA!,`?sKQ%ZQBb`uvr(*RvX(HޓOm_.bcMѮ<<=pqr^=BH,T Bqr+MӬĂ(҃6T!ȊBWȊB3|p$S!r;)ƒ*|LzuLT<1IizJ%Z5pQG2co]c<aWccqD}ʺ(ʡ{r6GcȺQZ,B2FƦSxUmN9J^j5e] cN|՗nwh$?̽S%&&ȟ9 yZ9Q*@C]* McZWSi\U",Z8r5F#2Cՠj"*KUh*U899ZZ]Z"IDATK @~txzxcͰť:={dtΝW^AG[A^&!!Qݥz nFE&My$&&S.xx>|~C۟Z<ےsVg%}5-Z#Kz s>#Yci-4j%K].]ZIٶ+:vRf/ W֣jJ="QGyu gˋӦ,X3s@i~'Ƽ>!!\7__oߙ9s&vc)lL S~]භ7_}WU˗{iԸʞW&37+~\xMǡ'44O>iZ5GfӾ}{} 2gzuy~~s裏hђxg߹dhhKd˗bhmK/~c/)21qWN-Tq5&O'1) Jek5}h:vXOzmP&VR4ا4~_#տ>oЩ3kV䗟}V|hQav ӤqcΝ;G6E{wH=+OOOrrr[tޫVZMII!t$k?|/N}J:hlEU*kkب?># oK6~!/"--g351,OQh%|(@da?NSvJǏ7qclْ~An]X?e|L\7aڲcƭ899=Oǚ ə[cggO W֫mlZO.~KU \wD^kRQXNs?6*%2P-99|t2mWB?fj)6l˗9zI.TnnTAy-ώ1(qϊZxЬ31y_& G*rG)"TJC:ھ`dbKGD pHYs.#.#x?vtIME 7#, 2IDATxy\TfAD4W@AT7]Ps-i-2ͺee]/6Vnnn` " *1Ƞص{zŜsYwA3@`=P;QE0Dvza# wTg ov<$E;: v; v; va{l6ޯLGbfRUV{9*Loٌ>~ }d|S|R< uuqŹg ˻ YAW0?qEe1GG=upd2y 0$86163o6ƍއ ߒI(b3_7Cרvի|6W.-[m7Ne*Cw7WLE>ӯOWv%VsS }pgpp>.FeՊH4֟>у+ Tkh0IPUQ#PP`$4a^pϜ>NL(v`@}-N;qo|ŋޡfbϝ$~.In'G㱣 Mo.fMׯ*$=bCI8;X]݅:座WRL}ɂ6&h[5rSSNq}{K|7 &{hFZӾ} LI~~Av(sgB#I!TE$N8Ʉ 5kVbqp0Sff&>m`'Kh4(tiL.|{ZUUjш`(t899Ppo͞Xv\tdÑ$~}uR~zUBBkl؆(HĎm8^UiMdYƐ%h\|~<_t[Rhh.g=G5BHOO'66 0jժg6~&v]<,a4X` ##6Xس7Pd%QQ]طooT§~JHFQݙL:nhȷرS 6_w ]Joe`;1$ DZn @1M{*n0Eٓ̚PY4 &eS}ѦM{>3`}]4h Ӏ~˻I8PS2$ YK=rQGnZŋi('w d4qzO=ݻwwwb˶Dn#.ncƌ"$$6o`J?E`ƌ"ISe.wVFl&..h$IّK(sgNg֌W'$$жm[:k/Ӧ]7$YF*r`?Y]qZXWR8puV"##QUCVV^VݏO?mVCd j5w8>;}/ Ѿ] \`.7ѩS'>,VX@UQK憕lq?k3.L6MSV5ͦddd7g!7NB릪*cF $a(oG.)cӓż$ʕºvhr%u&~Uœ gرbCOub=xCgŪ͸]Xu9:g[eK2/)6+0dd<<2vXn߾-&ٶTB;򢸷; ?X=};RǪ(.eȐ!Uk6rQ=*ӫGd-E8ԩH0͌=Z-qv>Aa|GwUV!0m(df0dP1uhĮ7b<+VZ\,}zGa4l܆s/dʕo9Ayh1﾿L$IH1ӈ7c0xN*&<<c z%ݻ-GH||ਪJt{vh+!q?9\BX3fw isPų7ǎ<=16iŹs8x𠰖}9UU50z0=ǐGڼi^^^Iݓ^{Ms6e{-UC13n8A#R˳51j|?/3mIR/~99EGhEpr}\2x/+t!$cƌ)(bve"^ݛFA *Ff OϪ AtzKDuv^-̝;W ^gQJ63|qd$Y;9¡CD _ͺ7`ҥ"ܺ}7\ͭCJ_wBIhuMTFM=1O",ˤ;ƓO~UhBM-9>;w.SNd0Ε̫J|"""xܩh(}Iۘ;w.fBUUztȦ]%I7}ݸ6,J)!k=g'cAo HK`o~g^ѽز-&+e47o\@pp0[,V&tpܳ<J 1b̳VI3e,알4.v<Y9(Ǐ+Q䢏$I<1f^Vd&V?0%~umO@p\ƍݥRɲeUusV{V'Kl(BMjNk6!I:=#MoYWw2ƪүO2Y.cHII駟r(n;v׊+wc3H $I;/kɇ( ׮f2oKa]7kKrr2Ǐ\,˜;s &;GNP^.nV[Z@[%b4QU= [Mfc^$YL`pz8h4ƎNVV: &@ޘκư1bR}zEK&عs'̠*II{IKjZa;Zh%I"7  ۸iUa$ITgo+4<WはkmFet:=ս(VvU՛IOAKXSK-/!Æ%?hLvpu`РA梪*Z… K$MF# 4Z 'ik5{:_-OMi}db|̟mUղ98u*zR0Q? 5ZN n^lQݫgg6Q8,W t!#&[DIBӋxQpSvȜ9sXx|j_?kjֱɵ23};BXM&k68 c2Yxo#55ڵ-瓣{GbOus,*OeȌhS^MBCyWy$I̙I#%$Ye{,h|Q-I߯Eՠtӊcz?^ѩbo07oOzz:[nr+= .]axRrG,XĢ ~ycRh4Rχe_-MsW͇6+-όx{"K2ZEQDֲx쐒z F!''ҥK;v%֑hJk2\C6cfI>tNgs~F̜9Ij5xz?0M/\He@ޓTUYD=I{dE%_,j[mڍ6[K!E[vlǏd)ځb[[6JϞ=祋Ka1ݲyf:w,Í޽:Mql22˜kj^TUujӪcCZBٶJރ9rE,Fnn6dNI6k,Ipsf]&O.R 6%nܸ!ƛ~ޤ4lXt\0H%,5f%h"8VZEHCt BdV.r)HQۙD͊e\#+85*((0ri1rJ ? Z7ؾ3ALj1prv%**P]V&]'󪡄<ȿMu_~;ؿ}, A@0k譞5ds)ȨQcز=fZMDdʥ믓q;nL89s` !r <䓤Z}Vp$Q2sLl#+:Yׯ#)zHpX )CU5Ӳug.Cdd$G&/N^[*Wvi٪=?oxdYlذhƍȞǩ˷~/!}>hj՗m񱄄s93Gdh4dϝbuxyyQV-޽;^^^(BBB6lӇ8x:݄W i(*_Ҙq/TSv5n*O+t8::wtKF#32[v4$I\ ׯMOF"7I޿*U, ?2ӹ=KEі#).ƬBP&.Qx`N&-Zw;I8vd?W2hWwL&@Ҵy $I=sԔԮ@6>+*i\G JU4mVPUUd\]R.tLZelhՎ,˥fϮhyX(GYo,t ĝ+m V~oż ժ*;jW RY\5G s.m*AYW^Oֱavav;s;"i'v fe9:tnWt0ԇ&!wnW]OMmKC Yaڮl%Pq+s~1BвUW fb:!oD J c+Qn=i5 qt s=w1vы@tZo#dekrb-q!DkD_yݡv1(j㌶HS:Gޣ#Mu(u8]@B&'m, ÄҪ90=a<{ !z b|u!n^"54 )z-~,Oxv.a[Mͼ}!6i [Ӆ x%v!m!6Z#xb3TBl\#C|s }bc!>Cl9!6Z#(!6}\# bw >C|s-WMoV5Y gM6++fXk[z{`@Bdb4("QjbAj\z2_MdH$TQ{_[I "@(!@"Uc5>LIENDB`mathgl-2.4.4/website/mathgl_emblem.png0000644000175000017500000006003313513030041020114 0ustar alastairalastairPNG  IHDRdÆ bKGD pHYs  tIMEYO IDATxy\U{;ߛf"!@$D(" --?FEmmiDym_iZlp!#dn;ߚ9{R7 ݝ<'uԩᜳ{]ߵ"8>8Kp|r|r|r|r|wZkGP[?kXkY~=?q]+Xx?p_Wpc ~_Vҗģ>ʶmO.]+J?;$aNo|#3gdڵ-o}vM7݄R !jN>|7|ݺu]vݰaݸq{|Ckm^n٬[UVY ;vX;<֬Yvwbd!rp?{կ|k^{ӛʕ+Yp!+Wqi1χ>!^=&crrرcO>yfdd|xxn۶gy߿ڵNNNڑؘ:n~Ǟs9{˖-+V^ث׿n-`?l׼ #S 7`~ioVL&mu䱲O<L({= 4SU!mǢE;w.K.e֬Y̞=!ab۶m޽;wR,C{mo{^ooҗĺu`…G[r-P*xG`ռMob͚5k-6msm~/iss 7dD;^{-rʴ?J .2ưk.V\IWWGR3ڣX>u]%MGGϧ͛Gر 6i&6l-[ؼy3Zټy3sO aiޯ|+s9 1,^0P(p|T*__׼'| _硇brr\.GV/9vm̚5K/O|'2't_|QOsJ6lh,ֺuXlY=ZOJ>W_+ٔN6ⓥKR.IRӎm۶aZ\IM$Z.cӦM̝;N; |>O>[ロr)$iVK.?x'(Ju믧??K_o}[{}{?Xz5{ /䩧`Ν]wGj>5cm۶[p%qVih .!w\}o/W."޿Pp4t$jqrrAhI&TU( !NKVsEHX$Nw뮻.n47T*qײl2ARlO*sib||B7~al`{p9ӟ;ZFWWV//}[288_?Da# s,```a3|kw [֠%>ʛ~d…̟?E1{l,Xֲo>ؼy3{eϞ=֭[ 󙚚BkW_… +Yf ru9{ Y~=}kk֬a``s6g?\.su5-ZɟI!a15k{x/k}(xx;Ǚ(l6{D1p[Tpr ƀ  yG?D7rigzzz馛oK6ZH$(JY?ػw/BS̙37}G}@{te;i_Ϲt֮]ˣ>׾_WLMMqUWM[o>yZzs2{fQϣ7eY7J=_gMZkedttRĬY<ဝ&?tf:@eAJlo,{z R30sL:::1ca7chhxN: k-TL&CooalKG?⬳jv<˿ ?x<y1olgR|r:::;Z.fꡇ"iֲf 8W^e]F2Dk[_\CY/_> .h}[jZ$NJ+O~ŋ9SY`6l(b˖-,X}co?!pNs=S߰sNsW|+Vyvpkf~z}LNNr=뮻䶱ʹ{T!;vB10(1 $(Css$owϽ񆷝뛬ŋyꩧ8I$^|c6n:󴵵HREN8#~~;w}7j?sVX޽{Yv-]v7pZZ֌;f}}s,ZSN_"s_WYd \}C۷/| \9(|w=\uU\uU\}/z1?>_|1z׻k(_j7]XcL?>/+lٲtrMB"jl "n :@@t<3򳗢cP(lٲ xGC1Z5qPC"~A_TVz={H$V@z1! RQ.4g_w? hG=u "E )[)Q%IHx@ꅼgiI&M?>>\6Zƍ7ȫ_jy;#xR吾M&9eE;0("|ߧV"r̙1)¾98*vb…xw{mLŀú{[Bt!VDX@J8W^E%X<Ӝ~針O<)2' ܰʫ_JTW/7]wo{b.[EQT۹袋)%aR*t:8̜99C}S Y8@QP,\ȁ7T:3WDc6##?b!s߁]|l6;_ UVo~ywD*vxxǡ49x/O?iO{,Z>|c dTq,`͓|e|uYd dd2I" Jf쌯7ȥ^Ν;ǽ{8vXk-;wc+l6oR Э>K[Xfz4ݮ+W-3^0 Yf sγO>$N: jn{xtϜAGw7ݴfcU1 FGط?ScƆ87qշnD:|be~THJZ^z)bvr\3mBZrYndN89͏U/L5ƠƒZb&8Zb֘ddpIDkMXGOY]nz{g~sI&$)㻸8Ja\.MNR.ɏMr{W2=] Q*ґ/￟?Ybu8pRJ%t'i64wʃl޼aVZyn{?wO!_Ask?LK RNhUϗ.vͼ푛o`RJqba̙Gϋt&ۣU4rAEUT(B`Dǀ/]NI{ 7j%y'{キx.HUZZرqBP(Htww?kt:]oyʻPax2` ֣aM.֡oÚ(g8bm og^O>|#gHp= QXCT86CXdވ>MXՐ'̻~S]֒w},]6,WUzKFGQ,ݵk'tE"T(hkk˂T:O- T^Wjn͢ Q (lKl":kZƴlwW1/ O>$K.V,`-}0k\$"hCT ( &(DXc0FVÕD*O0Iʳx&{L&իYbE3rLE/ <,'x"J#* `ڵd2JT|>ω'd[/Vς5|Q|ӊ$I(jAe2͖}7o(T5ŵӻMfA"%06~&ELZ((>O233ݵktYc;yߤTq҂i,%@9~[;H%: FT*RZ#U0*V_/9?M(祑cظq#'p4Vf/_N__KH>=k}cbbrB@6m5 z^.8JiU\nkZ]za͚ |o# ! a$4u 75^F.iw>:Ux\L>tN;ľ}SNyNet3< `! c m kU;VXt( k6@ːe3i9IfƖ-[p] ڃ>8◖g铳Qyk IOH)>oI EhkQXG$%ؿlO:߆=ʄn;*Ic48@Xlꥎtӑa?6[k I"!lBEfd2}NC688Ν;;ER~)c){Yz<ys Ɂ "pTj/YW֭#Zԯ5c&Pnu-4oǛcoE:b$( <Ӕ6r5,IϐM.&pF&DD}lIjZZ" 48`@OX/ ^&$[a@JdR`U A6{.&Ʃ+$:[@ιKvt D*!R9LLLi\p+Ơ( 1:V!"T @7(zJ(E))UQ`r$9CPu]f̘᧜k=oA70ސݪԃteaqueH(.AB։'Xƍ'_)zD`RE2qr~˛o2| Y,ܾ};=Qg4Y¶{Y.}ϦV,15"MXɐCPPF)H!\OcCmZkɇPLӹqA- P"Pt4&نCt#l#1yx͛p$7D MC3㢥EHaVV)UJh CZa-: BbAVHp)DK'~KFN6$3|^w 2=r(y!X5r%-XD"LظQHAT .h!3+-A{BTdn"U|HhLIZ!jMR,}!{UMPTeʥKB_8nÚ4]cZi:e- DyBAUH*XDlYՓ<?._5<ϙ58]x?d=@ B@?㠵f׮]GgWTZu+=զl\]+A:%d ys#A T ύWT?Ox7Kk/d@R d=MB>,sp!eQ%B'$lLi:`#XРzjEsF!AH$#ܴA8RIH|Ub$p(\kjȦ,;( V b@2 е,c52i0kF~W@2URIUHT+IT2 J t>ʫjh)S֢h*z8ʼn\b,D4#,ɒIS AaQKTsIyEzg'*laHGQL`5TP&ԆT& (b XʘŒy1(! ."F5b$t\1|%Uu)%< /~WVTϪm2Y-~ZGmu)(MK"Ii @d66(bE%jlx_=(o QX2Ǚ$&i*iRi'`&3!1!y Q$kʁ18qigQA 5%* 8@H MHDh?=T!Gx‹c Q_afxpJ0kn/U$EhB J!HᨐP[ZDX.#lE#'`j[a+\DתDڢXtiB"cJa}[k$6-DJ"J K#4ʓ@MyDdd2C"DޗQ{222¼y^/ @vdy tZZExap0`- BƠhXfH @~3|TI^zHf0|6&Q&u}U;&Fk RAJ"mZ05 Y89Hk2U(mH$R8I70@:@A)ݽ3/;nA"$e5je1֐HDWJ%vmKel *&Q8?BCU/zRxշEj'JaCLd1t zq|/CqaRV-S}I4hu7@Me'S޾߰sv&d'v!J"ĕ.Z, jsIfAI%-RZZ%" \7g9A` *\+bU$p)W4e)6up)bӝ;= +""HR$VDـJ`D 88N;q14IDU:ĚC-uݏ91* V#8ӻ'6e[ͧ{Y%ptrյ[Q?1uc ]ns?0+1ʹJeBAsAwQr~bBQH38,uX5IeU$H]'zqNJ\ʁa5,*\ڡozթ)Ħ-^GM4}w2qSH$I# BI S9HtG8)T H&jUk TM%2N\R)Rw|?iBT8:q#q %PT2(QFԕB4n,R$Ϣ^Uj%qr.TBT*1>> p m-B&%6gύ>h8Eؤ-Q}TlU01[pڦJ\<[ɍ{x IͣPDg?#vZLXx^fܾF5ZF0RGF$ֺxp"EZyt3Hnqf+;)ۈ#4 ¦.A JARDFc*D(ESq*p="@1l@J#J`u],8(!Pؚ YC* <x(u=HqK iWrkj) ä%Ҷ^Csr&rUjzBQnNݑo]@CuhfF`2 L,u D`elLF'6EThW#DkR 30pQx%(AڙOɈ9{]Az$i+lzLZP wўds% &A9i| &A5m2W`'f=:@Zbei$db D |.N}=#2T؈R`8tx1$6|AX!DL? 1&B &.[Fp)U\&)Y*>A٨f"'"vMЙ\QleQ۔Tcݧ2y"S틈+%5\"<P-I3&]R8(O 6UHhC5*V97뢤+k>D" &(dj,8E ) $&u\O  8KywV?hB_B[-Ax칎5{^,:~hxrszYPUgC*쳚*X^T\@%Q3!I\^ ($݉^*5th Q'][nbc1Qm-A 0qbNZ HIu@Ț P0C"G>7ݛ<41:r[1,@ nKiŸ@& IJ`Awûsgwe9a)V(<^ @~b'A'A)I"dc HC\nb-XwTO*+$})4q$Z#q'}J蔏lJ#Y-ٵiX][8 .<g&pRjZ:4D%0oիLeog}xٌ3Ö9msKa5;'w@xfl3qvaĮX[xMVh<'w):"--ZjoT* zܙ؇be7_#$!B-18uƢ4eQD!#9Q.LR& t[/"X$WJОQ}Âᩀ}])tٽI ۄ r} ;硜q40JwN9U,6?i+;z:x+!%,ZETDRĘXM\Rw9Ξ{6g=r6l;wcOqGu fL 46HOO+?CRYtC2i&CA2 F*Z\7I6C5 GuH- Z,碍("mb-2(b=:l콈3%\BHZDTBX|7ŌSLL e!3TuLAAdr'I76f^f B(,qI&S(/l#Jѩ 6`SJ ɇ(?͕uF3 )҉]ej)vmIt& 4O!]+uZ8X [`~._r9_{ZJd\B^1#qC|GUWm_g@BOb q"DQHz@kbX` 7pR I k;x p %7UO ??O]*$E-*c j`&hT5&ШFּ] fw?Evp ,&YjoҧISdP\4*cQjcy*}HrtA?,84U┦QvuUMc#lɱ"J.,u!·~V$ؿp3c du96R]]VpIJ,6vlM}`.3`n_+cjc~$p^Y7ɦ,l̍6چʇm@J1cFym/ T[9zwoGu3Vrl9CNHYV:IDAT"9/5v}E(GC=@8O -X ICd=gd@ XI.PBu4MPYGxbǗuɖ͸lSEJ( 4S8\zl 9ЛwǎHD,Cts϶\DJ`}F`u}FӮ6vҀ~g $gro?CVⵑ4˜;8nl2>}A(gg3ק^U ɂn5Bd52ળrބ$ri~glڼiu-|:ZB*RG_}{lØ31}$.\@0<<ʕ5s%VmYߵu#KHWT d8zT 2]{H=I))@OSIK> K.4@@>fIf٤wuu|xֳWzV(zr=hsYh5=sıT',0\O LM<]˿3AC w~f6~=TME)Yæ*FǪSg0潛o~Yٳyi6•<\WP嬉MEz~E(ug-'^79L1P7R & j[yÕJٲe3_[) BdҐL#%3H"o6²T`iד {IZGfᷠ $ס;q=P4Pd$#*p/N>C6=B(' rl):;;-Z^OΝ;ijj"jpqV\Ů "Log,NQ?R l߾C]ws?dFEG&re=s1q&n'_{i%I&5p13i-5TF41^MW"!RB%TS.Cdd;۩8ƛfXj%cFzy $QidLǵ|ik]<X-5D M=Y]U{v0<:E&eᒑwSQQGm8(*k׮e8ft\9CriZ6rq=2"|`5dK%O;~ dhj:@=4PbOzߊ$B9VL$$aE.zJ~DVi )*Q26&#i5V~4&aY/mmmL:݃|è2bSv71Mp0e(¾}a4؎MMm-߻w7ӧO~TW\qG7S<{eU0d֬YXEp躁A`'FH p/b$TC}z r@A@TV@E jF!'h*B*" Bpqu)\>ve4wL#L2qDlF4rv\9цie8nIR[ΙWTT( >,/|Tx:i(֭cƌ zYVPUA(-Vu*@2g &r>d~vmԬHRvtI.^.(B6>'^ *h5h$kUV(zTme=o[o+WSrsr50k֬FYZ !H&8ٳ)ݻwʅBpP:F.-[0qD***$ qظq#TWW=E-FOQTdEHg\)D`+Q?+$o$E"#)*@VTTV baQ(J5u-Q + ¨~D8޽?ipLټys`xUW'G"2SSQb&o&X\.G8&0uԃݩT !51y۷o=$DEihzL0BV28N4/eMY9Y e]LbB@O)N`qʄRWD$l6.{CYAda a YV!O:g,N6mhoFkȠȆbȺ 4# 1a c?JQ쪘JX~=gyb fΜ(lݺɓ' Xx1_Whmm%Jq9 /—%zzzyyXp!˖-K.|97xb sa;)BFFFڌ,pدy[neҤIGvTWW\xQIE4M% DUضE!űm,3\B7c!]Hdٯ}( @uT-@it=iZA/=yrΎ@.]… Yr%]]]5?O<= 71c(ߵ^{5&Niy,Z 6 r,sc|_en@K6=~z"(B*bҤIdYr㏁"I~ZUUu }1H{{;k֬ӧ.mKSOTA۷m۶ fB!vܹs"Uz?˲_h(wP{o_W$DN2$3z~,VZutvvuVLB[[?}޽B@(*`adY.׭J˘[@[o1~C-i---ǥNW,b̚5cp|piX۷u @OOi˸qz4Minn>nE܏<!_,(.}4T*E0,K,ڶ]f o2mڴ~ʶrxSq#rظq-'tySQU!,+h$kӧOPI+,wş(8J <uپ};v,3zh$P舶RH$8ӏ;m}AoNY`۰a{/{1vڵr-wHRG?z_:;Z{K_TUUq%G!q!w^6*DA,|ܴil'~h8b y衇ׇb폣@iw`nuZu̙3]z<^|E."Fͩ<ôsw裏tw;R;XJwyۮkܸqSN9b]}JqE9#QMwhhh8$CaR$0s{~|3yvCCCe#<ڵkk9k˲X|y{eA2d˖-,\^{ɓ}yl?;v`p ,YQFQ(ؼy3_g֮]i믿̙3yww͛7"N;}v8:n6mD&N;L/ƶmT1cFSN9#9N38ʕ+Y`V>|gŊdÏcZZZسg+W'dܸqlܸ\.=ǡP(pwf)>Gedd;{뮻\.<]>~gygڵz^}C wuXz7OS~FYn> ,Y;vN(bΝ<޽~R?r9.Bwy'ׯl|  \3UV:f!B!&O]wŚ5khiiaƍs9S(e˖~zƏϋ/W\0۷og׿fѢEl߾V(uYtww#Bkk+D vW^y.nFTUNcʕ\Nݻ5kֈwyG,X@!ybΝu]!w饗 qDoohnnBJDP(?gddDtww uEWWx뭷߈u։!!et>B!)Hu։L&#OlڴI$ 81{A֯_~orp|)xX|9?OJ60 L'?#>u]_իWcY} [BfDIENDB`mathgl-2.4.4/website/mk61.png0000644000175000017500000001273013513030041016076 0ustar alastairalastairPNG  IHDRdd pHYs  tIME *#kDXwIDATx\{xT͜s% $\D$BVTfXBQ>BKrU *jjQXE- w$@$Q1 $!$d=9Yjxw<y}7sc b\Ă V,X`ł V,`uH}PJ v㸀~ $QJ)0*++)~,G@YY KUUUT,`QUU4,1L2N?UU;wrtiZ燘aILLt8:1ֽ{X4FKQYT٪g0Yҷ)j}^UڃT٩0K,I9yeUJ^]niv!X욞 SХ_d{- V ӑ20ueLЄ*;:t`) *BB?+40d l]˜ @И6'߉O`A:u9biOF)IW@^Sؒ9L/  ! 5A%`c4K"@ F=:1P nʋJ\NW}E*ZC` L/E !"~$!A,H.em@!,04*2nXPEE1zPJeYӟ!o=`EQYE,$hR0%>>>%,[l:uݺ]mQeÆ 3fpTC6oܞ쪫ZYNGJJ1d˖-yyyfXcLU򶶶pߎNXi Z @Ne#Xccヱ;?N=dZ4j5\PtSE5P49YNUUC JKKگY\.Y4TzY$KH1,kԏwE_>[}kG'VVm% esB mmsһU3X=L*Y,{a{qh#+B%YM.$G.s_|sUJďAϽ6m^«<'T;r~Lɞ៌w<3aB}Uٹϯ!2+7&D2uZNI4'Bׇy݆?T oi?>w~jA]넮6({va/p 9cj@{Juݻwq!!/p)t,^r 2$4KȉIv1j(:t':],QDPEu4UBtюic6,B M10F,¾vqǠ>/"˲f f)yW(: qFV\cMMMWfR\\` YrRZZ-^jU!>Jo߾  [ZZB1Gv&EEE#K\\ܰa>/,,4` yE9b?cłxҜ_D tAyyyοD^gddDKJJjYlfA.;B!-G 1zLm?ϝ.++s9!W5&Y{h?AΜ:9<qϛg<9z<64!{7ٹm3̺!ׯgD1Mαx3{¼%'}qZVQeᇖeuFxM:ksp1}Hf(G`u"!a_XD,D!Dc,;vlzke8Hfeu3sJhڢn}ON6-[_r'{?> &0(ߕ=磢ѹ,PMe(m{Kd$P9۽|K^(HSP,i9wjk_S[wH!L"+Qw j,MeM^~R$3$IZŅPS(b]z ض{nG>TMNi`k w]iO=&y%f7,!L cYNOl3rQ2T2fbL&_3<dYp,Dcnp]KHD/ nsssBBWvj E>ޓwnݺrmƍzO^EEEZZj5sEp8RRRl6[D-g ~Nhl \.%/$xX36Ϥ+,gLb0TP@>xߔ772J O?O?aU5,IVg͙&%5y$_=?GKnOxŽ$O5%`KN!ݭz4t=~ҭ,olf/ܳ,'߶"brZs?=K<1LFnI6YeY*Yьa|j۱.{ȓqgN|0*+`~ 寿'?,v>o.]7 p1ߖgk%+yd矪(It!L'K EWPοv%l!<2)uODD Z9L\\;p1WTT󯤤`/7wC9 7[鋱/>>>R\\l i㋶b&Yb_LPr@t?>|8<?(++$W/ȓ:-KrrrEEoZ8BpӎfNiï>+ZV6#sS֠R͠3,EA'?p]NKGy8t`ϧ{ZӰ{Rʊ0wđwVOk*l/ŰjTy~;=8@2s%`/zwN-f_`EpWtD#:s^gzO?oڄR7eIOj1{m;+U[ +k?9Bikx{')Wݑ3"pǟy9/vJ9\Eb+ڹ2bW_RaDxŀO)99#޿]|ْ$$iֳx}vâ) 5poV$I~H+@c DR*OK+1]j^89rqsF Ŀ+*Kt@ah !QHKә²nv HW,H_(Qv]ƛ/8|/3~֭[oeyӦM婩iƐ0~矟EKKK)!v?a v\.fZR,BsĿXb+X+,zWwǾIENDB`mathgl-2.4.4/website/shiftix.png0000644000175000017500000000526613513030041017004 0ustar alastairalastairPNG  IHDRddpTbKGD pHYs  tIME .5W>"* CIDATxǿX]Ki Z*e_Um,X1T)P+]!V4646bؤPPkB0DB i]۪G{ޙ;.$9ɾog{H)%>22B@!# 2BF@! dBF@!# 2B@! dBF@/Ϳ  ¨~>ɓ|>|>?@vrlvr:Ys?ޏX4np}=ǵCJ@ 9 8 !px?Ns"  xZDX%,_G.@zu 7 3e"tcPH,߅\#7(NdDsAeJ"n蚿h zn(}hf\yS^ pY~CK NjmbXpBu )Փ̵̈́'ԒV ^x8"VfmUQ@8Ѓ H9CZah@*1t^aMr} i0@ĥ"~6 sz} *5P _e kTȱ|ж MM3o ھۆ=*@Z&~̓[1f+ЏWԇg*'1K^aeש)#P׏8;{yf7<<{G%7Δ*`+y8\_{?+b|s=0=:0B<+/P-d@a YAF5,X˵ 8}M Me_^k] n@ƞd - \G2YLzƍiƯ6@'⡧?'c(dj2uBxw;ŧKNQ.1~98Ñ#xI6)%hq[0w\<3ҏJD.B}@mY c0E'{m3'J]n(̺/zY0ѷq'q߬uL\,u㊋]r/9dKٜJqx*I}`pu^S*aF!:ԺŶ’&uVV\B)$*e].U9,- 0t k0yȒ .0*{}{OEpbA~eeTX0x WSWLmӾVJ.8dBwƺ9}o}TX%t ҷf!(DJj݉K Xk `-($:+h1i1/͟91ŸŨœ+(\9q!KvQLRWY@J^ ='n{3V Vs``xqۤ{7mϓ;̛BIx%Q)8w0F>q: Y\*v.i),X}s9,ܳ}s7VO_`>V[ҡ'+e|g 8qJnǪ] %pc񲥐yduY-P*Yʪc\b,^x:8?tlVn} #&C @2Z+GO߁oʱW%aʲd5mF!YPjB :vq CM(lj2P| ^߸D%w8VaC\i{B!\Ɖ|H B/CwW]S7<VՖzZ–Jd%th>.8܉)7A8]ףٙLSe 4XI=×H%vZ!&Ʉvm݉X;u +OL/ێF4&U`"_ЗM'ݏ"~ &X:mG j6P7m0d%t7XeBpyJ's~*ΎK<>q4:aW6k-_ƞ-uzLm)[0ZՊ n&di w8dU .@2Ggs':gu&[]pmt$F.ZZъVLZF/[2B@!# 2BF@! dBF@!# 2B@! dBV#/7߼VIENDB`mathgl-2.4.4/website/classes.png0000644000175000017500000041637613513030041016773 0ustar alastairalastairPNG  IHDRC/bKGD IDATxw|Sw7=E  *S_A@ 8PTDDEΟ" n Ee*2E@E@2l3?I۴Ioz>ȹ{A!l[ld([:[vءt"<<\uԱ4cǎѣhլYc9m߾c&22Rjղ4ÇĉxS\\,jjveooupS (!P*UJIIIVxE\\gi  СC-%ڵӲeU".]JV׌):du *YPtI3fXk Fhgu@|9}%: Py-: X-ާu*V;0% mTz5Sv2'hndNoڂe{ &}J21L- ` $CP@2- ` $CP@2- ` $CP@2- ` $CP@2- ` $CaCZdNM:PX"jB#5gc?>L -L!) :Wt`]5\g%ˑn.MQ;EW#W_Tկ.IrA yv$Wqxn޴^~kѱ*!>^ѱ_QW~"cro pfiir?ӧe ox@*]M~sمJ*HMJ+u</ 8_Y3$$T˖S/U.M DEll,ը!-Y19Y۟/p%9HuQ &۶'k/+5~+{U \G:%~ԲRJtғOJqqҴiVG Tai"{[n1^ZZN?u+~ȁfJK"EPXt\jzf=#YQU{{F*Y gN녻:;Sn[Zj]Ȩ(9uRmf轧UN];uJ iV|yS'^=)&F:q$G͓&L^P4{V&&JI&I#͙#}kۘȁ?l,c[-nAv kDÜKKOJ֗Wʧtz=EYFڽSu6 T^-0PIMڴ׃/߯V;[2|@&ڢy2-WN TN#N#GdԠ4|4b96yru8/UJ5S^ԽO(Iq-  墫m9=5Sw^jFRl-g3IsNf-tϓ/( )];$C }R:՚5=ڸNiQ:C︧DC?ߚ5W_sg~*VO{ӫmi^svm馛*qt(eftOO?o4coVwe>;v<^ܥfjիժr_y%S/'榮{汢~o)LSܦ95蟣Ue-jмUSt雹s%=2*Qޏŗ9]$C.](ўݷ Z0~]T[׮қFKg~9qӮ ݹ߫|~Z8W |Tްoޠ7omBr} COq;᫙qSt >k{-oթ%xA ⺻SيK$Nodni 7$c[$^6n;Yl 3L=[uڵf[3z=Tϸ7E۲l&լYɕ#*7WAL7Qkך`,ژ~YPJrL߫_ȓ=q^{mߚ7w[pi,lt\u /8|~t]znM5k)1;CK1W7CV}A~oɯ9aJINV+҈ 4eش_cFWhZjFI'Rjոu;EDF)"2JMڴװ/yձj)Nu u CTz ;_';o1cj֫(EDz tGKI O>_Smk-80I h3,̹;\cfo6-oX iT颋p8m9?4]T8vI]|I@]{y-YI} Seqy/$;@Jbmϛc=zd]&ڦ#R%;y5?[3sŻ5%Im;ߖy[kck$^)а0UQSvӰ)s\/jj:񿺬5*_JKMѼ +vaڼ;թZrY:5'iɽgoͷs=sr3z.Rޡe&E;Ճp䓢z>؅M.|f-$IG$-WPI~ PXtg|hiI&';7OwVNݛJpMxA /I.܀y?o<ߟ\Fxߎ֥K\)+Y+&A[L9ڒ({u-w[TIv.^ڏ?nFZge[3w5@:W|5oQ}P{K~m U5C)V.0=Wo}CB^swK6x`PKM8ny٨~]ܡ%I&&kdu}MsNiV]Xl:|\X8Ua~%I2-?wtzZ;7Owޔx6^N˖:{r~O?Vb؅?ԯ_11?uRg*&L 9YObOL{n&MƚgΘaڶ}]rkTPZ*$4pϽ۷H^qK럣G܎( $m$I'%QںExlB"PxҒT5n%C""u>s m+#b$5bItYM2Vnx=n-\Q||P;_Z*VS'upn]2BI*UxsZ񽠕9| ݱCrѳ|>կBזDa|Pײ+<ި_ٹ6fapژz>Ru}Zl.["ɴ]oy:7s8Y7&MKuӴ0m^$C!IJMp(5,L[Hx"+;Јd˖qINVn&OD7+))XeYTTΜ֩GUyyΟ<~ɳٳС9-7፺VV"#3޿1ޒ8kc: ~  p8]'9$hпIЯ+ =U**Z~]鯃(-5E֔H߫r]j+my^{WkQ"1VfY #k傯u?}J~]y_U^KK}v[>q\^A=o/x5;_%~}λvm\':MpRu1mG}:U-¹E{D߾fʕGΝf;O?MիK.1SYc JGHK=&I3fd=b+7KIKٳҒ%f֭yk eV]sՅfƌ!!Jf~O['+--UgcZ|$vK3oߵ\RG^S>ס?)5%E))am^fzWOuXc0OVZ! ZRU{G |T+֊s{O};}BBĖs}W7אw&|=?jJM]짟ӡ?齧sۣOj ]^O{uӎuk]y"1}ɇŊ%U<[RWtl^>O^|R.ҬQj֨w^[l9=:b;OSS͖]߾رfujw-+Իצګ:BCrٳNLcǼϩTɔ[LF;Uku{wi&̖ B^|-wl\)SVz~pH=A>6>>+Ϡg(,p8]& j:K5"c:4RWR_T2kL#.Q:^KR:G5r﯏$:6Vç ܯJk($4L1eʪIOϸU^f-4||xJ-PPQF/{zK@*:O-$?׈ t=+)SV!a-_A /o/߯VN]a;-3IҥhˤO>F0e!˪URRFf0lA9Rڷ/0yIj\8[i g17w/o [u]T}V<̩^26;;u4oe)8$DU9վω)SV/:U/+n謊SXDBBTR5>fEb +ȑ{2 J¡tې_PEVxOu9mu2LO*-K*U*s57vS-VdUz-۰ޘpPB{[b;qqqڷo wI5NW7/o3Kڵke˖yg*&GFtc~c 3lE 3aC̒f͚_4~iљ& kcdgϬKꫭz(...sۣO@@3pWh԰7@=ᛩ%I .kiq$@~##9ܦqmLw0Ly޹B 3nT?,C+5%E藞O *8$DW~!~k͓KJNo|,l"=mL3I8m{6z,B;݆k˝k:E%8_Xl jVP|5hcd(,$%H:7xL-:QoCQ*R\H}Pͯr&B~ѣM(K7lut@࠮G}$CaJ>PobT"4^L7Pѡxu (>ژ# K6FYld͝ޗ?d1L15V0<0RR6wbKVz.stI%[  Hld([`5y R!Y- "6WPu&0c<[  Hld([  Bcq~ntcCS3@ b<[g(lđZlar?V[(QIJ^K8shau@ѭ_ou{$'Yd(laUڶvamԋOZ,0v#sr`s ` $Cmr]qT~!FYӦMSZZa„ `s=ڵBtt!{jԨaZjj{18qBWnuHVR%WT)͚5ˣe\rVzHW]ua^cu[RJ-+AÇogyF-[:[R! nݺ:w*T{tV¸qԧOIRϞ=5qD#VZ/\ԤIo 8*'=0y2rH;gVS>~ƍgqD=7ܟ6mcaD믿k.. pF IDATPdGј1cr{7`QD}L2E{~JJ^{5 #~7͛7/DZ!Cs$Cu>>Ȣ{HNN8qvQ2/rڵk5g"|PErA;鹷zKgΜ)4iߟxZZnADիpB 8G2@d+4cǎO?-{=WhnSNeP>Whnׯw(mt}J~kS9wAթSe2T*V={uiѢEOA~PN:ENJRŊw^x02 }zUF^4~xE+YF-[,VM6կ :Bg(}JJ"--MoFˡw(G&ǎӨQO4 6,k2 &;O.~RVZEPP.+488Xݻw3T㣏>RN\o;(iӦZ\9 2D\sMXM8Quuz 6~9O8Q_~2B2Kz;ƍ5m4wy9_tE?VZo1O Whٲe5x`ݻW 3Tzm۶iSN; 2$Op=#ڵk>#8߾}{… .DPPNo]6lЌ3t%-[j_t8GP ӦMӎ;2˔)W^yE{+2eʸ|nhhz۷?\y.%%#d}j׮]=z?| 7hժUZ`Zhs®HS4TCx7PGw֬Yt饗UNV7hӦM֭k^oÖT#G|X|飝;w?VڵU楗^3gjÆ ֭~m%$$x(b pL2E9rvޭ(::[nڲefΜujĈްf-YD=ۧ#FRJ*M6b ]uUzW] DVl۶M˗/Wƍ=^vÆ 5sLOںu7o{,$$D[nU=ZnFRk׮/(sAmٲSHΛ7OWZ<~W G~֭[{?{Z~XXz{t򃂂ԹsgE ` $CP6Wy:|FF!FxPt@# Hld([  XMNM_ߥd׼>L15#G>zhZF[vmٳgk֭Ecիa8w^͛70laϞ=NJJ|`a4qeuVϋnuzǏWr,>ԥKÀ `} Rc?V#G^T)%%%Yqqqڷoa85oܯ(h!jstaVxP@2- P(AAfsu0\֬ 6*VåʕFΜ:BF VnA:Ur8J6^ %)ۥ->֯RRGᅲ|RM:Z*>,-Z$st-H2.)s37E()+/ʗ VNCL_?VG ໲[7D̑>ju։iZ2uCs>9rm-ZHIU<_tuf&0&HZIK^T7$mܘuiRR2Rlԩm[\i eJ11&)1n\{{[^^\b~-! 2fȈ0q7on^Gٲf~U\3s?ؼҥO:*o/[wך5W_zܼ*VOwM<ؑulzkU+KXv]VaCm$)ժ%EDWp^nR4jԶT?F 3ݺb@j><&""!!qr8eYξʱc:?_8/{t9?G_\=^/Gߟ|^qle7*<fk.+޸8;wnvF*j*jvz1??nG|=t߿?З_ڈQQyj0hmモ#""s_r4nP9>υZX;v =CR߾fHi||Ttt;H?uڵB$oӥݥͯq۷Kw)S/:Z5KƏ7C82Ld~f4#zyII[$z]c'}4d %y~-_no/ fkܴĞhz,*%t{Y󺮿ތ":u#M(]yerRR.] ̹{ m" `޳6^au:֢gm1?@ss͹{%s+HOy.=_Q}sz?̜c6EGc~ (E 9rKK3%9^ysE[uݺU9w7zP43ڈُ%$ȱu/ GX9ۅ{ƙo6^FÇ w67ʑW^1igFP (>jϷnm{.W;/MPEkעZ{K˖kwa=k朹~{)8W`3m;x:{`/_V$ԯӧc҅}%ڈ7zMnzHZ5x5jHnF$=3?s?|P2Ĵe}U鐊.ibSyw]RZe:ˉ1%Z7݇·o;Ќ]*s w"¥![xZW/ﱊ w>11﹝;c&xa9o3F_ شɬ8zti,' -pؓ'뗷TU%y~ƚ3g ?]hYkHsE29cmk Z|ys͑#w{1fo ~ mzضmsoooރs'~.⹂W[.rgUkX(Uxs7Vp.hegoڷ7H}cZ5%\7h`O_V$ԯϗN0//8omcڿ_j쒒\s0[f͹ Lاu?YrLq9U_ǎbS E;rg ȝwU:v4 DGK]&}I|&zG5"ڶx"-}̵%m~M2/聜nIޭ_Igާ_˗7W$u ic<gFlZ[n1+J+K:-_eo( $]y);$m,ysΞi-Z$͛gF#լiF4IժoI(cSuߔfu8>loSF|,pxWaXaq܂ʌ 5Ci] ylUX8Y<] 3ŭ[Rԯ-`5;62 WÆf2Ľxn2Pz\zȱ{5ozԺuknݺYv֭w}>c-Xo6l5jd;޽{[vۚ6m!CX,=Cm.Rj\+))0:m߾]ͳ: kzaSSSch͚5:mܸz6`K@C@;w!X@ -f@ p):(9sFJM: ʔ ~,%E: ""(i)-Rœ,=ku*%EFZP<'OJL8HnEbjC: 6njִ: .:u: x@5(iPڼ(\O~@&)zQzcjXv#6WeUjbuHQG֖ 8 }Rٲ?H]&iuڜm7Zj:#+iJ2ujU3429Y>=kO7uhg/ UtҠAIA2(a\0AjJ*]Z*_^&iƬkMZ6sJ:?tYR:`LԢg%=jUi\3ƍ}GUL&N -AE:"M" Ųuus]Yubu]{WQ, H ET B =?If$~=}&;~g|wrt6kV1̯~cc7SMF6eG{ߦjtYJM'm KW^i-[L['/i#utg vͅFPy7L|^"ݾjSu]pTaTtt%ɒd]z, ,o-1Q֏?ʺ))v^kɊ~oqU̹W^_5;.u汅6|xEJsffjShOզjFRSS9>j?l꫕ϛ34ɞ҂믿^nnnxMyͅf7ϵ$kgƊ|_;%Wկ_?/ 6mZ:7(.m-6m!muyvl/Pq}'U^Y);9 d cuic{|vU)RS+3fW>B z6y1kMO\34S'3fN/,ַcH4qUTdn/Tz?2~[l@iix恙= xQ3M2۱MhMB{|ڼѦʆ;ohِO|{켡ڰms}-;~|4<|^"վjSuڵ|; J ewLYnU'S6x,rc]_-+˜Tg.nׯm6_/Go ڭ6Ttmڔ|M_32LY6g_]֭y-3zmmׯiv?oۛEݔm lgk lg}@o ֐zMgٲbbL3)BgίJ_XWN(g(`ӫ4!63jYٯlfUX$5EۥK7@׍Rm*ړT6׼{77=#u:|XZ5p9vRt!c?(-j%uQhsmn0}{iV/6s󦧛0y,Wu?z>XtlD&鷿 Llɒ[<}<9OpB0Gk,*oRܹͫW^m>ޯx}:tܖ a3d03Uflٻv׭kݖ{CQm*ړM=ե~b|٪KHnԿgEGKad_m 'ipBMb+ <9p O!:852W YxiwWV 9g0o}/g6IyyWeȺB=IT_u,Y3.DF}'htJomwR.uK(5>/ bP~jz['u8=CFKʕRvUW 7{n岅 JmV?$nS~׵޽fͤ͛6ϣQ1V!CSng4%EիnaխSo1CN"OPE4fھY&cQDMVy͵9 d;K[ d;k[V;so '|b)33R3P3s۲M .5 ph_@  42g)}T\,m 7KNtvG4' hs@pր}a@#pټng4d' hs@pր}@#Eh$ihwn;:a=E } #hO@p࠭C]Crwx$I:;5X# ]$C,k[9L2Sjs0!dhDW҆@C+YSRq H, , H  4`lKas4d(Ѐu< aHo|~INdhmP0^hX@ @X  , ,h.w$E%:Լ7 dB2hMIR>N`sDdhţRv̞Ƈdh֊ ;IQ" , &RϞvG͖-vGђew@*-Zdw@w)aw@O=%QuoH",:$[gw@OvG4nf8иG" GC;l_<=@vG v` sIox 0@EEEveeei]tQbb4CP6m4` VRII$)11Q]t9𐜜lN'm,H٣m۶Cqqq6FwnwJOOI~~~ߑ1ahX^X9#vjweYAh^z%M2|…=zOZZv%I3f>c#G}TWX}DGGX4qD6G4.uwgff]v6F& , H $CV#IjũAQ" 4`2d8a.-1|f8/ 4>dœ<ƈPa9CoUt$ŵvMh# 4`]&EBA24̵1/ėr 8$C\lsbOeƏPa"lnXDپ g+gGԼSc%Q"r~(Ò]j h|HNhz $Cs Xˡ#YH8@v v` sIoƯhHJ̯hX@ @X  , 3@;0F%;;+Wγ1ٴiS;vo߾6E@rXe륗^Ҕ)SzTNe_=SRRԹsg#۷kj׮!ߘIR.N ?BLzGTffaVVVkdt{dhD_ܐ_?j3/::Z͚5; Q;t<a@G+YrWjb„ 0aaڰaôg jҤ SQrY$Cq/;Qk֬rrr[h]и=ZwyaP(#Gkfw`g(ЀM2q6GH XIQv` sOԙ/ŗ'p 8$C\LCCxc%ad(oQ7pJKKR]tYgiܹA2M7ݤ9s(66V^x:T//4hڴi^ƍz$C\uUTii͛:%E322ԧOuY~,Rnn{z~ťڹTW' @o|,)ڢE WqqqٱcF޽{kժU,tkjYZxE^R`w8!dh٣Տo3=vPg-ZP~/..SO=&MkݶmFmO?-{,Ɩ%Q3"m~ܹSmڴ{ᨔmժ5Z&&&FQtpkǩl(d$D:plRv˓rr4Ν+SR؞={{|ֱt!EFJMc -)}X&RLL/HVҮ]fۻ$6޶lfޓwhMn,-[ R[˖Rޏ]1  ʒv6ΝҞ=Ҏ&c߹SRPO>YV:gϞ]=Ҋ綺6LMs*) P7 JӦI۷KvGcmS륾͚5Nul)$pAA𞧜__N2.Pt9 &đ @~~lDJN6[RMIoTJL53smǛY;B%0lÇMlÇ}LOtVBù`Ru s1,ߏnƯӏNTy 6-Mj NM5βgrr=>L)))u#66νB)K޶n]WNfe͔eΝ܏d('˲,@HÆU$;*iiRVfQ;ӧNC&C,Iڱkw4A1d(j;4..NyyyYn=a&LϾ펤aHNNV| @D'g5H{K={JziϞfXڠg(@v|yŶnYLwo J8PZ9R&1ڣG0yPbE-u11A A;SW9shڴie,KJLrsk~t_1Hة[O?լモN=505F999j֬YΥWhpy0g(@0i|c˗K52s'oX5mT VP ^GΖ22Lt edH%%۹l }Cܹ"1zif +0`^V&a4 s+wڌ G@}pM/MomjVGTTg~&yݻ)"TqqffƚvU8Pj.01(:\ mǩl(d34Yn/-/6yV!uR9T%YZn}ޡ?p#BMEEUHP /KXaڤvAdʤJÆI#FHSH{ ,8gs: rTm\"S7mZ7i1a0;B3hټKJ7V@T8 zV=Cj嗥70σwS$< 2nC+p*z^w9vI%G;V$BhlH7HHaСRbbpC{UѴil,s$KtF3źuƅd(@ !͙SXTsp@wh\\B!Ij.YqX@)fY.OTtƈhJJ\RTTs=r:^n6Xke]+kڵku7|z]~:uײ y?P(fʕ+Mg<3gԪUM2E'OZzj͘1g9c ^kR7 IDATSu|^[nњ5kj|͕+Wj֬Y>땤Ν;{@=cpP^T TZZ?y<e˖O?Zv)3;;l2}g^N=T;pq+l2}^XknذA6l5-ZlРA5fu-]T/Z6x`yM_k~^ˆ Rkٿr@ Аs=*Hs^5I>l*#ܧ=5綮5Mk~fs͇Ox/wM|P;{׌pH;w+п(xA2w MZ7^ĕ'y-$9Lǻfa-V5}n8U皵}~85=Z^!bBN` AyyyJ8j9ic9WPo$CFIK+#yŜ23x{NF6%:@x}J ؈JtE__(d(yTXH/(*Hgi@=\G{bY$5y ǹG5=DgQv8cwHH,zm[鮻rI:x/xonMSYib͌TB24eG ˷_˚5K:̑vͳ;2WK6IWK#r?K?, .l)]u4TTܘE פW_֮~ƍRFԫWpcKLL^{5ЏҚ;չu7ik%s:vN2{Oz]ӓH?oDi8颋f@xb50eA>|s: r۹Szu]-[Jo}vBƾ%¡vGԋfI ˓>$F,~|t9&1:vԤIp;3gh<,Mŋ^BҒ%;Hs皕菕'bb2f͂?B2T~W 6ibzN(c Ԍ) f[fZcJ٢L+4AP h7ޕI/`HL;O:U: z@}r8bK"yJ_KNV\\F&L0=cB_]$C\LC-T ֯^|Qz%i6EF/ؓ&Yf[}miժU7s6=uIDDc>}"H/(-[RGoIC Ť8tmD_;sBZR*wxb$̓G&KwJ3G*^8,}ߺi=UG:҆F*H%uuJ1??_۷<%RAztĺ]WGρbOu;H^"ngykR6`<ˤmՏ~JkFJ=zִhYRCܛ U2Sz{]R^/ `عJut] $'KW\azv!m&PZZ2@?U8ZuHRB SBBB1&e$ߍgI}T<1VZvT-OIVozfo<^>~IJKJ&緤+I]:|~)ޯԦ -}A& }iҷ_-$wP.URV[j3pW~!tuȑfH22>f̰;Soi:ITJV:[y'C%Q&)ڮbt/{̼?6)_Y)iɽR[B̛}ԡ9ηLL KYfΗ9NiPiXw3Bں_zSa,޵~]yf2sfo!8j=&C=RgztxQۑ|K1J饍F@z 駥o}^&):uԤI< @,i|*%ȑR"l柛C}9GtkݿpJ=JRTDYғ?ҹ|!=uTnߧH?"}r]O}bH\Wkk@?"VvONzWvIPj$_'deuԥ& 4P̉zs_H/|%3vq#n(w[E3wGowq#t+JR ]lO?IsҾ}[^z=WfӞ*3G7uE?~d(6,ieąijuR Xn)k[YkxH1TH5ڃw]ؠˇt1+/K_u!gknW ֧N5ʥ&&[3^l&W`KwgQvBl |Dh8Y~;_\Z9EEfޒF2EǏ4PVMfR>Np{/aOe~PR<Tz5~΢Ef_llPCC RDku[Jh{6Kz2^un]X&+/8fՍmtu*0ǴÅf+ nj{׭m7H[w\6Ծ)_A޽gnSX\Jvsm87']sYhiw?,O̖.]{H͛7 tntk ˷_/҉'JSxOvl=' E1j5~gv8sЪ|/ ?^rl轼UU?zIYJ_(;T5Q)IE%UUG]/"?yT>/;ӥ<9:5lp3ͦhk/?dfJ&m+]ylY=C;M/G:|9IfIC76ԝ#R8;V](vϩr.iY6F 1RN.jsxJpN86.|_,uc[rM5k[AR[Kǯ4s햗,K{W}~A&f4M鮻ٳ>}LUs…fuWWI$WPlN顇KͭZpHg-͜)PkAOvjqOM-y.eޓ>\sU_xdw(ۏvP9X>Z-elR~t꣉*_9rDh $BQ=f[ U35~,t]UWI L [͂ ;M\ʕ e9v-)U3E*>;iܳn+ot*k HUd3ơ{b vh3TOHwI%ns; i^ayKR [+Ͽ9F)$M?ɐF#ʦ7x ԿHQA?q9osP>B-yPIъvRR3[oy&;$L;v4?h._8gb{j`<䧟{^zɬ$)99z*4k[CjyS'O֪G|.Nx2.{i$eK|m];JzS)o/?5f?QuITKvt߻8HZ,4Պ˵%`Mq}+%Sg/SIq0һ jשrQNNtEf{37*)^~Yzߩ}$_!|lujdÇFeˤ㥮]矯m|ڶMNv)ʶcQVHKfl1$Y5{ƵP|j?^yz-I&-Cs$FwIJRb=̝pۦHzJ+U4lRJIȶL"{';HjzhGeO=zP\Uh=ByQq~һ 9*ǀGۥN8r~E"e;3モ'OmkʯR áv+<`緊ʭUVDŤxO[)RDͩN2[R9c|'kOwL)!FٷDZefGi])w YRƑ^X6=D}>+ΡBKuN8JCj䫏!芋OzoO?F;*@ d<5_j yI1-9v5Rs]di}>VV? u4JgͩWY6ߨ?-1'N-VZZ~Z$mNj+ VX9ۡ]u7i#!uڵk2oI&A/ѾnsPRج&j(*J0Abibi0#=C?CZ{y.K&Q [:VV[ֺР{}z}!fU㈐N3VݦoZp^8$p^^*~6Fse}Dμ_Lo{3T|^o /Ҫ'OWih6b[LfB&Z[wJTmijj;*Rc]j3ܥ)ojIߵI^~9=A$O98 ZQ\+  ?VQEg]_WMF:t=1t!'>VfJHqQfϒ;:ءթB>"O%y2=jѯ: Zڻr[->dy%e^z]b7]$C²p뫖)/҅Q39 up@[s'|^QQVޯ+I`iO);ocdOGkߩky^{nz?Gzjo~jtH"//_KXD0 K.8ַՐ}H^,VɇվmP\E5RNTpN9 ߹.o;ʥF<ϯɫ$鰗SmP1wKpkڲDYZGe_~ԕ8%{[9'?@D24myD_\_??j3HfؓO .Ȭ> Yr\byMJR\IVu/PHi]2a@}j3d>GVJ۲{ֻu`[mΈ,_.\Qn |:&$)+p$ƽPQgC@P33 m5Dd_Gie.(֏K+n߬h H UX=wnzM_>2 RaKhTgo_ Ԣoڎ92@+ɵidj/kg2itQ˩|`vg48 QMta:]tp[/ gD8N8#<TE$Iq-Y42Ň-XV>K{ӕPbl򽺻6?٩'[PTm*'47WѓҖKj;:Rc gK|VKx3. sEW|K~0+geVdIxڏu^d)5;ѩ'EZG GtR1s0-ɳD(vo~;)& tM'$;z/hy^J,QN޳ϏR&Pw~3=21uBs}$Y1?V/vVO&Xr@˲S*ʶƭ݊mPKw*ͷJC|,~|?_ծ];S*6B IDAT <!][.K͚5;;գ- JeAx:N m`>mRq.鳧?'{/KOnM*)Pf&PB@mZ}d-;u[ >rup[Rf{rOQRE!SBBſ1Ҝ+7i_pP; .0%pڵH"4-i!d(` e]&Pߔ*2ޡN9$d(-ey7R^_ʥsBʕ]wI#yߦ4s2|@X@ (ťZDMW%>M9p"K2.& R ׵փΕV&L"y!M.u"=TXhOcw.GG @=bmTYnzyN{W w{$5Q>=$+ᆞhZ}[(sAvypJ,MTLÙf֮W%TO8Av׿fNQ1xgal2y=VOaF_SQJl'?c=@qh!U|mǩhߊReLJҚ'JTq.uRt>߇=<'=3{n.ҝwDObbw0w'V=ZT{&KQf8݊YM>[Ψ54H$ !S|wJ[?2?ejÚ?>WO)7QzfeU>wtfU_ދzBeI/hlm.^-=|us81 ̬nL#BJ'9rrTr9cHtbbboJ6HЉ?,e/VNRsqV-+í S#\Ä.]L{sRiiEƍҟ$vtՒ` 륛n>ثJԷo_8RTSɜMh)=*9>QgNS_|oİE42[ҷկ_?itZRy-00=E~Zzili޼ʫo"wғOǏ+R 6ğ|R*9fMSZÖָڭڿʭ=]賷fJot8m;pD(7׿^v~o{/}Pzz?]j^.׼uM׼`evNsENH^vk[K]x$e;wwHmzUz{Oli=)5g"{ل}z/ۖ%WRfnyYzgJp.u<ߥK[?.%ڵTm?~H-J?B4'$f+'EW=W:T3ϴ/VO$CpDw!eyr)EF{-+uXeO[R{\sa,95K皇jyMqRvqynv͆8&#C'N҉TmIK-yHs҆\NX}wߕ-3?P~KΒG: [pXGّ|gd( > _jYfz"OquLm]Ed}&C;]R \IV/ٿ~tvo}_N<{GWK?}'jSk.ܹSvi_ڶM5H:y/Ңx/K$][}_slԡI{ٖ->ꔤkzO.l,%X{v4*--Mm۶O;v"]Z6I}7U&i.耲!"T@ATAEdeU,{Lht6ysyOB&=c@PVwl+A@ \uxk118).ſprQ)'}[1bկWHѿ,߶ xZV9B:tt d78y]]]WfC{!>>f?ŊY战ׯ_ԩS6ܨ[fݻw`, E橘:7|kzCRvtww6Ԯ]HLLYͲk׮qii'Ν;IJ= |}5( BCdhjE_{ l\TG8n{ьW=Ϯ/d3 |깱tw WlPyDB=UTiӦ64빸hS(vŵk׸rʃWrIJJBQ,.?~Ǐ?ٙI&#Z5ksuuU{ּVf͚eN%0f4qvvTR(NgJqQ f꺁狜jV*\+&sH4n ׫YKXNoִSBd? /_^\ruGzf+ڍYlYͺ?foVc=f7f2e4Λ7Oܹs5UTnҥKk5͙3G^ʕ,Yf_~E^HHf=1K(Ywf͚Y/ nŋk]pf3gj hѢu-ZYoƌӬo٭+DVVaEQԏoz\]D m~t[Ic֬{xv;ʑkXsȏL&}veҥԩSÇ+3(5jP/t:Ϳ}G~lV4ieFQ)]ҠASNJ~QF)!!!ʊ+G:!lsѤcw8k[Q4 )J׮r℣{)@xx8 .dvd™[wkq'A;G$eS̛ws[Lsc^ϦiO1mLWL%s1L| &ۻe f'>^.q8V :(n{ʺ "(V/oiT  Ǝ޽{5VrO59s LJJ\|٪{Fų\~˅̄II'|2[{ =A}\cb$#,K̲$\ti&F˴0hA.й:m~]VӎBdNQԮ]:Qn4m?Ww'fY)YWqdve4yF;hM(QͲ+rtQi;fB4yˉk{μӣpase$NUoԔe,|457Xۛ>\:sv,,RFO׌IX1_ܞf:'Д\G<IYg/^[Ӏo5Nq ʼy|ڵcY֞ȸhjk(~&3|p AQ0l=ٯe3*1BB/a"h=Btj3tׁB䔆)]H{c!#&΁keYCϞvdN}AI)IN!r¾}߿?;vh/^=zr/rĒ%Kڵ#ٳ'ǏdɒY3(wB:XP9=Ǻd;PUB8^W^nݚhѢ QrelȬI&a7_ŅC&_D:X]QS;K5768,]S@F*v0Bn0uVMH2T!= "8l""D/p񶝬,d` 'D9Xc'Сz?$$k ۔.]D/_DO USv3(_ƕBq'*WdB2q7.mT]4ac;3W=DdFz;sau}Ne/D^IJzxuEor z`%KjէOׯ}Yߧjժ6R_1j(vMF,λ~:{]v?>;+Mw$<pfi"LBQTL.TcEk{dBW%{L xUq>B!Gb!DIVlJdsaD(@|+ӿZrO~F`/g5dI"1c$*D^r[$9r$﷙uhŭd[Eyy嗭k?j+eqqq=cǎlDžg{y}!jJz*?jw=&&PB\:EQPZlYQH6+0JڵyVb|< q-EIOHVIqDa&" 3S|Ygahcz' 0W@w\,#GBN8A~شiUYƍ3giS~}usN 5DveyplL81ͺV\p^7૯pYg!CIƜC&V?g2z*7R`y?Bh@rr2&-C8ꊷ7l'Dlj_mE^[GɦNWt!U.; &X_+`]д19s$BҥK3rH aSСO<9'NdRf̙ʕ+2e ]v͖ aV"J>b/ I 4$t\噥iB~2H!2 .\(>R{g9ֈP?&S݋֖D"}oNz=zU"W^!44bH;C q{=j׮iqwwgܸqٳjWҭ[7:vh5zTGr^g3W_$B1c@VB$CBCbխﲤI ՏpuM)Wz'ua*ݝ+fB!ՋMra *zj͛G%2J/̒ 3 #]fqɉg'Ə/kA3^oT2߳A /0p@~eweذa,ZQB4wx}'|Ƶɜ_Dy;/]ۙwnbG#(%cr.Y=zW_ȷv #կ<ܣKͅN| 5Ƌ<}͹c$D%*JaaatЁ޽{[%B4h={7n#%BAM>)Zh.]Kb ʔ)cQ~4i AhA3@&N4f1J4s+ԵF#36%McL׼X.r^D^lZ51eV"I !5S\ژ l|S꾨^4^þ D0r^*u13WjM9d21~xVի- *DHH۷of͚Y\rL6-KSLɲQ;v$44ZlԩS dٲeYKfN 듬>evQK8BѢs'#^9" 5a:tOKEQذa7&r*VD "X+fytHn|WaAh;vRSΘ5`Azd}!cڵ7|Z L2%Cm[oEhhUY5k(R!rs2\+s+OܨU60k~htuyV7jrThy&>Cu<9,*n;CBtL'ORJ(c"BMDHP}푚IР>.4LFy !r ·~l9lٲ̘1;:wBhKNNfƌ СX IDAT>;wX)RѣG>I*1Fº$}waؾH~s&ʶ1\X.;Bx8|:E>>nz'*/I$C(Z23gH"Ⰹ#&b.!tdh~|:en+6A۲ CvͷZ24]7_#&|䃨"׻x"V*W!!!ԩS="/^̀qqoرc%/bŊ9gB<;W\X?m;mOa CEF„ FJe  |Y 0 [69S"߉h$D(&uNEʓ&_-$ByVll, QFVҥKb ֬Y#P<>0n Oww(R5iӭ' |fa'w8{n^GWAus/TUD6,kVp ܡ/7ަbUYt?3nSg}Ep; ]#\a^a:YCz\Bk׮wܹsz= `xyy9wBӧOӯ_?o3!V]EsɦGcJP.T^OF*7$kf??SjԀ)Se"{(8pڵk?8tׁ{'ۿ:gUY Kְ_YV兼zF|Y z$]ۗzןMݽO_yrUfFv}ű;=IJ=!~/Gmo08xv#5,MBBq9"׬/tw87LV4en͍4$'Ьh!70`/*VgϦYf( g[F>Fm5TD YVyP .js.u| 95!DiYmhb/O3e(Wׯ+~S_yP)V1o[9#_c(f3?˴5Yt8ik6Ӵ]Ь5+@ھUj֡gcfF?ƒ瘶v  yZMx+`0fmX 5%'1W9(Ayo?8˔Uh ٟ̊ LKUPLYOLDj)18K :OMr#lnanU F޽!z@"1L2D+ƍcNW^,?ի=*D~`Jb? G*xYz< N6m]a rHYLFf#%[dQ矿۽5wPL?_L`ɬԮǗ p( _~ŷDI3==ϖ 0!4z=N5*[Q/v6.]ȌPEk>#zE'IܕwMp_:2مPӃ[d03zR9%ml kG%$ȑ0i:2S{B=G孷b˖-Vemڴa֬YTT="ٴiĉu:={믿/ϒB% Jju[ꚹ/:ڟ#\}ePAV:~֮.O?S!D #CZ^oXUny`ܼrɪ.}X$BA@]M7{z^/4-ڶ}K ؍/"9))v^s}L<ܖ~ @%khq_Dy3(]ݷ"TbH7-Gha:D# Uďo˻yR||<Æ VZVТEo~zI B˖-ٿ?#G3o<P3@N4F]i3σ*ݜQN\o X~9kKdL` '3.mYPhqLв靻˪KoSڧ(U1c}UoUvY*UOxz1ύKؾnKCq_*Xw'ucϦ|4w0,TGEXԮk|?3~%KCR^#ԬM`mGѳK}"% iNNe!ZAj׆W ! 6osi:}2n8;!r7777F?[o]~޽{?0{lS! J=D]?271xUSJ]eGAе+̚yXmԯ:in0uV(l]d1c UZ;˷rvuLeV1N&>\K|9#YSJQR^oogryl= O>w' i*l+vA:xU1lt y ë¾} _ YYfl&#s(eseܹ"s"""`?%틸"t:kjӦMZ͞gذa;;SfnOI`3|x DFT8jZ:]K`3f |򉣻!8'Pd2l(݃1DEįdi7-v1iq|ބ/yX++:)nlM֓a8}gBs+aWc@ӓب=T~'ATD8o\mP7kh dugѣՑ)U }9o"2vt"gAqs(PssfꂋwWMd9wWbV+^Z+pyA\Ç cێHT8} ͉]ԣ"#,~>_ 1gђ+R|EoR } ?HVFέ;=o9 ‚|ÓU,ǎA>ZNN0t(|dp B!(@*7RS•ɜ=gǝ%^>PxXXo(dl.WYKN>ͤ^6V/vڏfU/[xb!l)(©3VD޸XNs+ &F+vmfuG# 2AAРC& BsgG"OOu1Q/.V-[BٲEMuuutOxXѽi1(HFfǏq.A]Mu(QwL,bVjq%@L<,ͪDdh.^i.bʇ6`0˔6}xI\n4{ O<59w_ЏC?B`U8(g};liܶ7L*x)Bb\N`IT ~p~]BO|iă1#|4d|,}.j@pqggsӑu %FR9NVm S-\`ݘ<\m_EݖOL~o[Mέ\:};18R\yj5kI}.Zܢg/>v{,䁽DEc6}TZZҠu,yBd՝S j0SLB!B*wuvt IfǯdkyP|B*dݴ⥥b`NiAwd(N^6ki"740P]aCGL!B!($ǭYAue!r'՝mu"\9XƍDB!B(Nܺp'uHvpͲ l..]\ƧdUT h{w^"Er_B!B!xH~ ~#D\נ+oHsV}u+?@fB!B!,I24ިIFE$>^ ~d0-˺wY1}B!BQp\۞L/IO<3B [@^pq?? sLB!B<;FuVW@eQwt"/ILaàU+Dh*P!B!"B=W[sv/!C@/B!B\ bŊ,]w9s:_Blcj[;ޮFܜ ̘1%K:[[&Cԁ I!B!PH{9¢{$Ϟf_k<~x&z a$cB!B S]x yYi3sneddA!P!BLR5Q& 7lqU+{P=̘(5ѹtu͛qzs1^z)(DJ5ń98--(լ|5, Μ5K129Hv8 ]v,B׆9E OI,[8Qv~mz.1hD7(*8qB!HQaqqpڵ?P.lgFDEA&p(о=T ʕ˒ _Uy3%p$}+xwuthJI?nDAəmh, 6P(!<S?onS ˼)3s~u>tܙ\NB!M*O=Cömе@L=77z55Z,^ܲxqhV&K k05qki)ȉM Rz_rD7%syS,B֒)=fЧko!^[:0+ !~ľ \ݚlrᡀQF S> >"EEsQ>ILAL!N0Iаt=<_iSum…Qǎo5y奎n_εJ+X1˗[s >^//0۵}~ch۠bu"45??X9"סO"BMVuFPڃh̪=&6q5]cwss3]T4 >oBpsMGC7+8vY-'8 AOa?qc1(EZ'BS+^BVUu0<@ [>'^} &=ڱS?7B}^} tCs\ ύXM3j_p,*' (1u:=-}A3q31oݼf*6n;fxL@Ng*cjPJͲ9-1[y#k'w|.S1+פl1 l[!rԩЯ }Ч9^~D(WW_s`ji+ fecjVMa]ְ!͛2uݸq0e <<\1=;YgmPwu(u(&LN{:-uQI]ٜ̕ͱk 7}~:r~< 3ס$8u j =Άs7a*ˤ[\5bc~z^:I+I'ǟޟ="845uIn:va"+z4_:mdS'fd$FΊo`LF1i 2MHbF̆dhDv̺5[UjkcN۞hUl+TZm:nOa7UveI1TUUuG ;թ`[{=v:㻡+|>ή~wمuI\dh kPW аI\O#e/8kNi^/L"p h?fZdEV2UsiLoo<N:V._̟ ԩSyFfuS1֭gbf:fnC?;vB[<=!*J]+\9r[kfӄS'?PMԪ#F@:jM L.ٶ7Ցl YA^Y߶#%*q|ޟRcxu g'{x[N,H$m\$cʴr?|q7Gw%GxB] |˯cp肺V24+}@M*nbTu3{06EAy?JcBkgf;TDKu[n2T&M"ޥXO6Vp"8w^z v\rHB^09pv"ӧj=RWPGdvDf=a4ujP" 7 ƹQ{ G$pDLpdNn/;Slzz=hLwΈpsskbb1ܪ$vX4N=k$ ^Ϸ=3?/nt v2r Ҍzb|j߷d{#Ӛ$yE|;u9<#Si\IG"F0ܴ+YcwR^:=^V2SؗEvuBBB,[2@GZ^~"`>9q}B^wi+t* L}]g7F )ۙ(Z{ a2vf6j/hQk0m%%4F s)_38ټ$ ٮ\DJniqdFtzH54]s}_xY6CZ '•l-ۙ(0rim_i [i]:zuM]&^'~IDg|]5opծ:F[vI2;v,w޵8ĉ#!%&[o_R~9/븾 !r~i[OT8yRy֬W#>}|`nS_|Q~玚ٰZv_z,ɘGi 0PZ5=vnusrnhQz!Qk0mE3Mpve2Mp\K2M|2s̱Y6e dsgy!rꗉ-[,[O{BJoUX@ԯ̞ N$>jOU`]6nn&J6.clp0|zGiKk|9|zW}~"yR]84-oMf];T1vRW&@S* Âm-~av~ΆUajbQ;"&BXNxIu7%=|ÝIѠ>.O؟kr挓{|*ddh_1'663fpv-ԮmmD"mݻæMЦ *P.̙&, k/ߔ.:vٲjd0u m'a@Ml]IE''(V ڷW70;V;С0j%mooXL]duKѢ0y2?/E5`^WfxvhAu$NAvF]ɓ?xH"4`ӧЦQ ԭsP(_OX9DMx jO5Z>-`pkhiGAzjL'+jv3^}vpwV5OW^UEOi:}tc%oK(BkNp)n}nϖG^'}#Gwtsk+E!C]T;LJFuĉ)"kTT|m"fMv3r6mjQvi]:Դ*4u%>YJ֤?67;78WVRzH#GA̧~3gqDalho߼sP}4otQyc4pΎ(Bh?JftɈtܰhVh`;OuWwLr퍑Ҽ3764snw:;B5E/U.^rK /uձLUՅ kĈ"xO GKof"#=#F;|_ wh>;ϸ}z|׼bؿ*41R@3x3~A[^ӁEWXcz>b( u!Y :i%gbG̊5nK{[|/3%-ժ%/nl*ED:[|aM#)ttѯʲ$J>r;|?|;9FA*HŽ2>RhC)5c7vkRo⚮ u)&LtUաHk m[ZpԿt޽p?gd~~]Ύp]|O׶ikjJѮ]x%UfoU[--Si j աE.ȑ#/՗PX%'KFI1_7*>vM+&}/$B\5)Z7KEL[=t$@AcMPHO>$UV.\0bb =~\9m+Jq[<++Y#Pu ]ѣGsF6 c%Klw,m-t u9 :KHQQƟ3bƏu-]z=ڴ\܍E܉'4y\O>se,>|pϧNIeyW/7ŋa$Kdh7a]tɴ浇ٳg5q\ GTi{,[GjP;xhm HaGg}fDz7U륗^~ꚆOѭII8. j1ddh6qtkzyy'жm4vX۴hĉڼyyt.\ФI]K/ŋٳ裏(r$vIb)A۶ImJ;wڞҥRjy'@f -=iӦ饗^Ү]4qDUR%GcVVM'NΝ;SOiҤI:{l.E꣏$`[o/YR{% HAԺu4qDUZ5W җ_~UVi߾}:6 ic]7H|֨!ծ-#}YZnspO?_w|2T26I7J\ ; җ_f|ʕҸqŋƍId(t&N.]KޒC$*@AE2 ?ZgåեAc$4! g숏>Ш_ڱ#wc R\P{_O5 ) RL&xׯK}'5h aC U@p4~|ތ,%[ sXgG̅ Ύ'p;u I'}8;E$CH~Q:p 7hL ȽLlTvv\Ó<$C(9Y7.W&?˗ϵrP=;YixS4eg'ؾ}~Ak׮uR4p7}Ӓ*kQ#}l@8p:u0~~ {UV;wfP6y $$$hֵCl$C2p=VZS4d(Bݫ;v}@d( Mk׮y  `"UVTPY :(HؑժP+Cd(٩ ҥK.G 7 Hʕ+٪ ڷoۗ{$CܹsB:vK-$CRrVXq #UV{o w ϕ+WkڵP! aU<<|m&IԛoH Jf8=[6jelm^Sǎr||T7X-wT>a*!$''k>|nj#VZN E4״.9-k֖5IɡcԦ 6#wXo;vbccӵ+VL~`B ]쒯ij~GU^S%J?fEj霙H"ǒ5g >\[l1=dPP` -&٥ڷ4/Sr6I;դ͝k:m'E JԊ+aÆSd#F96Sg|C{vS77 C7XA7K^0W wJ[ңo*꘎:2c޼AIR:}X>Al٨5 _Z|._z/llsut$v],nX>d9m{Lמt9TPWWMWwЁ]1<;h"5GT7XEXS=jΞ<.7ww-uWܢ F%oaÆ9MPPА 51m-nsK=z>uQObӾ~_ڽi>X7UH7xs$'ۻunݤؘȊ$u {Tߔ4g3~R_T]o7m{anRM'ϟe9k$I-ڇf}i4 IDATLwGCZBjrwcG4ϵj.5isLXMܩ>ϾunVrb6^i(~͝:I:8]{ǏF+?u%yʥxE-Snnn6NǏ5m^^*5k˫?kןeMZ=Td}cS^hӘgԡO6.~Hk=6x=67b-W1Pqk霙6)yzyei\Wꫯ͛s4NBB7nKQXBڵsvE1Bcƌqv(dʕ+IujΝe 5T312e3՞pjIj7;qGJ*9]tI~+x^#JJJ9S$Lf굫E{iwU:wdONԖ5K5Wb6=(S5hZu7Uf! nR$G^xgH*^'v:}Xjϖڻu]ؘm~HM=ldZ~F۷g{ 0@$I۶mӟ0zꩧGKot9IRs99"6?;0\|Xl٨ؘmvwd=Ԯ{o-aN~LߔBmV$IGcJ0*[J7oPX,ڳeJR;;IjRP S2b&y:PI SXX,Y~[QQQYWy<EѴiHkС LwW+W$UTI}#Ba? uJu'ubhIYNjzϟ˰⹳ kLϵX, Y)W뎝%IIkUwwA^j9E]hh֭[Hdѣu HNwIN_AGSRuݿO_A;gO^*׬ݛ7.w&hϖ|񂒒u)mZBSGۇhˆ;~3ڹ!Z׮\օ3^Z\yfï7GRnm}䏵=j.9D]ƆA5[+2BCCf͜9S fs:t萦Od瓲*깑Aiߴjo6?/H|4yiݒ?ˤ$Js#?Lykkh=zQs,Kd-oW :v VT j6f7;ct`gi |]}U߾}d;Zn]GyDų@^24޹F|?[ok>*^j5hgï-I*q}4vc 9X%tK6zb:r_JzB4j^*]F/W^ _|^k7wwxntWQ_WܢJ.#wyQzcsd2ըOehfjڵT˖-{!}7@ƨ Mcyܢޛs1k%IUVu5UFM3uU gfsg&̜353Ozh]~ImlVjVm { U}s>G777S={!Ch劍Uxxyg\og]TZuy+&_?5ONzM6ZlVZkѺv횳.|vK6ug6m诿ҼyiӦ wK$C)777uap<@2K  % Hp $C\P.d(@2K  % Hp $C\P.d(@2Kwpelݺ)cdmw p &g'X,JNNܜ=sY,%%%9; l:11QN9됻k}_<=ޠ,9-K1Ţ"> ʜv.K.I~9;.(<<")b gS̜9濉}L8q[n5ϚM?~۶m33Ϙ۷i8sĘ}M9=z;v0SO 3wsܹӴ3 oNKXn,X I_;[nqrT`:+)ڤ\}Ijv"sĜWLNfs3r6<9J9Oeb΋<~9/[liըQK+VH2ō=:7n~'F eBl+sf%=?"{dGl[#;zg=֏?FKz.lÆ 9?wUzIIRQαxt@׮R ǚ77?[z enMjR4ڢy%YyK B^s:ZKi#-hΒ%s6ZqG-.j̘1mEƍhG2EEEiܹϙ1cա(RH#FdxbѨQ!  u1QQQ7o^eP\ǣ>/ŧu9P!J!b2SjeX4r<|}%wF(䒒KKu%%$$xkBRj믿R "d N'ա(*HM6e*jΜ9E2E{X,ꛔCrD@"6oޜPٳgS B >|f̘KQ$22R|m>4pnL@NIKҝg "n͚3gN5k, 2Dϕ@qA-\0[o91 J]HR.t䋸BVjZj&''kĈHaњ={ݶEFFj„ 6ǧLH7sLmڴ)c"lܸqկ__3fК5kj_hh֬Y3gaÆ6mEcǎ͓xD2ڲeZ駟e=rwwwwwW߾}i&͚5&):k,m߾=b"Srr7om۶Maaa&Arww߯-[(22R-[Trr{<&_EGGСCP׮]+ㆆ*44TK,ѐ!Ci&5n8WըQ# 4H_6JgGҴi#i*VXdhT|y]Vy2~hh:tǏ 68; 7ސ I2^z榊+<@naPӸGCzq%xqJpʕ5e;fx2g4%U({OŒ{;dߴ~lf{XodCM' (ڶ5r|#%] %$mF"_sl-)HdfGbt~!gOyJVپoXa;2d(9vLjHT&M`TA?/]f pAڵG%K/Ybש,˗j2D]܋pedfZ$i͚3E2P<iVפF$??X1)0PMki~OgGyx{D )8X3F;86}z5yzܺ ,ISYC2\@޾֨,UJ*[VUڼƹ3fHn'u"8¥Nҥ%__)$HT;3/-*Wf4tBs[,җ_q*%yx؞qQ٪n:w5;_-haҥ׮{^5QW^xA:yҼ#sov[;wl|NRTTN(**UAVquH*I'NIiG0q~R۾]:uʸN֪eYdڲfqJ>3 %reբE ^.m̙I) 8;$.&<<:b gSsY,{X}%c}ɲs,o/WN#Gϲ7(Ǟ~86zto똩3{SOOY~q!CUKg?m?9|cosv3H8zh/Y2krq]v)U^䚩S\7?߼xkH~F_=8ޡ{3f؞7iq<,,-sa|?Ne(O?yƨ*7nUXw[7ѾbTt;rX39Yz5_?iʔǸzܱckj_~)Qa~wVI-[}Q 4qQaefW/svxth).μF٪Uҙ3F?HI{ܭ7*o}mmω3us> 5Nqk{uCķmkv̬kK\cײɓ> $ \P U""ϝkիwn%9ٶ-98.Dʔ1Z7c|1F㇄Ȓdۖdd:Լ۟o ?sd64<(qyeYoe`Y 2[*C(Tk֭F[ʶǛ53/]j^xݨy+cbr2tqu3,y2\/?v뭎ox>p }Z7ӯvcxx5?Ǻ&^ڇ{+z6׭3?g`=߰ݍuH%Uomww7~86}Qz}zs,YR_@ucŗ^Xkd|ʗ7*O5](mdYܪqeKcϭ[c;w*HϑkˢEƳZV RNcgʕmvM؟#5)2Ev팍n$˖59q¼f;|,J˗n޺ۻ9'{zwGD Pkd\[[w_ڸMys$$#ڢqz|vʵzj~k\a… 5rH'VTIg6W^3YeȐ!{-X@FVreb%`s{{͟?_GVJ͚5tΞ={vۆN:m7oƌ9{&}u5FDDƎkjժ9swNl-6l0u4YќAAAa]lƎݻԩSvۆPms&d4gntim#FPo?~ݶի맟~2k׮:sݶ#Gꮻ5jЏ?h:g.]tYmFRMhY{Zݦ+Tnvܑ*UvZ%͚:ցƺ{RvͼbE%vlU:sLkJQaYqoFrүjն(]=3JYXgFײ&z ?vO r8пm3Ke4g5CeyǏYf <|pYV $+YYPsڊ϶mcolЬόeE$m޼Y[VbR鉗']JyqUڤy6Iߍ缔9`Ϋ7|M缐^ܮo,P~s;'9793>!%b$9I'n٘bs&8m@F֕' 6m>hT8N,=|*2#2xVMw'6l0z'dի7^Y5`IzMY,gըT+cvc So7팊2vw?raϝ7"oZVH3%}d]I0_r)erJrP3S yzV·i_RT)~hJYJ? `ΪA*Vՠx6 \g[5HżK%|}M缩rUި:TQèt6LJ=}My^rj@KA#Q,<)EGKg4l-QGamk~zmF"qcccM#nܺh|Iu IDAT8fMc!C_56ڱƦ%Y9闙qr2^NeF7vp,3qZ/Frۋ>wvYRqoH_`TnbK~]cW^s>/\3[2Ymf[AV4uQOƭŊ?$=qg ʕ֮vΝ3ڷ{FK=z5;3nG5H>k$ Ҵi YY MH0nde=~mRn\f4e>9P@'-_n$K||5ھƭ~Wr\9i<#) FfٲF__؁y\inr4;n]gOcNOO#ڥ`=:1k6m*,i|:޽!qa[2JJqH>5S'},i5`p֘m?L|*V+I-[MJsd77r*+S9ٹEQZnEWqxzJ/f|^``sٽHr!q *CyZMԦs5Zji:q)A{ƫJΎ @[0BΒq/y{kԩ -:P}FM7nL`=!/@O>]O΍W8JwJz][<%TRܹ"sΌ@>;+t@ai<1 P:tH-Jy\׸WY%u3&ȱ26 U؁L)4T Wt x\WQ % Hp t }:{\[nmZ 9;6y-cs o1O-[!QFz%%iVuvD@Μ>-KvIRJU=%ѣz7SN|l0@װjv ,ʥBBB"EIcqq(ijr<@2K  % Hp 㣖-[ZR._OR Ύ @;sN;bGtd15iDŋwvX'9y'$~}T)DɒRH$TS=%N:Zv95Hcٜ'R^ڵKuqbDgS^\)mĀQCZN:IQs<@2KtvYz;:~9g\oZm?vۭI U$I1Ondh:gjD/RFM/O/.&m!uswg\Y+9c]k}=I崕dXRCZE(<%ijժ,-={ǜk/.m^쒧nnon$`0Mw,hGxOUjձ;v̿䏵{%%&J:auP|ܳeD.i J px_z/llsut$v],nX>d9m{Lמt9TPWWMWwЁ]1<;h"5GT7XE8%>EۣrswW nRwz@-Z[)Tٓuxn3ud/QR{ t!9*wx.]8{Fe+TTjss]լ?΍tz: 3}A'WO+Ri򖷷C8рJzU*^9#5k&I3%Q~zJRrr^rbRbs"̄ihpc._kd֏}+MQRMxs$'ۻunݤؘيqJ:=ozOH^8sZW.Kե@=p?:^Lɣoa2}Kikۭ|8J1M7[Ԯ{ǹeú`s؁X;sfK@i #=zM2tբu4WbIsmXLۣתMRγboޞ~nk#i+O)9))ޭ4״oy OyxxʻD (A"9rDڹQq钳#pM*Q{*mbJ~ٳ҉ۼ Xb%jՊƜgH'OUJ%KvIKϹod<$%)!!&`z:=_yBo})~yQXY{ng_щ5w$ܙqk$'MAJ58|P?6^g|bhYq3y_i UC'Ӝ?ׂ離YԤ͝v2c5is<ֹYɉڸz5w$=v?˗]vR)777#qN?RԴm{{qԬ-:sGՒ_Jܪ #m?#)ǭonTh iu(h|nNot=KB ܯ?}k:rv`hL6oԵp5o.EG٤t.]M*-(97\߶`Թ|~[˖Z+I5&[P^m_}% lU+i%I"]f?N}Z͋$aCumKwm/wޱvms6h ٫,t}cS^hӘgԡO6.~Hk=6x=6f?/-ʄrss$֨pN;|3M:vqjgΜX`k*[ Y?&Cuﭗ?X^JNJgoe6*+E+mZt}}l\W V8!IzqD+r*tSjƵvGQZf9<)+⟧ ۸^ߟ*hįVڳe\L$Mz$H 4i)iI[IL5̖QgO[I1gYI ײ;IIRv2;?NW.]Ƹr)^g|:o.?$ӧLVO9HRckWoxGYsOltImYJ;6DY-B3E>+ۑؽS-炭/tvp'O})g͚E91"8;#___ͿsN}Nc:tS5ѣPQ2oذafr_uppivڙ^*U2x4 >\ iW^ 4`1u{ywdyk׮iȑ;CvvM;M\i?I1bM [n9rH%%ٯSԾ}{9TpQF3000%C2,Ԯ^6Vd7=]͔t4v6nq4N=!JWɚV͇Rs~j.kV/PG$^𻒓Ԣ}GnNy{kɊ;_#V֨樾=8TG勸wdkWu6Vax_aSׯ_  X~= T*5˵ױAc4 aGb7>r)^0v*@u8rڶW Cccw"$h|ϭwQZy>86X:M\qvYt|\ڬe-Pͱbn^Ǟ+ȦQA4j)/_?V3wOv6v^~BkBADh%8yaok׮BA|}}4*iii*}={6Fsss/z u7V0,}ǡbՏ!/µ"L1ƣ:yYe Kܿcq@'Ckkð`p|5G׮ܿq ;V.ĵz TrK };=^vyslN-Q#ZZ"=%o"p|Cu%C |{_Z u ='g֘Pǽ@oX#p*T1غ8ї/t<}SBqN&eFVVV.ODKfDDD%ڵkk/)) K.ɓJu2Ԧb%|3k>~ N©] жH4m{|w;z;/ Tkneof͗?L ܼ)k(|ǔW[uP\\+H17#u1YZor |[)6CV<]'CW`C[7tL"""""""*2220k,=z4ʖ-[Qqnt̍; e`lZ՝`y'ƛj%&,[>UfV[3XZ{t_W3~ ane д]L^^c wIXO+J4AcQ ̭!H`R,kE!`Qq8U]S}yÝU/cnus}6BdS|R>M~?NYfZJLLŋ0"$J9B"&1h\8)=Q~#cUe/n݂`:u nnn̚,"*|Ʈ玍EJg D߾}={b $&& L۶mǽ{4888">KKK<|kaڵxǯR k(tp;ECs9ոzDe3F萈Judա˖-äI;+X'Odz 1 Cz-1سv%NX"auJ\ZK+YJiii>}zϟ;w.YZHz΄ҙmGG5jqDDDDDDDDDT[qqqy>?))աH7Pi뷣TFF0D6rz %txDDDDDDDDT*4ܹsիBX ~֨ߢaQ)ߪ-< %""""""""ұ ̚5KkFDDDDDDDDDD:vZ<~X_|K0"N/[,\\\Y._Q踈%g`QF01DDDDDDDٳgyaԨQ(["m2gϞELb ǽ:&"*ކ-~߿ut?UVaܸq:N'""""""""ҙ L6Mg͙3o޼YP"""""""""UUh\Rg;&Ct@U9X;L@^B6lHpEY; P""""""""JOOǔ)SԶ7jTjKlR)QcxWLQO0[~=┎7nx"*UzKKK9s/^RRիWXb7b|2LLLP55ǁ넎 YO?l|wDjj*jԨ!tHDD:ŋ^z:""""*R) J"ڵ˗/qIYZZHMM<)*Jq5dffcbFZZҐ,>DX"all $I֪U cƌA.](Q~D"ٳ"HMMaiiuFFFFjj*Kb8p:\p<ذaׯ1c011qJ,899ٳg622¶mېggg$''o}T2]ܾqbMr2ZXuӎO5+Ḱ ܸϞ"#-6Ƴ'LLT^dffbӦM={6n߾6tP Y+uñi&ÇHJJׯ]ErpAl߾OF\\RSSQ|y4mݺuÀ`jjڼ|ϴ=s9؈J D}fff>>`2UoVŚWΆPX~?=dIÂq|ʶ8; ƐکQ|0|<|P SN !11عsRӧOq1;v 3fѿ,Y?~~!44TeǏɓ'cٲe/b2HϽyI[0Bgh3TeUKܿGp@, x4vAD\3 IDATB|UAhT ^$ne;A;10`24?222bٸ{|}}Q\"HLL+]033CBB"##w^_ `24pqqǏQZ5|ر#abbgϞ ¦Mзo_+,ՍT"""P""=|X<} 57¤U`e[^ʶ<nFۡ89YHKE#!>|q~SZZBETfvD1fIII%KpBk< SL)Jڵkpvv޽{QbE+6mǏѩS'l߾]ii;;;١k׮5kS"""B իظ3SlKBED,t]'O&m'_@L&y>17 ݷwwZnZ ģ;~> 3|csm h\tƑ훕΋W"q~YZaJYX`U ]¦1:F_jqCvޏ72fe1}s?$%}pM w^ݻ" 4IW\A`oocccf͚.>)k)Ξ}pq훱gJ 'A Xt 6a@-?v%ܹz _w'pU}ώJǒB1\9AC0x }l[2;V,T8#ؼOG_QЦk/̟S٧c@^nz8+gC1{72Cl=;Pa}{|`j e *t|9&O.ỤGƒ%K۷NBxx8V^_U}8w._r3@ 0l@DD.^O#PR|_7V:S8pѣh"}㏘9s±,_DDDȪ.'N-[kWNl,ۻ;v ]tAZZhDGGcݺu Ss#G۟gDDDDT4NUuGlq!|U /y1Be[!ߠpmχa޷CT)Hc*zC=X,S|<+D_Vk(x~z̈s7ZuO^P?}E} AKT?f6CC~Bss+GcITNWCq'ʶ>#Ơ`mWϝƂ_ӆF 7ߡʶ+gCp7*یMLs*`^1/9E?D7j&p7]]܍eC܃y _Ǡ!(oWw^IcߣؽfRR.!>+4;=KQj5-C[7;kg>tlA]Xb >Fh.zm\&nѨu;}XZCcc-dgf"I=qc; Ƴ6/#k)Wd; H69o2ѸͧrI  !>"_[M甴O1bD }ߒ%K0|p|V.\ܹs]vEtt4 ѣGZj8}:j׮ <~Nš5k8}4cGQPHJ"$Dg*/LMQ8}LP{]cjLHqI1EY5?ΤD)400Qa:bPfn`1;Ol*VʩnzctRc]{!;+K'A#dhUP Ź#ж{9T89Dʊt `Ű}\P*Tv=wzNTzo޼ҥKNB+뺄/___e6mpBt n݂/Vz.\=zСCJZ puuŖ-[?jժ[Ç8sLb|m={VX͚5O?J*ի5&CU9{'CU6m $$v۵kRRRжm[|GUY5 P»z888`РA =~P?oUMPD~?H텎eѥLXkTu1m^ksMԏYSØՏ)e9&ZitOØ"crL;ڏ9KØ4)~LHqƴU?8Z1k7薕$9MØ5)~L-U55^3$H{+'cH2RuE:)Ӳes9S;-=r*=Gaߪ<ްU[@n]{ZY[)oնDZ00TR.9aRsԭt{}qF,_<(P?prrQT7zhc-[ުU+)IN0AφǣGJik޽{aaaS{q///`JМ)^^^:jժs֭[FFd*Vߧn]WNDDD;ɻTelmmѩS'm-ߢE ) cr T*Eǎ!Hm>/W1Cݘ`h;o'Zlv*m4%)вeKXZZl^ʗ/vlZub0ǴQ'h5ikk1+Tr̲ gv+,mԞMCIu5153CrK~ 3 Ws:nDĉ#x|6^'&"++SܪUf˒i) [v53O?|WΆ-;)O&.ރvΏ46vNZacn:MCbsPϩ0a! Uϼ?_S{JJRۭ[5R9XXX !!^R;57^ʕ+7nŋT[o͚5U\2Y% 5 GE|||x?022B>}&QFa̘18q"̙777UVhݺHxNqcH:6V"}C$..Nu~J5jh|_ODT4f~Mj5hZmlذc&$$?qÇ }7FȫFM4z ,꺦Mj=… s?If͚i=fnN?jPYšs ^r퐜OF͆MsO#$$$͛hѢEA۶mUV͇>ۇFΝgoeU۶mCVVv6ѣG۷`R0aƍ'Pjժ>VVDWYYYHOOo۟}.ʆ0rrU`l%&"qmD0׮ BBB_ Q:u*fм&Qa+~`Æw,˕ D"2שZ͋6]{!C8oy24g)c_otؘ{}%w^sqz6ΛDM6kq1S}va;wӧOGdsS\9;tرCqbffDǣZ5p|||tssåKU2~@LL 5j)SI&X"LMM!myyyaϞ=ؼy<i|Ab:t(h#""ǏGdd$ƏHlm˗/cZ=ammgϞ!>>^i/n$o6mN"Ef4AQRwS+m;n%y>:rHiPRݻwsu(QQD(7OnZں]}`UBҙ+6(mVOwLy053G勈{pRD)֬X+;gO@HN,? )OVJ$GѣBCC1uT8q"<{ ՃwۿL֬YሌT tRҥKrJRJYtPP͛7S^u ۷!J xz*/X6mڄbժUd|rX#GԪbW[uEHHBCCѿ煆@]swS2^kj)HXycRJI(>o);z(5.pODTnW"hiG7TkOѼC'=`w^0vlt S\R)-ny046F]p|W Bv"qϻ\0bu>8ZIp?yW|l*]ңhݺ5?PL2'O3f@~t_]swwGxx8͛]*lw͛7G={ntAAAwϟ?ȑ#m6@uߏ駟~wLyebb^zaؼy|y޽U.AP:ɻ%1\]]ѥK߿]vݻagW4Kdxzz"$$ݻʩiii7oãHʯOp1"T&l [Lh/Q90rQ)*4 G_qX#?zƅpz"EhN^>h֮?q2H~oD!a;i)o0,;_"-%o\Î q-.%n]{ɒoˎVyZ{ɹ%VwDYKKAM.P5zHl}дgF-4[}ާgtI޽ӧOsctt4vܩk >-Bhh(O?qi]nnܸ0899aȑD͚5QlY$$$ 22{źuky2Yf E~0o<4lo޼K0sL)P%OLmcmذ!郶mۢN:ƛ7opUL>иqck6n C `mml<}عs tŋ#22mڴԩS\&&&̙3*UOgcZ]c M~0A-o#4Zڴt: "=xd(?"+CCCBsD"~kSNM~YYSp>$Ga@omۣD,ŽTSs+k :=n\ǴPARKՎs9lmOek"TOof>mcms#3K+L[u^c-iRj5 2 MuP8׍4=٦k\c=zSLsr׮]su*ѷo<]9*H{``  l?UVŋ3$M4 ?qs{.r;';;UVEllAI;;;<|P55imllpQ_7[K.Uz{yxzzUrػw/6}|tgϞןjHTGЏ: $|t d(l~i@m۶q=#F,+\Q/o| H$JTJSePGQ~ٱ_prMeR)vڅӧ*qrr˗&WؕB쌰0!Ul7=H~\ 9MƛJDH}&P,Oy)Y!JDDO2?5Nbu(oG=P= `fam0i:J:ܹs8r7oӧk84лwoT^ưFI w33"؈2=b#<]ꒌ ;zUߪ%~֨߂kEо}{߈BÆ дo۷: " eu1M4SֻoqyY>d^3"""_zUi&=uRRRt X>}D(sjSMEbnz"1`D(ћdOIRtI.WjۍmdL,q IDATo{Dbz/#F{#6;TTRK@ODDTRdhVV֮]+/H䕠022p;7nDff&{[ĉHLLyDDDDDTp&39rvmr e P)&00DDD%UM ;;[X y!55UڡDDDDDŗ?B$- /Aඤ ^JJR uPNR~͛7v(Q14Ƞ} dir?812 >YP<+K@zzzADDDDD|Ig& #YpiZ\[)PڣDDDDDT 8E>d) ><{=6=E~R %"""""**, ;CttqOFAN/ "KZKKZ %`k{P"""""I%edr g~G2r<~ it [ܺ$%鲶 `رCh01JDDDDD% ZVgd)BEn) @j.@Zb24) WTW^ۉHRQQ꽌PSC\Z rd Nssv;;W׮Y0qQ`e(['SҼ"H_rzY她9`cxz/;wVU+pCCww 03ի͋'ǁ*U@D*V4y"ҎDDDDDDxp8'yx\ɜJ?z4d}SpY_Ν%Lr߶mۑ#eX"""&CX:m#"CO[ʂE᯿: ".t&aRߟO R,V plyt40l,iZp<{@@hѻ?ۙ L88'`wcG]& >㮀坯bM`B[7َUd=z)j [_lÇ3cmlDDT:1JDDDDDT|mL4dyW #ص `|eKZncb$G'LP^T$Ə%Q+٭sԭAuoؖvA #C "-1JDłD"aDQVLC)!P1j1SpgwrfGGGc=%E[FT&@B,)jmI tD %bo޼: "c9DDEδcL6F|aI.>dmŊפjUY2ME |X$ + HOԟ.5s""DDDDDDlobैϸ#t803xfKmv߿_}2X[Ϟ#Ž;Z*>dPvvvB@Dd(Qq L͚@x8:zI5 /VFԮT[u!!@h(пBCeNNE|||0c "=':"""""""wwySץR }]ϟ]O<μ 4H1JDDDDDD>\6U>4m!N֮ߍeUNN?'NOD=A{~zue_KSȾ JVQ|uka "P""""""*6>\6#F7nC)澾BGHDD%QqK3e;iDDDDDDTlлlmPcc &M::""*XJDDDDDDF/""P""""""""" L^`2DDDDDDDDD %"""""""""d(&CH/0JDDDDDDDDDzP""""""""" L^`2DDDDDDDDD %"""""""""d(&CH/0JDDDDDDDDDzP""""""""" L^`2`] ދBG@DP"""""bhJ# ""*}8MDDDDDDDDD8MH`qqqsnݺ[nJ*\t j={, TI7 ,,Le/F-22C Q;fXXb՟1*ۆ Çlx"t .`Сj H$R6|pDDDl:t~ϟ?aÆS]9^pAe۰a>jX5~~~xʶÇ}}}6fFF նf;vTZ&* P""""!"((ǎC\\B[޽d?^m?RTm[ttk;wK.j{15uk=<<|'O1% :fRR$10t;v+5^SZX[[YfBADDTq<vލ-[(%BYH_ݼy׮]ŋJ*W^ػw/233J8V O?ŶmT 533CӦMn78::ŋ*4MU,/_Ԥf͚HLLTVrB3))Ie[a>d[eh͚5|iaanR]va׮]5j,Yz""""MDRM􄁁8""""*nܸTPAe{tt4j֬5j]vW֭ '''Fzʼn'~ mVȈtK,+,=\d( %"""IJJ´iӰtR3S{GPj"~:v܉M6͛ݻw5V&L PP"""ҍ[ᅲo,cffQgϞi܄+;;;)DDDϿ ͛7ꫯ0`zj##*7o1&M?(¨$b2^xlܸQx2eq 2d.]!C[VDDDDL5իpK.?"#7nĎ;7o WWW}!Q0:""" ++K!ZV-!faag")) pu#"""P""""HKKwtt0"* իW;&&FH2@J $''Z萈/_^D#!""d(Z&L@FFa@дiSàD,*T8 =='N: BG4ssssdϟ͛t:t: * Rk H4nܘP*222pB *4M4)V7o ++ D ڵkA-T`\3R2eJHMM0"""* %"""""4j(S~Dh(0JzgϞXfaQ! QxCKT:j ASvmԮ][0 ͮ]Qi]Y(a2􂑑lll JJ:.IT s#҈P""""/^?,wߡe˖FDDDDDDd(XرC~O>L2MDDDDDDDDD8Mґ#Gp…wQU_d$ @E@EUQ@VAkjVmԟ;TVAVe 슀N62f,s'I&q]g"ɝ9j0"jJHpB\ s&/"""""""""*CEDDDkGy<>>އшHUP2TDDDyw}T! ZAP4L^DDDDDj&MpM7VDDD)*"""""ҤI4iH_}HP 557oޜF$"""""M""""Mرk[jCJd J=2: S.:||FP2vk{шX#`ѝ|ISRTHƧ.Y:n 3 -|i;FVAu,\;47-]IQs&AޞΡK -D,k̼ /i5yRмR޶q?ڮzFN(?Y?BˑlXr]m쟝e 1зHrqqVE&99 &СCׯOpp0 4n7$==2D[D;4k]p, fyp`NoMg,W"ŽD4m pKI3=󾍼ZV) @x'KK9RhXʱO;2ysj `4 AC v;[_ߤ9Em{}Y%"blY Fxp`}yn"bN"TƌüyJ;}4k׮eڵ%))QJUYf  ++A駟밪D~md- vOonvΝ;zymf6]L$h`BpLNÀun.f=9@R7x _ipl4wX< wB ҏ1-b+[hY>Na`6s& s@"R!*ir73oT*۪U4hYYY >? }V ZX`00Am)]uhaY$XP)@0׍ !8O*E~b 6ۃ&<|qB=W}f$FS eNK-[hſQ"R= m _|WOicl>w ;vCbTZD|܌ҥ ҿRRR\~'t֍uE~=^ƍۗh"""ԩ^Nll,-*-~̞=k}'OK.DGGcZiРwu ,0VXWXA~+ Yf$&&rkb"/^b]vΝ;yh֬!!!ѲeKF͆ LϫV\"!!3fU"Ԟ>-0U;C /-=]K7`QX<ZX#`aK7 c.ե *%UрhUpi)YF Ƙ.x"RcY^UPWxNtHO[7[_?(ƍз/DGzvݨ2ǹe1hd$,ZT2ZXFpq%?ThEj &[oymҥlذd{=^}"-[Ɩ-[HII*7w9s0bKl۶m۶}2cqW|:x,_˗3a|M{9LR#G_|mۈv9r$'Of֬Y 05gΜ @BBBc]v-wuW8DUm?VJS]CCCt΄˶s IDAT Pҥa$' b(-3))sPŶmVn(y5+MGg̀_OHGV{뭷7n{!##OZZ ^Gu_nqqq={_~??ngݻ޽{6lNc\~=/ҥ IIIܹ طo/L6+V?eˆ 8wNbƌԫWCYX,-ZDFF"HOOgѢEX, ='։'bٸ;زe l6>̇~H+Vcǎ_$BmkyWjqB\P zlrg=lrk֗&8ᜁu灂ǏQtHJĨ0/4N'E8mLbs)$o=P6v/⯅ҏEO=ٺukz| ނq`c덕`x5#ܿnٳF"tpػl6q0(G7 AeOX\| uȑ#A*AM3fLey78p g̘1L>ݵG C4hz=..8xi_;4h6{2MP`,_%pPP`hD킃Lu,ĸ#2P aO< yeY]por65%gᏔ -p̛uJ2a„unݺIJ$, 'N,2iiiDF6Y 2cDzuVc}YcqF9sfdsȑ#+%ƍs!>|Һ2$''94ܑ̓d,P|o_6g=6nݗuμ[M۹H|R6o`+(_|IdSm~Z6/*ی-ysCGĤͩ٬%^;Zt&`ny-y'nfY9?ɡh PrٕvJ|ey8.F`$Ub>#j~[ӥߚ?4{:XdoVNm©myLtkzW29M}j:ɭyz}A0y_>oݷyӡI[X[60jykw&mN cy~}!Cc39}7M q<95M gr&Ťɡ\Y͠0 #fL&gwo㳡[6XC39xZ>'H{\ছDn(Ҝ IJ jĉF", GryObjiDʪ&kkjVVV}}n3{ݓwzz;у `Z]#p)[lFp>Yz5'Ot~I֬YCpp0{o:~x&OW\x/pndX|k|s,41s"Km a^j/$g.pm~R:໗;څ[RpvasJ/q\ћ!v^Ƙ_J ؂co;qk2c~œ?˟X>Ń*e!zmתmt(ԍM7nfݥrt\Iв$6]:'Eܔ &/D1V|/m%xwWs`m۶-&MbÆ >}/>TXy;$??9s^={6u]TJ&LwߥEd?ӫW/5j+RdA[oeńb  6^5>OqEʙ)RNQ-,<7Y}9,#pظR닱s-xͰ#@[`|1g~NY4.xt;fR?*m: ؊OÒzN?a[uʺsR9Q8g]ظ"Rn vuӟ㈤2o#?PAjj*'Ok)pz;Xd .ǒO?4G}OoaÆaXj9r$ .d̙<!GG$''m6K;&Nb}Vn 0h V^M~Xd ujW _ǎiٜ^ ;߱q` 7DXk02 6O 4D&mC [JW kn"וg}D\՘C@;>cQt99d*b&e 7<B9׹,z;-,x(S+;t 1ay[w Xm|:w6<ޏs/{`lJ6` tmq_0Ҳatks-&mvfrx0W0iyQ >suOm6h@soLڼCfx6|30؋6Om3%% pVy@jHM'M7rtv 9M>ٵd-u뭷ָiL2EšO_ܹ3,\Υ Yh 3,~5nJ.]e\y[q111\p~bEw/SLMÆ IKK8ZlITT'O,Qy[X̘1QFފ+9e9q˗/fѣG.]JD |c͚5>*1Wmy|W0~ۚ=[ls=3gC-5~Z˗rPu3:͙E~Q!Y$1Mrb3XO_vDf煇); ĥvכkv8f3 c ҘM Q[Xsoo{.,o/tWc.:Wm۪Uo]ϟz*Vr㏋,ܹz5v<>֖wΐl$#tXҪ5frqHHIҖ'9rڶ5ʯ_9Z@^|E?.J*X,5j$a 7QEsW^yDp/;wf;wAZ]zYziI?_昼=Ϊ!C*bu?|nupw2o>(1bڵd,U2^@nZjF w:1R50hf_y} nrTUt(YA`ퟠIdnt)$%] <$iYm""sѽ{wիG`` p L8]vP'֭[ݻ7ϟuXVYTաUVKD(ӪR/ᕠV+bT>'] | ܍1?g##if")-@"p[g]C Sd")}37稈aWp\ +Vo Ƶ :ذDT}9JЫݻroذ2_өst٫c:tn߬mob__|mۖmū6̮S½#isCYe Dr9gԨnT\̟!!0mHE^>}Xx1ǎ#''{3g3fC BIѝaY)ӊ.]LZIZ-~'b,d$RAu,]C6L]t]jš4iM7̦ڣOXػ~ؘO40խ_pLL4za"~jժU2{ʔ)i2G$Rs5D^BKo89vCjRA uUz0RPT"ka4OSI4ieVDjU:2`l"RէZf C !>>bbbݻ7-gux"5RAYA$ef^@z_ pa$"0ؘSB3[ 1 -uD>^zѫW/_!◌hq{;Wt(9<Pjƙh9 0QHMҫR2TDDmԟlڴ~ϙ3C_7>ʂTGp zHYP)IEDDDDDDDDVP2TDDDDDDDDDj%CEDDDDDDDDVP2TDDDDDjD,kuH"""RŔ ZAP|Hups9pF#"""""UAPj0DDDDD i JHa"""""R+%&&2x`PF#""""""""R+nݚ֭[: 4L^DDDDDDDDDjU۷oO>I׮]}T6%CEDDD'N0w\{WP?a"""""""""R+(*"""""""""ɋHj*[z ÈDDD)*ƍ4h*t_ RIMwpB\ s[B23}#%CV8~8Ǐu"""C&""͛}HdϤI\[nhDۨz}ZHP[111dgg: 񑐐_ 5LVx饗|b!::aTfa7ìIBmDBHH|%Co8q![:u8[bG9[27AtC())*RCeСCDZ u"""""RDt< `,2};UeӺd#.1U[ѪU+zzTgq8_ku%-- JNN#_yjC%aB\DDĿsqLԧ XsWat,2O("""a""""@jj*t=o޼9111>HĿ*ЫAof?ɡV:<JT3tHSi&:vVZDZLuE oOgSI?JQ);%CEDDDDs7yph~. z+)*"""ed\v-+r3) du֯ +"""^P2TDDDDD.fZ*|l{c$-J9%CEDDDD䲳Br}zmj6JO&&&bX\[fff#"""Փ"""""7Ԍ5BLr32G^^^DDD@)Uj3,4ցD$ߑM#EDDď)*"""~;w<<<܇ш\I͠0 WHL@[@FEDDQ2TDDDZ: Z%:dh5>㨝edLVqGEDDDDgb[˾G4Scd6'e_u*XRbb"v= EDDS2TDDDDD|&dP[ o!?Ҿs9FB*v֭iݺu!"""5ɋĴ.%h@Ml/1_Զ""""(*"""l߾C! u+KUNM*Rԑga;CEDD{J'N`ܹѣIV /uK"BUu|6薗2O9Nա"""=%CEDDDDħbaBVY:X#,5wf8,"""Pn@=B"cZ[qj;DDDl ieT{<4U9ݘUVߺ?SX4gJO*h>sUhe[p!III牉J9+ 2'zU*"""R 4iy֭}H-ckVNE9\!6ʬHIJZ⥗^u"RN96!kr S IDAT*K#:,f4L^DDDDDjG5 "U"""D~~>j&/"""""~ D]D ġ0y 557oޜF$"a p:IgC'!H5di&z>gÈD[rWX#44^DDDR2TVNlCD|dԩa[VV]tu"UcUv}%B6Zd >2O<?ÐNP[;wT2T;CΝ;}HZA?^k'Ou*ZPIDDRe 1114kaHJOO/ߩ4u"=~\Kl||$׾ }Hj"#}Hlgd }9D֬YC޽}H $zH囦|l h|H8-[: 7&/"""""~/?N}z~a>MÈDDD nvΝ;DGZ_u |rs0F%"""""""+[ĸ`_$",U Zb_Uc0EDDj %CEDDDDh5"kZ]CwF$""""""""R{Xamntvf3|\.Z>QDDDDDj:ny}v{DsG,BCCK9SDDDj:%CEDDDD֩>}\F&/"""""""""*CEDDD۷_ZD'k׮>HDDDDD*""""';wޫdH- }T2 )pz{> djT&GGDDD*""""""/X1"̟9EyJDDD*ɋHj*[IBZԶ|M?*DdJHpB\1-#3qGQHe0y qB41K󇊈 UL4u>FD|!ؔdc8?&% ZjK/0DAaqtBc:mD?P2TDDDDDn{?_#"""D_oQ)?ouci?9=a;YKbש6PP?P/cZ6?.˥H_#>4/eJnX%k<807qu yVZѻwoQDDD|LEDDJL8{4o%Z ,"+'\deB& :*)*#CCJ=o?2D("""Յzr"Rf!cL0:P~}iРvo&!Zl2FE||<OBBK.u{WY7_fo$B 0fDNmgeB&w~6|fv^e?c.%ʈx `4 AC ÏKrY/"wި:|1ow]DXӾ6oWkQ׮p~VDDj*.HKMMe̘1̛7ľӧOvZ֮]_W}erI ƺuJ;|0f̙ٓ9sаaCD?N;}3sv+15rA͛K Ƨ.^;UǿԿA^*L%̺Tp`ɾ"YmZuÑe &$K#v?q3)֒쳈XkBp UHJMMof޼ysϱeΝ;GNN _|?89991!W{gΜk׮[X^|ERRR 33]v1uTիǺuڵ+gΜqp8nMLgϿm%X'T6mDǎ]۪U:Kա*3X3:3;zQVZ?M.e*`$B^vKЇ4`o%~\ˢ;3X7bD(@`"T]7g_8b{;'e]"R-9ʸͬ^}):d̝DnJH=z4{SNٳ/tܙV+ 6o߾ 6!W{> ?m۶eΝm۶SNڴi3<Ν;x衇|vO]ni,*SUd 4P2sK#) NlʻQq5H.@; ?$JpOrg:'AUUשa\=:5TDU`@#:|8̞ Vkˉ=%CE7K.DFFKIIIq'Э[7֭KTTx7ҷo_SN{%Frr29,ZԡgE^Y|9&L74=cʔ)E^;rIII|l۶h׾#G2ydf͚ŀ^s̙$$$T8ֵkr]wa+6[8p|A!Ο#lx2K"h(aRذfn˖-F]90bmS#\i =(+2Tx뭷7n{!##OZZ ^Gu_nqqq={_~??ngݻ޽{6lNc\~=/ҥ IIIܹ طo/L6+V?eˆ 8wNbƌԫWCYX,-ZDFF2#HOOgѢEX, ='։'bٸ;زe l6>̇~H݋4h?Á9W.ⳛp,)Ug^Zرy,T0|~*ʼ@cIN ,` Lèt*>'7sNb$n@=Pּv/cJߤqL5e$&&FX,233>34hԖX!~k"[0n~=CZ1k^ڿnٳF"tpػXE}^6 V;o%BE SeH 1f̘" ݻo0p@Ϙ1c>}k=x7ѣl޼L1=zur7e˖<\}Ռ;{}=?!!UM4rHxYx1SNuk޽;ׯgUtlʢgϞ4iҤ±ڵ ? ^#..(ڋwL۴i<رc^.bg[6~q(w*TJg 0V^?NmgLt 4<\ V~hRF"ӛ"xcXy9j|\쵑@ Zhhs9|FQC V X?X3" _W]d̘ 7 u{?x,nt#iz0k֥Z2v{4Wkd$|{ s 0ʽ&LP⵮]z߭[7&^3A:iҤZ,&NcZZMtV>C aرlݺg}}%93sP#GVJ7СC|<czz:QQޏt?jp}3s`ږG!Ȧ,?,26g^Y6O&v}QhŤ͋~XVᗷ͸V꘴5<9hٻ6vo!L{?Τh^A}(|ڡ.0DŇHjv} ߎ #<\Ӭ3[W2wp-`,p`N,pP{n:wP7?̳R{ywI?b'H,f5[Q] r__羚6W}}o4]$c^h3Ľ) xhsU.LlHLo󧕹m5|Cd2f5[Cnt{\ IJ&-8Hn?99ry+R۶m󛜍WrQ2|Ǝ0DJkKV~}geeط~ڷo==ܹsSH;,Y{ry~@6C<'&S޶qf6od=j?lI1is͠08} 5Mzl6Samzo1ܟjl2MBt{(`ֽ)GZXTjrJt,XqZoh̟H Zݫ94[񽴕q#߷o_m۶L4 6pECWn;$??9s^={6u]%u„ hт4,YŸgzEFxW,h޽<6..sIL`#r)MeOѬ/ZD vbg\N:w4j/jc7ڏmIyd"V㝲ގ3>Lff&vAnn9&{ssX|v7D">#8p3sL|Iڷoٳg8q"Xϴ,~.\(:Bmr>;)7mnL!"U(0Z0X{é~vW8Oc$Da W ƪx\?oڿ>7fGIohpz{>Tr3jxZt{0ޔS#vۥիJQ7Dj%Cp7}1*R&5W^\ aÆ1{lGT><~U˻s$''pB-ZȵysͮuVtBll,w+ފ… O%+/SLMÆ IKK8ZlITT'O,Qy[X̘1QFHNNsDFFBf<^YKN_7?d͚5>"a(|WI r8^bQ#vNfh'bpfh2Smi3G;gLڬ@T3mm "Фس̷9Xx^Y#,\7&_6/F/8Ue}[=ϛln,PGc O/\oOy tXm~7Fkiڪ{Uh k r77pဝ]dsxQ.r4f7¸`Vij঒Dh܆HVZU8:Wpâ\w Ϫl`<}>yh3jc{KYwQ3̤ ]PҤQWU \q]VV誫.EHQ:Hu'ɜ'3i3B$kx=y/x9syGYL<}=Vt{b"l 0pٕ۱YZ<剱 Æ* K$k}Hhw_Igkx T2Qc ꫯ`4RYV>3p@l´i2dHI _,9:t(}7|3 .ԩS<ÞDuVV} `厩¸[x={'A8|pCTEYWϺnݺy~7tK.墋.zѣGIMM_~~ -P3):-s˟,,JtXCQ׊~k5|f5w]Dh$##G~z:$=z&rh޼9Ga3~UobccYbEɓ'5 IDATj˗/{UW]Ŝ9shѢ ,oN9a';.`i̎,}G~ϖmvڌngtu?:f=p'Hzc_rLη+)n̙Ks):0K/}9#dqܲj!K*\WRv4'N;1>Hbu7͝ Ffc›oBH$-9ϧ|i]<}v>ɕ+[LR?ϓOz<ўv߉RMTeH-6bVZE&22.][o1uTԩS0|6mĸqСҰaC+=P^zqF F QF <ŋ /T{jgȑ>[h۷og!))cوcǎL8;wH4hЀe˖_"C|\q]Lf _/RȆ\U͛7ӿke>67`tMJlC>Rzas01LUӪ,6『@l~u+{0d"4ooErҨUѐJE}LN|W='z v#FUп=<2tނfh8C͛_?8s&Q\x3T+j|'%%lٲ׮] @\\\閘Hbbbuԩ~]ʲ/\d6w*ki߾=t GٵkyWt`=Ne1#DJ<_5`գ:_=#\33"Hq=D.R 0Eq!N'wf̘1̝;~@(eЫW/ypuR>W;fTFTުB ˣ41H%sW4}KVҬlR8NϩY (Ep8{7c'j="r˗/9)ϔ)Sh۶H*jўf";{8fA#r9%t ˆo$k|wV4!~kU\`ٽy|3搼4hr垡~JOHr%̜ [ա$J=#R(*Rۗ}: j}қ G7ҤnYnYNڍu( ZV*>n13k"b|'""RF9zG''..I&yu`H";HuNܞG^Y_]qqGױOEDDj+""RN6v'>>SyJTgs6Y `4"Rz1ӻHL6oEHͦP 44n:$u,5`ݮ%"" tq壅*A D&Y%""R)*"""""RMfyhHnOk pT"""5 Ziܸq :ԳV @a0굱:"MPOa9D[B0D$@Zh9y$+V,w}BBB[HU::p`~YiBn!4n#6*5Et |ѽC_$(*AkفADD|I >.s+B H"e_fG5ҸCh-+.7'39Y}ߊ~Iw;aTkJe84Ji\r@Hl4jq73Aj_+I<6>I!782MPn iY䤕m #s9>mQh6l,X7z{9a ֠ yҹ?Q=&Me[CL58e. $B+m4N4 ; _%|rf̘Y~kL2 Aid38}[EHdDoĨs3 nFr;h=+8 azwcf6MpQo5DDDRDDDcҤI億F#R;ii5!d РcG؃2ָ{m8ljJ;ԩSHsݎJMFr.M(-0N\:1v8HdEWP2+)ϣ {46 ,VpRhvx"""N)"""""c+uO>^BN%,ZLTs+Qk@DD, jus(Ny(!a=h'Nw_~eVsH͠dTH#vv4umǏgwQԏBDDDDDXZiь*)XڑޏCDDZPe=˭Z"&&&.Yd@(EI!ݘ+[ ac`kYl D_bi/5EDvSe~zvy-_a4}wqaX< ]5Bid3+6G %CEDDDDZi3ʎX!hYF6?aFntuVE5N4dܼ4ضsUDDj'%CEDDDDZljPrt +MKo4BT\9L6)"Ѡg "I-LcHdпN>y :4!j]Џ,]bm^QqNV,xJDDDPBCCv3ZȅѰͤfneʠQZd}Ӟ!E&IPաM2f#2) ,p?+\JHrp(ۈnQfڍu=^dKCM6%""|_\ P%2/.q8,,켮U $'L\i~;4/""KP21@ԑh3ё䤛3K9aܸ  *""IEDDDDV:8Kg4f^|8m )]DDD""""͛߿z@$"U<= ٝǒaiܞ.8AhTA%%9X㇊HpR2TDDD8y$+V;D Õcx3,Ρ/sU`D8x["KPu۹~N$a9+Ǥ,eynf&V#FㆊHQ2TDDDDDjF]Cq$Qjpxu.W Jh3΍hvED$8'"""""҂ ظq#a4s#XK[Xn$@GwDX@!""R Zi̘1T VEDD"""""Rtl%2PDDD )*"""1i$rBBB(' 4VݘKjBHͦ;ǏclP[.aaaCjxN08vXC2:2:m4 ñ֢TYu/C_kZ8jtHCVV)))CDEE0Epm.ȬY;HӤI@!Re:w̷~0$ _=A!:I;h q fѨKu.82O>ᮻ t"U' tR&"""""ǁO&׳|d}.KGv.b QI7jl%""5"""""R+ӯ_?f>yRvL RtfOoL\ '7vo `D"""nR+$$$pM7: B̝;7aTN@@!rN:Ǐghvc7Lfuأ˼>#|xsݾ8iF-?:1Zt"w v`d ;vo[*rJ%C%t+sU2n`1qaUuFƷS *BOn#%>@G!Rq)*OP %%{[jELLL#( G}\?ׇ: N| |1Vw Jׯgsrm0""[~N$!_Zz5.b⽏*""R)*"""""RN!,cD\M^DDDDDm}9_V: )F""""""hχN {W>DDD$*CEDDDDV7nJOO?s&e l{5=SW{Ksw %CEDDDDD*IV.J*oχNޞF#@QULu`Ճljx $}3nY<=iA$@7=IW#MP`РAyvmIDj(k(N±x=; ,g1X56 DEDR2TDDDDD N"G[I"Ѡa1Q '5~T?JTBq$׾AhdU9YbJZ0s(JTض6[ӫi:=Y()`,,]DDDDDDϸq:tg9,,U'e {] k~h>l\~j[ dJ $$$4#.# oGҠCͮXڷ"!PE3`d7ƶײbJp`~MO~ۧg\ `ofWCzFY_t +Osm׿YvG:Gc[rRM^DD \od}`@$V2+ǿe$e,KVK9bY$/͡0l/X7z{9v{G|$FV\j9S \#y nc0 `X9rdKf@ Ic2=А W[J۸rn7m}>]+kb)>Vlg)p/@sf_@f_H;b,>x&!K0rʚbW"T:3jX"X,櫸->IN.8blfn/(?tc<x(*""%%[oD^{5nʩSĉ|<裴hт?8Vk}`͚5^]uz"s>}:,^yy=v̙,_&M0sr_'AJcՃ]ř0NXl`vqqqL4JHH(q'Y>kKYKJe %E+lLyG0pHng%I`BIצoW'1Jgdy- ,Q$Y5~(OGy|<ʓ(OG!:/̜ ˗C&HIJyKIIgϞ̛7Xy6mӧq:=zKt:5jTCz $3s'I[j?ڼysL 8w\gD&66"oqW* VL:СCkEWy(wWRR] }E,u.lRl&C&@J;bޓnm 428>=ے˒ai@:g}^^wu{xfj#~kRY`U*u[;)T[g;}Vj;0;tv"`6p5 QDO.V?}R;{̱B/'8BSvլdKGqۚg0<"j&Gyzw~Q4-(?nt Cx஻ #jcH#R ߧ{DGGˍ7=~ՋuRN̏?֭cԫW(uo]ee>SbccYp!7 3gNu[n{' IDATWP5jĠA|p_|aÆ8Zlɸq8qD:tbaѢE>Ͻh",Kʰ c.Zl <<6mpHfnݚMr'N`DFFrwSn]<Çk.N 3O'of.蹘{s$渟ɘ@ۓ{‡1+Ak.6H8Y]xyl{ZaH"/*hyL,"lؼX`^x15 6l0矛۽4;׬\ RR =*< 7~Up@|Pwy_: ˌad3qfXD|S2T{;v,v"--5kǹs2d/|1cr9r$w&;;ݻw3bx N֝Owݻ3c vAZZٳg}0^}U O2vZN>_>(۱X,,\E… X,~ĉgӦMO?ĿoJ^|Pw}gqC}Zs=G-غu+}tӷo_DFgRjŅFZhBſF]m4uhag V}ޙRMdhd;9ڼrZY99UhfOw̄ L`,YfP-\|}qSZ4f5@}P>g2<{c'Qj,_ +ۗ{!KhrUM0;M{Gz5;֬LK3qqfsx%xWå©SPI0fP9Ҭ6l]ۋNz?m{άݺ鄇 ||W_}qUVG*1"ᔋ;w%-\>"z)0zi\"\.ѳgOyT\llO.[,~Çi^} h׮]m{6c֬Y%6O>c|;wѬY";wlƗ_~iaY:ٯI&`㏥^kѢEe֭2YXHzg5<[׷/fIMqr{{6mL#V4F@%u0-olSh[n`p9-_w``p0 g ,SS?nx)qϽhޮкug*sE  ܹyƪҍؿ9]RtA)ia|1* t4'i{dF4f*rX0jSr…zUte/h۶;/sg5k/_&?,ZTG޽;"**v{éMׇ;vLrTS&L(-^z\dbqҤI%X,L8C;FLѥ nV1Çc>ӟu駟Jl;Xf g;."Nq6oޜ{裏bޅ+A>|Gjj*۶m#44ݻ`ΝPn]ѣGiܸ1 ^QFXV\.[&"W9V crj6wU|r W[*t'Gyب[3`㓙>89+~ qb wyfYsg o99m2}4(<=yD]&b1'8@+ Tض BC1O;wօ={QhJ{oVukxΝ[d,++J(ZLzz:`NS\ ʴ=3h|޽\y^k}iԩӧIMM%&&BHMM7`޽3gΐ[4rqǷiMQr7?+Vp1Oǎcʕvn4s<#< ݛݻӫW/jBCK>[,?gxדGn< KA׮]Y~=6ln(xnu]\μy>|xVW,tכ}ꈷZ'3ȟږ%[>:1g2kZCΏdE[E״,weRHܚʅkymu5|a}Lȓ} +S&˕^(/1.}0',_glX .d$C"5qC });'hGT̮@n5J\^z^IP0 n ^}#r}`㒁ޏ<3Ls9k^abC&dsPH3qʯr95V6G)\mޯYqŒaid1g91||i p˾ydm.'f{_cgHks95tL݆D;_"#SA Pb#GjUyԤ$?+ݺ$-sfqNoB23s7jc|ر;v3T+mܪkl_ ={*t|rr2۷gҤI]'NH0dg{d111p 1w\9s搗ǠA$w' &.sαxb~iKӦM6m'YXqC^vo/x?8{}'L@jjj)GV_um9UutpnCiiPJZ<ٷz~ -.oו@swU@{`X'(})ܞcu}x?.yމPFVB#576\"[i9 b_PJkg_Aly7xne fiO`V Ŭ K伨(RRR8v\rIǎy{ͶmXx1W]uUHNN+䩧s4nܘp, ^+'+w ={6]7￟￟}e+nĉX,,r;鞤xgRRSNLTUVʬYСs믿'^{|uu6(ΛU?1\\]/+C>x 茙H Yz%1g/Y>w3kjvM2Lٽy$gGHϱ (8^V3{X9&4Spl ^3OٯpNn+Rh}tYEw=-{}!CNؿm.sYGvp::uHjJJ v[ڶmK9qϛjjj*۷'99)SSO}vtbӦMtڵ%V\I~<˳f;$]d#'yΊpZ(}W>sY;w.v#J8>֤GQӉ*4CUrf%滘c~6b& ̄ ߘUW?8W*fuf2g`mGY1 wiv ]?%?͘89+~œigi|]qB{`;woŕ [dٜ1ci굶rh_&7òqb׾#z7S],1]FJ |wU0fȊpaj#lOL-[`qvؑ)SfXΝcÆ =N Y.=n~/tɒ%1k֬cN<-[w`G]S'5" r|lw[ faV L_;0T])33ufBm݅ &!: ÜX-fUk (dQ5 -2tEŒ[_¨xob+ _Ë| qŲ;9zgisV}EU*oXu0z9RNshsR~t=nhB,w5F5 O0y2l }gv %5k;#j壏>">>N||<}cǎ+cÆ :SNsϑHz q 8ӧ9vԩ86l@^QFߟ5kZ IǾ}袋ڒ-s<3ӇFJݺuի˖-#66ӧ{=֝t:KɓsrrWܩS3f / %`LsJ租~C|o5;)zh.)]*wQێ`?]bvg׀$[/[%NcݮƜ>sF ֏nQ]kcݱafׂ1w˭> +1ʍ01u`N43y|),)wR/p"/*u~?2ZsoPa!eov{*AFѠC')fw Ώ>xz|<|t??ʗ<ͽ>Qk2)c<OC=ƋTJ3bVZE&22.][o1uTԩ 111̟?M61n8:t@ll,4lؐ}+p"{ƍ6l'$$F1x`/^ /P)Z$#Gbh<8Ф$ׯf#**;2qDv2sE ,- f;zѣݛGyg7p#F --qܯ&{ޯFp˚U&?OաlРAygЌ.|XM2+A,~:!UB̀6Ŷ耙+!qF{>aV>t^  Ì138331?6@U #\Xtb㬋9=gc~`` ; _kVmUzUZ\N6n\El[!{'տa!aMhs2!:"#q7z˜#:w6OJKmۣCѣfuxn|_ii"M(IЪ(ڵkݻ7ݺućG|MTVgzlHG2lEtELb׻mm\9Qh@I2x@\9옑Ma>3"h9t셌73 aYjghS7`(ڵf[7P(p4TM$"&wC=aHmSޯEpjߕoU_*AEk(-k+E7eCJ׵(*RI< >J2 `ѢE:tݻ3f sf.!TTssLћMK)C8oc^aFԌDj7-p..A};r3 NnY=l~63aH0-2t:anslιs < >z:e/_˽n2e m۶TOZ[zi\옙;81 C[&)^ڸ{PT];Ksr)=CK}w IDATdĉs= 2r38>gIz2OC3mkTXX|y3e y$|T*Rˬ\Ç &&~p*]&rW޲׳qH0+J>9s]oqԗ\r ]tMXl|*_bəlSfO"`ӳY\ ÇC\8…HpӺH-ӷo_0DjwRCv W5Jmqř=.|I^z 4wR;au@2#%q߅,,қ,m^r]K3˵\Pp_r/paf;?N30  |ޯysy2#3Η<>݀1T$iQ+JU3qþc¹6jL*5+='N.ODDDUdIJ=8AY۷{\%ALyh5?SAI1cmd nU13Sƈ0JDDTA@k_dvʕr pux"&+S$rۿڭ4w{xyJ^QA(wG=.n5DD&C; pT~8I 6h/ýJj7-0MDD.""""""#j}G~ǩvȄ%ls1JDDDDDҚ5kw^k{֬YebQ'uRV|uc$""d(K[lyzPy!JDDDDDD.;ڀ_Ɵ&wBDDTi %"""3gZm۶uc4DD)g{fja6I S%Zŋ k(e*d(|c f`;: bۨ]RSu<!b弢DDd䉈B)0h ;ʬp:Q$u0 H^$< DDDDDDU3)P# ó?q"7EU"(G\5]sfDDDP"""""bbb0p@&*D `b5:NRXGi^#f/"/Ԩ-LE"""O9C^:u*N0D3RO1|aQQ4ĊTxfqP""be(UQ(_<<磥o=?VBRbŷXJDD %"""ٳv6mƈTִEhW^81JDDD`:trJ9ҍy}V{fAddgPKp#6UDDTyX""""""3Z qz B.%"Ҙ %"""":ɤΙqCÍ?M f$q""䉈k (h 340Csь3|%D0ȇ}}pG5On+&C^q0js:b}bE~4&"/ X#G;$:+x qzTDh9]! ^D=>R*{}󅪚IqR| xQ MftODD?Q_hʡDUnmQ(X` 1 S0/ZǻUͤB6D)0p?p wyO"GHm֭;NڵC:P~iw@DDTer'NtwD5F6?Q}W6`^.gkcD T߆@wUw G>*=yQQQrwDDS """""hQP8)tK)[ 7lY+N'cc-LE;=e# V%Z=MH[,Rc˓0h*+%8xSO!?? NT#2 8Aoh~ o/Q^ٻ?ԡ""$ ܈*p [*QEŷe~4.CP%@$UC6H54(@/DTo>@tt4RSSQ1""""""kEߪ W*2 fĮ:ܳ+0Y(iED(Q=d(AocԨQ /Ꝧqr ^ڵ䔳n ^1WghT Fb"5|JCs53D"ŋq%O=&4abKC%R`#}yJ;Lkx^r [班 w֌&c3"";NDDD}taВ 5ܿw>@;ehy2j=~]C SuO)~ Zuv֧ !ȘNa2oQQQUDTt*9$\,T5h'C+~ֿ~5@sɌaԽՃFzE?SA٤M5ap έ6 k'*y &CoNIIqO Dh_ߔ_Qr.SmƩzl|G?KTCSdqlɿ#1VLm6[)")G'D .V.j ~ͺsYowތ{O՟m='3'iQ˲a"P"""5of Y|5dei* U5"hL:W0hcMh<z ٜ@݊n :kvÁ}^ؗФK*[3v4 DDuDDDD b a ] ًߪurWO~Qjpǰϋl*O-c4-L8DD9KRH`[HA;8ys Z n.#{\o2,@pp0Wn?m?(@HqrA0b?I}Msi+ÀE*C'w#N(Tty)>DT o>@tt4RSSQ1DDDDD5"ATa*rcΝD( VW  @>#&k&&sOs;e?9:Px&B&Cȫ%g'D@z+55&9vXE>nh'/3> :w!T+ \)A{jOX5U]Q]d(y>iVp̜9={D~\PHX#{Ky*BzC*X5a>HY RXw2)MDD㜡DDDDDάT}R@eGeyguPG-ArD<ОrHXlXm >NDރs %"""ȁ0p@\~ݡh=}YERPH__P$/Ī{mLz]ܕ~EDDބP""""'1uTc֭x9jkn09_tS&SZf{E;_}\ &a vX6Q5FҥKa6-Z={9*"&R$t@@ǯ˟kpba1ݯdC\}>+`2=K|DDDDNb֬YֶlƘ1cp 7FED ==ݭ1pt?<p׋ !EΓ׏c|K| @܅K^ֹ)0Zhv3+}bm-`-%Y3 c2믭`ܸq e2ca׮]}HLLtcT3h#" 9O)B$\vlW V2%d~%Sy3%"dL`Ĉ>}:ƌ 6 00!f'Oիd2.]H7F:)1@ .VG}(&$2 >sf4$2 %SB*ZA7n!12t-^8_ ]o}3+>`ܹt<{g xMUD#G>rĿDn6CkП_#;=t#bZ'@وYc|JƝeTSi¿HA` ? ׯ> ={6|M7GU;|('ͺ>aC|'"}&ODDDTMmۆ7n; z-00k׮EXX^}Ud1$B1Aۈ鐹'v " ULU4 >ؾ}!ZhǏ߯WZ4 C?hER@sa6`dqU"P"""TTTQFAŋׯƎwFTgeee{>.r@vO"G<;]CĕC{<1|jIk+ZSag a*rSM׏n;^¨c)`26?~.\AѶm[|'(.jI&!""{qw8K\(0WؙWN7 82)X5_N#zsf%IK5+U^J=$hpag+L""MLݦ8=z60}t[Mϟĉ `0`0"$Fxv# bP_ Ozly?vǁCZW/_-l }>,PQf[g{4}rV""Od(Q5Ν;!!!111x衇w;t (,\zzXtr9N( 8r2$R#m &3 דRt}yg9)1JDDDTMd2^x>}< r9^}UH˥htR?f3? 9P(\waÆ;w.|I7EVwĽĈgl_Z C?P )6H0x{bEK2jJDDn&DDDD5ٳ ׯ_aÆT*ڶm:Eԩƌ㰟Nòe˜wȑvxl׮]8yc0`cZ˗/=w܉SNU=GJ;@+,,Ċ+t;vEEE_~Uѣ.}vV}[hZbѢEN㉍ő#GM61yd;CUw ހwz0Ch5PaeN0>,Bho9B{ʫt }߆i,I@p.\ݻkDsرèطo ::{+U-^z%mСN8@8yӾ'OvoNegg{SN9s97f._\=SSS8q~=~3--ig}i'xiK.{3g8;aƎŋ˽ٳg}駝{'pO* ZiO?TݻhѢrϣjf᳿ᷬۚ!±ϋ tn2 o 9 5vK͍os̩ߟ֭[7pW-""""m۶msz, #!r/ٌg;tx|ڴi6mZ-GErF۴sSMM5EhC5̷sB5?\aDJ(B״DDP""""7IJJ–-[pQ!-- ϟ``2ZlP@H"X[B-֐yG:F" f+!u<X_< IX< %""" .]BPP6lǏ;Fx>/ڵk5hu~z߳cǎP(zO^?ٰaC{=% !Ѻukg3;H_-F냗ѼCP6 I>E @.2[_L˖-YTۍݦ,`ܸ9so-9CfDDDDDDtL@v2R_:4#b}nx6#N(%EhOdhr2d:"p ]f2 m)փ}P8V5b:쒏jpbzGNrt@ i[gXٻkE-<&CVhs̸vdO0Wp`V_*/j/-PG]RժuB! /]c B 5)d( @ WyшaBZjSѺK~PVQ!?(V^?n‘Oj2T""W'"""""Z!WI5Q#}& }q P)|| ̷@@?#y-"8c>zI_ Ѹ xWB0JDDDDDDNXv|n/ .dYGq/|$KA>hqimSK0[5${٨ ]*gР 8*E"lv}"<hyNA7 8ROcvHu3Bh=>_ZJDT %"""`6۷.T\bK}SRRlO@Dt29 8M1H9$@J|4~̄K̆&C}l))).s4ݱcK}ѷo_kXJTy+0|?zQHۏ24hcˑ{^!y-}XT!_ WA#@DJDTS %"""`H&C 4?<%?xTMiqbwP 3vMB0c+:%4K+1WaDDTOD۷P(V !P\\ӧOڵkhܸӾEEEطo_1G%:L4G&M?_n2f.n6'Eh^a>ꃀֵSHwːhw=rOk8"GJ6ψ˙SnVh_ \ofRJUneEFt8E QuDDDDξ2yC pT*EϞ=L&?~yyy *ӷBY9D? `˖-ʂJB6m0rH<3crpBl۶ /_ZF6m0zhL0{zz:V\["-- ׯ_lFFбcG 4ƍCHHk8[93 Xz5֬YG"++ >>>G˖-8 :111.|Duh5T$ w#>y2!#Fy|zSټ +0jUCvcwjH)H΀ODDDpEk{6IIIHLLtٚڵ+<XnZ;laaaHOO/s^U{=FǛ5k5k ..R7xgYI5k֠K./2[ r Ļヒ)S8<^^ә>|cƌAZZZC%Rq ~_(͏"{Ofi~E -[ O> P!ը3g9so/jo#ttt4RSSQ1䉈}uZ2Tȿ+5kD( !!a<&M§~4 /_+}tt _}UPԩS /T>pWD(U`.& fA*®5CafYc-_KbLyĤE u5 ݸq#>#} mې<$''O>ɓ]? 2dRRR޶m\L4kk4 6 'OƗ_~4t:h48p&MTZ//sMAVjZ;,"??ǜ9sp1h4B̙3X~=^uo埗JM@~h/'氄r[,oC50hNSJ*A3pz"0y""""/pyDFFZJn݂uNCpp0z=$ ^Fn޼FA֭[PT־ NpPsAgZ=cX|ykf3Vrx{& tu78eܸqXdK_~=b,_~~~駟0rHBBBaL3lkTDT9f7niD<Dޤ.n 8 *.{^ Ӿ-]e[BR|0[5|ԵQ]d((Zz.PsO8p=dȐ $$$t?æ=hР <إk6mW Kűc\犑#Gڴ}YX|y"r=FVk 8Rsl"h56z =>Rx<(Q1JDDD%rzaU߿ߦ޽{˽WUدޮ] OFFFݶm[]z$\.\.L&nRԺI$2UCo[o]Zۂ `ݺu;v,BCCѮ];L<k׮j%Ӣ7-WIjkUJ{fY=>T"]ɛI$VZXߦ22JI$˿ձcqcݳDu DDDD^"22Zu:wqGaмysq"kW|p-vHHH}\9lqqMd2Y7l^Fq~Ν;1{l4iҤӧOc>|8Zl?04Qm 4?<Uj}#\S-`HFP7˗YfaРAe3v#F`BM$RiW9 DJN}ᏊK{@ F[LeY,omڈ_ % %""""JK2B-%CkbPl%fnnn}\9[*; vݨQ#7l@+L>}୷͛qMY|+,XP#1$2@10J^/nislA !YیX3Dh4-vh_ja?c$ij*FDޅP""""/hPV={XZ{nt/@N|δnڦ} rDDDش?R?wQ*xqF̰|ŋLwxex;c  q+/!ŏGzJcR)p#Gcv/!C`XP&$&>3_ ̜ t(lj:gMZxu qqq6M6U'))ɥk^L+90p@U\*YA/ڴ]M.ZQK‡-zd }O.*Ƶæg`Ps5~į۶IA+W՗7yy@a!p 0q"U7@yC-UݺIxѩ Ą^/.4ox?GVzlg^x<(&>o @'?8|ضOu?DހP""""/c? ~ܹ˫ utN@:l0~\x}ٴ=Vo֥k=2_6mŠn3;@X|¨ ̓W/`2w(p,4D%f۝}ҶĊgf`hjX:jUi?o%٫WyCogٳ*ם;7jˁ sĤei990ubglXш[Rй3pxN鷝|DDDD^>acB-J'C˽4h"K)r &MRL87XJbb"Zjemgee,mԩȲDLL Ǝkm $&&}9;wDrJelڮ\wطo_'|*CDE |Wy.6 ˥^n3 j0J%c$xCZ:f2$"K'wݻ}WPKrܒ u6_+xBLD Ccoٞ?MmV| ڵ~Q.bB}{1K[m.[Hٝjٳg&RSS]nSN}]pau7`ҥ Aٳg#%%C )3WZQFKLLīXÇǦM*u[n{6r=#GDll,5jٌ7oĉسgVZeSLyN:>Cll,zo׹sg3zBTTpMaXxM5^zaD6=VFC 0f㈊Ξd[|W < 3Sw{~ii%׉XxYFj/Zdy?&@&0gy? T*VTTbfP`0UAA@j@lTt'OL{@hx’+>>W 0b{#&QG,~3FLΖNVsXΜJFTBTMkI~~>Fw8::nޘN˖-5A֭Yf.oܸqaaa.WiӦh .\P?3.];88̵e2YNOO:um矂\.5r^z 燈SwƑaI[p밫BSy Ajv8Q|y}x>\l?^Tl~932'=kc٭c=$q=6 VFQ_cυ "r=s4&{]wj+&ODDD weP^T>S6pk֬*xӂ 0m4Քi&4mfPPP 1}tjH$HHHtχBQΪ(vv؁r1L0III˝%"= +u(=?Vy/Z~Ijl!W ^wZB=,Af;̎аy  +VWdh޽/fMyw裏bHNNFVVT*ڴi#Gg09T*ŧ~{ _}mۆl׶3ԕᣏ>믿~)))8z(_j4mwuzGy-Z&L@~tRܹuZzB^p%\)))8vuՐĠgϞxѸL"D>ȇ}_fa%-ov'J' `n~P+W!\zdTZ|A"J|UXnzi[&MsfɹUsXbbb|--+UQDDDDT/lذCqF7FDDT-['|NNF :| b2.'G;SĪk׀%K?qv-0|}e 6=sQLݸ!j'VV:]++,/ΩhիU]{w`^`*q%zG,sQ𵨎&:gaYՉjfp< ֭is=nn 5KڷoIO") _ڐ!׹s&T*.d~q-E:v>8ZJb fjKy,@+{=Ҫ9$LQe˖+]%JDDUgFn۶?~0i8L|.'U O ͮ*Pŋm,._.~|U1i8}35U`=}5JúcNN-{sϕ_!`2C=K.{Ε+WCcYwމ^ǶzҾjt["q`lkqzL؞4I9<9̬O˚Y a a i i5>92>93d}r~+d}r~a@:>9̴O 'wL!g'w5>9δO(׳Ot}ryn;'ʑhO /_ןdY]}EUUX|7@XB ,!˧>ݧݦ>sIENDB`mathgl-2.4.4/website/colorex.png0000644000175000017500000000214013513030041016765 0ustar alastairalastairPNG  IHDRddpTbKGD pHYs  tIME )1pIDATx1n@DGm'H2;RCln)\ylY2Eς(Qa-f´d>5gM4>\@(!@""@(!@"@"KW}ȱ/$V0fE (0].p`|`&F@V|+dz3OpD V@cb_&a.Ӿ  * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/other.h" #include "mgl2/surf.h" #include "mgl2/cont.h" #include "mgl2/eval.h" #include "mgl2/data.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_surf_gen(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch); //----------------------------------------------------------------------------- HCDT static fill_slice_x(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); if(l>1) { aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l); mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x); long k = long(d); d = d - k; if(k>n-2) { k=n-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;jv(k,i,j)*(1-d) + d*a->v(k+1,i,j); a = &aa; } else { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); } xx.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'x'); zz.Fill(gr->Min.z, gr->Max.z,'y'); return a; } //----------------------------------------------------------------------------- HCDT static fill_slice_y(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); if(l>1) { aa.Create(n,l); xx.Create(n,l); yy.Create(n,l); zz.Create(n,l); mreal d = (m-1)*(sv - gr->Min.y)/(gr->Max.y - gr->Min.y); long k = long(d); d = d - k; if(k>m-2) { k=m-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;jv(i,k,j)*(1-d) + d*a->v(i,k+1,j); a = &aa; } else { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); } yy.Fill(sv, sv); xx.Fill(gr->Min.x, gr->Max.x,'x'); zz.Fill(gr->Min.z, gr->Max.z,'y'); return a; } //----------------------------------------------------------------------------- HCDT static fill_slice_z(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); if(l>1) { aa.Create(n,m); mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z); long k = long(d); d = d - k; if(k>l-2) { k=l-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;jv(i,j,k)*(1-d) + d*a->v(i,j,k+1); a = &aa; } zz.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'y'); xx.Fill(gr->Min.x, gr->Max.x,'x'); return a; } //----------------------------------------------------------------------------- // // DensX, DensY, DensZ series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensX"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgX('x'); if(svMin.x || sv>gr->Max.x) { gr->SetWarn(mglWarnSlc,"DensX"); gr->LoadState(); return; } mglDataV xx,yy,zz; mglData aa; a = fill_slice_x(gr,sv,a,xx,yy,zz,aa); mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensY"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgY('y'); if(svMin.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"DensY"); gr->LoadState(); return; } mglDataV xx,yy,zz; mglData aa; a = fill_slice_y(gr,sv,a,xx,yy,zz,aa); mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensZ"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgZ('z'); if(svMin.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"DensZ"); gr->LoadState(); return; } mglDataV xx,yy,zz; mglData aa; a = fill_slice_z(gr,sv,a,xx,yy,zz,aa); mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_x_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens_x(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_y_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens_y(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens_z(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContX, ContY, ContZ series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak); void MGL_EXPORT mgl_cont_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContX"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgX('x'); if(svMin.x || sv>gr->Max.x) { gr->SetWarn(mglWarnSlc,"ContX"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContX",cgid++); mglDataV xx,yy,zz; mglData aa; int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; long ss=gr->AddTexture(sch); gr->SetPenPal(sch); a = fill_slice_x(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;iGetNx();i++) { mreal v0 = v->v(i); mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContY"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgY('y'); if(svMin.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"ContY"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContY",cgid++); mglDataV xx,yy,zz; mglData aa; int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; long ss=gr->AddTexture(sch); gr->SetPenPal(sch); a = fill_slice_y(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;iGetNx();i++) { mreal v0 = v->v(i); mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContZ"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgZ('z'); if(svMin.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"ContZ"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContZ",cgid++); mglDataV xx,yy,zz; mglData aa; int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; long ss=gr->AddTexture(sch); gr->SetPenPal(sch); a = fill_slice_z(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;iGetNx();i++) { mreal v0 = v->v(i); mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont_x_val(gr,&v,a,sch,sv,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont_y_val(gr,&v,a,sch,sv,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont_z_val(gr,&v,a,sch,sv,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_x_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_x(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_y_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_y(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_z(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_x_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_x_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_y_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_y_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_z_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_z_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContFX, ContFY, ContFZ series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, long ak); void MGL_EXPORT mgl_contf_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFX"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgX('x'); if(svMin.x || sv>gr->Max.x) { gr->SetWarn(mglWarnSlc,"ContFX"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContFX",cgid++); mglDataV xx,yy,zz; mglData aa; long ss=gr->AddTexture(sch); a = fill_slice_x(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;iGetNx()-1;i++) { mreal v0 = v->v(i); mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFY"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgY('y'); if(svMin.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"ContFY"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContFY",cgid++); mglDataV xx,yy,zz; mglData aa; long ss=gr->AddTexture(sch); a = fill_slice_y(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;iGetNx()-1;i++) { mreal v0 = v->v(i); mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFZ"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgZ('z'); if(svMin.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"ContFZ"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContFZ",cgid++); mglDataV xx,yy,zz; mglData aa; long ss=gr->AddTexture(sch); a = fill_slice_z(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;iGetNx()-1;i++) { mreal v0 = v->v(i); mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); v.Fill(gr->Min.c, gr->Max.c); mgl_contf_x_val(gr,&v,a,sch,sv,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); v.Fill(gr->Min.c, gr->Max.c); mgl_contf_y_val(gr,&v,a,sch,sv,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); v.Fill(gr->Min.c, gr->Max.c); mgl_contf_z_val(gr,&v,a,sch,sv,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_x_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_x(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } /// Draw several contour plots for data a at y = *sv void MGL_EXPORT mgl_contf_y_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_y(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } /// Draw several contour plots for data a at z = *sv void MGL_EXPORT mgl_contf_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_z(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; } /// Draw contour plots for data a at x = *sv void MGL_EXPORT mgl_contf_x_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_x_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s;} /// Draw contour plots for data a at y = *sv void MGL_EXPORT mgl_contf_y_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_y_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s;} /// Draw contour plots for data a at z = *sv void MGL_EXPORT mgl_contf_z_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_z_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s;} //----------------------------------------------------------------------------- mathgl-2.4.4/src/def_font.cc0000644000175000017500000260646013513030041016045 0ustar alastairalastairconst unsigned long mgl_numg=411, mgl_cur=194872; const float mgl_fact=35.7143; long mgl_gen_fnt[411][6] = { {0x21,166,41,0,39,82}, {0x22,204,43,316,38,402}, {0x23,250,33,630,32,696}, {0x24,250,81,888,80,1050}, {0x25,373,130,1530,129,1790}, {0x26,388,128,2564,127,2820}, {0x27,89,20,3582,19,3622}, {0x28,166,22,3736,20,3780}, {0x29,166,22,3900,21,3944}, {0x2a,250,154,4070,169,4378}, {0x2b,342,12,5392,8,5416}, {0x2c,125,34,5464,34,5532}, {0x2d,166,4,5736,2,5744}, {0x2e,125,21,5756,18,5798}, {0x2f,138,4,5906,2,5914}, {0x30,250,43,5926,41,6012}, {0x31,250,28,6258,27,6314}, {0x32,250,43,6476,41,6562}, {0x33,250,91,6808,90,6990}, {0x34,250,15,7530,12,7560}, {0x35,250,72,7632,77,7776}, {0x36,250,68,8238,66,8374}, {0x37,250,13,8770,11,8796}, {0x38,250,85,8862,83,9032}, {0x39,250,68,9530,67,9666}, {0x3a,138,43,10068,36,10154}, {0x3b,138,57,10370,52,10484}, {0x3c,342,7,10796,5,10810}, {0x3d,342,9,10840,4,10858}, {0x3e,342,7,10882,5,10896}, {0x3f,222,77,10926,73,11080}, {0x40,460,136,11518,136,11790}, {0x41,361,47,12606,50,12700}, {0x42,333,90,13000,90,13180}, {0x43,333,72,13720,72,13864}, {0x44,361,67,14296,68,14430}, {0x45,305,57,14838,54,14952}, {0x46,277,51,15276,47,15378}, {0x47,361,88,15660,86,15836}, {0x48,361,60,16352,56,16472}, {0x49,166,27,16808,26,16862}, {0x4a,186,45,17018,43,17108}, {0x4b,361,70,17366,69,17506}, {0x4c,305,37,17920,39,17994}, {0x4d,444,49,18228,47,18326}, {0x4e,361,47,18608,50,18702}, {0x4f,361,63,19002,60,19128}, {0x50,278,66,19488,69,19620}, {0x51,361,85,20034,83,20204}, {0x52,333,69,20702,69,20840}, {0x53,277,91,21254,94,21436}, {0x54,305,32,22000,30,22064}, {0x55,361,68,22244,68,22380}, {0x56,361,42,22788,41,22872}, {0x57,472,72,23118,75,23262}, {0x58,361,82,23712,80,23876}, {0x59,361,55,24356,54,24466}, {0x5a,305,32,24790,30,24854}, {0x5b,166,18,25034,16,25070}, {0x5c,138,4,25166,2,25174}, {0x5d,166,17,25186,16,25220}, {0x5e,234,7,25316,5,25330}, {0x5f,250,4,25360,2,25368}, {0x60,166,17,25380,16,25414}, {0x61,222,112,25510,115,25734}, {0x62,250,70,26424,71,26564}, {0x63,222,62,26990,60,27114}, {0x64,250,72,27474,79,27618}, {0x65,222,53,28092,53,28198}, {0x66,166,57,28516,53,28630}, {0x67,250,139,28948,149,29226}, {0x68,250,60,30120,67,30240}, {0x69,138,45,30642,44,30732}, {0x6a,138,71,30996,71,31138}, {0x6b,250,69,31564,72,31702}, {0x6c,138,30,32134,30,32194}, {0x6d,388,102,32374,108,32578}, {0x6e,250,66,33226,67,33358}, {0x6f,250,53,33760,50,33866}, {0x70,250,68,34166,72,34302}, {0x71,250,64,34734,68,34862}, {0x72,166,61,35270,61,35392}, {0x73,194,79,35758,86,35916}, {0x74,138,47,36432,49,36526}, {0x75,250,54,36820,56,36928}, {0x76,250,54,37264,53,37372}, {0x77,361,72,37690,81,37834}, {0x78,250,83,38320,89,38486}, {0x79,250,74,39020,79,39168}, {0x7a,222,27,39642,25,39696}, {0x7b,239,55,39846,54,39956}, {0x7c,99,4,40280,2,40288}, {0x7d,239,55,40300,55,40410}, {0x7e,270,41,40740,40,40822}, {0xa1,165,41,41062,39,41144}, {0xa2,250,81,41378,84,41540}, {0xa3,250,135,42044,148,42314}, {0xa4,250,73,43202,72,43348}, {0xa5,250,71,43780,69,43922}, {0xa6,99,9,44336,4,44354}, {0xa7,250,152,44378,156,44682}, {0xa8,166,43,45618,36,45704}, {0xa9,380,92,45920,87,46104}, {0xaa,137,95,46626,103,46816}, {0xab,250,69,47434,73,47572}, {0xac,300,6,48010,4,48022}, {0xad,166,4,48046,2,48054}, {0xae,380,106,48066,106,48278}, {0xaf,166,4,48914,2,48922}, {0xb0,199,43,48934,41,49020}, {0xb1,342,17,49266,10,49300}, {0xb2,150,41,49360,41,49442}, {0xb3,150,74,49688,75,49836}, {0xb4,166,16,50286,16,50318}, {0xb5,250,68,50414,67,50550}, {0xb6,295,48,50952,47,51048}, {0xb7,125,21,51330,18,51372}, {0xb8,166,40,51480,43,51560}, {0xb9,150,23,51818,26,51864}, {0xba,155,46,52020,45,52112}, {0xbb,250,73,52382,72,52528}, {0xbc,375,43,52960,40,53046}, {0xbd,375,74,53286,69,53434}, {0xbe,375,95,53848,89,54038}, {0xbf,222,86,54572,82,54744}, {0xc0,361,65,55236,66,55366}, {0xc1,361,65,55762,66,55892}, {0xc2,361,55,56288,55,56398}, {0xc3,361,89,56728,92,56906}, {0xc4,361,91,57458,86,57640}, {0xc5,361,91,58156,90,58338}, {0xc6,444,86,58878,85,59050}, {0xc7,333,108,59560,116,59776}, {0xc8,305,74,60472,70,60620}, {0xc9,305,74,61040,70,61188}, {0xca,305,65,61608,59,61738}, {0xcb,305,101,62092,90,62294}, {0xcc,166,45,62834,42,62924}, {0xcd,166,45,63176,42,63266}, {0xce,166,36,63518,31,63590}, {0xcf,166,72,63776,62,63920}, {0xd0,361,70,64292,69,64432}, {0xd1,361,88,64846,92,65022}, {0xd2,361,80,65574,76,65734}, {0xd3,361,81,66190,76,66352}, {0xd4,361,71,66808,65,66950}, {0xd5,361,104,67340,102,67548}, {0xd6,361,107,68160,96,68374}, {0xd7,319,12,68950,10,68974}, {0xd8,361,78,69034,80,69190}, {0xd9,361,87,69670,84,69844}, {0xda,361,87,70348,84,70522}, {0xdb,361,76,71026,73,71178}, {0xdc,361,112,71616,104,71840}, {0xdd,361,73,72464,70,72610}, {0xde,277,70,73030,75,73170}, {0xdf,250,98,73620,98,73816}, {0xe0,222,130,74404,131,74664}, {0xe1,222,129,75450,131,75708}, {0xe2,222,120,76494,120,76734}, {0xe3,222,155,77454,157,77764}, {0xe4,222,156,78706,151,79018}, {0xe5,222,156,79924,155,80236}, {0xe6,333,127,81166,132,81420}, {0xe7,222,97,82212,99,82406}, {0xe8,222,71,83000,69,83142}, {0xe9,222,72,83556,69,83700}, {0xea,222,61,84114,58,84236}, {0xeb,222,97,84584,89,84778}, {0xec,138,40,85312,42,85392}, {0xed,138,41,85644,42,85726}, {0xee,138,33,85978,31,86044}, {0xef,138,70,86230,62,86370}, {0xf0,250,74,86742,72,86890}, {0xf1,250,109,87322,109,87540}, {0xf2,250,71,88194,66,88336}, {0xf3,250,71,88732,66,88874}, {0xf4,250,61,89270,55,89392}, {0xf5,250,94,89722,92,89910}, {0xf6,250,97,90462,86,90656}, {0xf7,281,48,91172,38,91268}, {0xf8,250,73,91496,76,91642}, {0xf9,250,73,92098,72,92244}, {0xfa,250,73,92676,72,92822}, {0xfb,250,62,93254,61,93378}, {0xfc,250,98,93744,92,93940}, {0xfd,250,92,94492,95,94676}, {0xfe,250,71,95246,72,95388}, {0xff,250,118,95820,115,96056}, {0x300,0,15,96746,16,96776}, {0x301,0,16,96872,16,96904}, {0x302,0,7,97000,5,97014}, {0x303,0,40,97044,40,97124}, {0x304,0,4,97364,2,97372}, {0x305,0,4,97384,2,97392}, {0x306,0,22,97404,20,97448}, {0x307,0,21,97568,18,97610}, {0x308,0,43,97718,36,97804}, {0x309,0,44,98020,43,98108}, {0x30a,0,43,98366,40,98452}, {0x30b,0,36,98692,32,98764}, {0x30c,0,7,98956,5,98970}, {0x30d,0,4,99000,2,99008}, {0x30e,0,9,99020,4,99038}, {0x30f,0,36,99062,32,99134}, {0x391,361,45,99326,46,99416}, {0x392,333,71,99692,70,99834}, {0x393,293,35,100254,33,100324}, {0x394,361,8,100522,7,100538}, {0x395,305,56,100580,52,100692}, {0x396,305,32,101004,30,101068}, {0x397,361,60,101248,56,101368}, {0x398,361,105,101704,104,101914}, {0x399,166,27,102538,26,102592}, {0x39a,365,70,102748,69,102888}, {0x39b,351,41,103302,40,103384}, {0x39c,444,49,103624,47,103722}, {0x39d,361,47,104004,50,104098}, {0x39e,321,62,104398,54,104522}, {0x39f,361,63,104846,60,104972}, {0x3a0,361,52,105332,52,105436}, {0x3a1,278,66,105748,69,105880}, {0x3a3,311,24,106294,22,106342}, {0x3a4,305,32,106474,30,106538}, {0x3a5,361,55,106718,56,106828}, {0x3a6,381,76,107164,77,107316}, {0x3a7,361,82,107778,80,107942}, {0x3a8,372,81,108422,81,108584}, {0x3a9,372,62,109070,60,109194}, {0x3aa,166,71,109554,62,109696}, {0x3ab,361,99,110068,92,110266}, {0x3ac,271,84,110818,80,110986}, {0x3ad,219,111,111466,110,111688}, {0x3ae,256,71,112348,72,112490}, {0x3af,137,52,112922,54,113026}, {0x3b0,262,119,113350,110,113588}, {0x3b1,271,66,114248,64,114380}, {0x3b2,247,96,114764,99,114956}, {0x3b3,237,47,115550,48,115644}, {0x3b4,250,83,115932,80,116098}, {0x3b5,219,94,116578,94,116766}, {0x3b6,220,100,117330,101,117530}, {0x3b7,256,55,118136,56,118246}, {0x3b8,247,57,118582,56,118696}, {0x3b9,137,34,119032,38,119100}, {0x3ba,250,64,119328,66,119456}, {0x3bb,248,48,119852,47,119948}, {0x3bc,263,64,120230,63,120358}, {0x3bd,227,33,120736,35,120802}, {0x3be,220,137,121012,139,121286}, {0x3bf,252,43,122120,41,122206}, {0x3c0,250,67,122452,69,122586}, {0x3c1,247,55,123000,53,123110}, {0x3c2,220,79,123428,79,123586}, {0x3c3,273,45,124060,43,124150}, {0x3c4,238,46,124408,44,124500}, {0x3c5,262,58,124764,58,124880}, {0x3c6,311,73,125228,72,125374}, {0x3c7,250,52,125806,51,125910}, {0x3c8,347,54,126216,55,126324}, {0x3c9,312,91,126654,90,126836}, {0x3d1,276,96,127376,99,127568}, {0x3d5,311,63,128162,64,128288}, {0x3d6,381,95,128672,96,128862}, {0x3f0,275,77,129438,76,129592}, {0x3f1,250,63,130048,62,130174}, {0x3f5,219,51,130546,50,130648}, {0x410,356,47,130948,50,131042}, {0x411,305,63,131342,60,131468}, {0x412,325,92,131828,90,132012}, {0x413,285,38,132552,38,132628}, {0x414,332,71,132856,73,132998}, {0x415,314,56,133436,54,133548}, {0x416,510,145,133872,143,134162}, {0x417,287,90,135020,89,135200}, {0x418,361,58,135734,55,135850}, {0x419,361,107,136180,104,136394}, {0x41a,344,100,137018,99,137218}, {0x41b,341,64,137812,64,137940}, {0x41c,446,48,138324,47,138420}, {0x41d,362,60,138702,56,138822}, {0x41e,364,63,139158,60,139284}, {0x41f,362,52,139644,52,139748}, {0x420,285,65,140060,69,140190}, {0x421,338,71,140604,72,140746}, {0x422,309,32,141178,30,141242}, {0x423,355,75,141422,78,141572}, {0x424,384,76,142040,77,142192}, {0x425,358,82,142654,80,142818}, {0x426,357,59,143298,63,143416}, {0x427,328,64,143794,63,143922}, {0x428,497,71,144300,78,144442}, {0x429,497,81,144910,89,145072}, {0x42a,368,53,145606,50,145712}, {0x42b,441,80,146012,75,146172}, {0x42c,305,51,146622,48,146724}, {0x42d,325,76,147012,76,147164}, {0x42e,450,93,147620,89,147806}, {0x42f,318,64,148340,64,148468}, {0x430,224,113,148852,114,149078}, {0x431,253,79,149762,78,149920}, {0x432,237,84,150388,84,150556}, {0x433,196,34,151060,32,151128}, {0x434,231,59,151320,64,151438}, {0x435,233,49,151822,48,151920}, {0x436,360,144,152208,148,152496}, {0x437,194,85,153384,88,153554}, {0x438,262,56,154082,55,154194}, {0x439,262,106,154524,103,154736}, {0x43a,251,85,155354,87,155524}, {0x43b,249,63,156046,64,156172}, {0x43c,308,48,156556,48,156652}, {0x43d,262,58,156940,56,157056}, {0x43e,256,53,157392,50,157498}, {0x43f,262,52,157798,52,157902}, {0x440,249,71,158214,72,158356}, {0x441,228,63,158788,60,158914}, {0x442,217,40,159274,38,159354}, {0x443,245,69,159582,73,159720}, {0x444,338,134,160158,136,160426}, {0x445,244,77,161242,81,161396}, {0x446,262,57,161882,59,161996}, {0x447,256,62,162350,63,162474}, {0x448,383,76,162852,78,163004}, {0x449,383,82,163472,85,163636}, {0x44a,269,56,164146,54,164258}, {0x44b,334,77,164582,75,164736}, {0x44c,228,49,165186,48,165284}, {0x44d,222,54,165572,55,165680}, {0x44e,368,81,166010,79,166172}, {0x44f,235,59,166646,59,166764}, {0x210f,289,94,167118,101,167306}, {0x2111,381,130,167912,125,168172}, {0x2113,383,82,168922,83,169086}, {0x211c,436,132,169584,135,169848}, {0x2190,463,40,170658,44,170738}, {0x2191,255,39,171002,44,171080}, {0x2192,463,41,171344,44,171426}, {0x2193,255,38,171690,44,171766}, {0x2194,463,75,172030,86,172180}, {0x2195,255,74,172696,86,172844}, {0x2196,463,50,173360,66,173460}, {0x2197,463,50,173856,65,173956}, {0x2198,463,45,174346,63,174436}, {0x2199,463,49,174814,64,174912}, {0x2200,280,12,175296,11,175320}, {0x2201,231,48,175386,47,175482}, {0x2202,235,70,175764,72,175904}, {0x2203,280,12,176336,10,176360}, {0x2204,280,30,176420,30,176480}, {0x2205,381,70,176660,70,176800}, {0x2206,365,8,177220,7,177236}, {0x2207,365,8,177278,7,177294}, {0x2208,342,29,177336,27,177394}, {0x2209,342,52,177556,56,177660}, {0x220a,242,29,177996,27,178054}, {0x220b,342,30,178216,27,178276}, {0x220c,342,56,178438,55,178550}, {0x220d,242,29,178880,28,178938}, {0x220e,272,4,179106,2,179114}, {0x220f,500,49,179126,47,179224}, {0x2210,500,49,179506,47,179604}, {0x2211,457,22,179886,20,179930}, {0x2212,342,4,180050,2,180058}, {0x2213,342,17,180070,10,180104}, {0x2214,342,34,180164,26,180232}, {0x2215,261,4,180388,2,180396}, {0x2216,213,4,180408,2,180416}, {0x2217,261,135,180428,133,180698}, {0x2218,175,43,181496,40,181582}, {0x2219,175,21,181822,18,181864}, {0x221a,463,19,181972,18,182010}, {0x221b,463,93,182118,93,182304}, {0x221c,463,35,182862,30,182932}, {0x221d,342,65,183112,65,183242}, {0x221e,463,85,183632,85,183802}, {0x221f,342,6,184312,4,184324}, {0x2220,342,6,184348,4,184360}, {0x2221,342,33,184384,42,184450}, {0x2222,342,48,184702,52,184798}, {0x2223,132,4,185110,2,185118}, {0x2224,202,12,185130,8,185154}, {0x2225,261,9,185202,4,185220}, {0x2226,304,20,185244,14,185284}, {0x2227,310,7,185368,5,185382}, {0x2228,310,7,185412,5,185426}, {0x2229,310,26,185456,25,185508}, {0x222a,310,26,185658,24,185710}, {0x222b,229,67,185854,70,185988}, {0x222c,350,137,186408,140,186682}, {0x222d,471,205,187522,210,187932}, {0x222e,249,117,189192,126,189426}, {0x222f,370,209,190182,232,190600}, {0x2260,342,20,191992,18,192032}, {0x2261,342,14,192140,6,192168}, {0x2262,342,28,192204,26,192260}, {0x2263,342,19,192416,8,192454}, {0x2264,342,12,192502,7,192526}, {0x2265,342,12,192568,7,192592}, {0x2266,342,17,192634,9,192668}, {0x2267,342,17,192722,9,192756}, {0x2268,342,28,192810,23,192866}, {0x2269,342,28,193004,23,193060}, {0x226a,466,15,193198,10,193228}, {0x226b,466,15,193288,10,193318}, {0x226c,233,80,193378,84,193538}, {0x226d,342,55,194042,60,194152}, {0x226e,342,20,194512,19,194552}, {0x226f,342,20,194666,19,194706}, {0x27c2,346,8,194820,6,194836}, }; short mgl_buf_fnt[194872] = { 88,88,94,88,117,278,117,282,118,286,118,297,117,311,113,322,108,331,101,336,92,338,81,336,74,331,69,323,66,312,65,300,65,289,66,284,66,278,16383,16383,118,21,116,30,113,37,107,43,100,47,92,49,83,47,76,43,70,37,66,30,65,22,66,13,70,6,75,0,82,-2,91,-3,100,-2,107,0,113,6,116,13,118,21, 107,43,107,0,113,37,113,37,107,0,113,6,113,37,113,6,116,30,116,30,113,6,116,13,116,30,116,13,118,21,65,22,66,13,66,30,66,30,66,13,70,6,66,30,70,6,70,37,70,37,70,6,75,0,70,37,75,0,76,43,76,43,75,0,82,-2,76,43,82,-2,83,47,83,47,82,-2,91,-3,83,47,91,-3,92,49,92,49,91,-3,100,-2,92,49,100,-2,100,47,100,47,100,-2,107,0,100,47,107,0,107,43,118,297,117,311,117,278,118,297,117,278,117,282,118,297,117,282,118,286,118,297,118,286,118,290,118,297,118,290,118,294,117,278,117,311,113,322,117,278,113,322,108,331,117,278,108,331,101,336,117,278,101,336,94,88,92,338,81,336,88,88,92,338,88,88,94,88,92,338,94,88,101,336,66,284,66,278,69,323,69,323,66,278,88,88,69,323,88,88,74,331,74,331,88,88,81,336,66,312,65,300,65,297,66,312,65,297,65,293,66,312,65,293,65,289,66,312,65,289,66,284,66,312,66,284,69,323, 150,215,154,243,158,268,162,289,165,306,166,318,165,324,162,330,157,334,151,337,145,338,138,337,132,334,127,330,124,324,123,316,124,307,126,291,129,270,134,244,139,215,16383,16383,65,215,70,243,75,268,78,289,80,306,81,318,80,324,77,330,73,334,67,337,60,338,53,337,47,334,42,330,40,324,39,316,39,307,42,291,45,270,50,244,55,215, 123,316,124,307,124,324,124,324,124,307,126,291,124,324,126,291,127,330,127,330,126,291,129,270,127,330,129,270,132,334,132,334,129,270,134,244,132,334,134,244,138,337,138,337,134,244,139,215,138,337,139,215,145,338,145,338,139,215,150,215,145,338,150,215,151,337,151,337,150,215,154,243,151,337,154,243,157,334,157,334,154,243,158,268,157,334,158,268,162,330,162,330,158,268,162,289,162,330,162,289,165,324,165,324,162,289,165,306,165,324,165,306,166,318,39,316,39,307,40,324,40,324,39,307,42,291,40,324,42,291,42,330,42,330,42,291,45,270,42,330,45,270,47,334,47,334,45,270,50,244,47,334,50,244,53,337,53,337,50,244,55,215,53,337,55,215,60,338,60,338,55,215,65,215,60,338,65,215,67,337,67,337,65,215,70,243,67,337,70,243,73,334,73,334,70,243,75,268,73,334,75,268,77,330,77,330,75,268,78,289,77,330,78,289,80,324,80,324,78,289,80,306,80,324,80,306,81,318, 248,203,248,230,200,230,214,331,185,331,171,230,104,230,119,331,90,331,75,230,17,230,17,203,71,203,60,136,3,136,3,108,56,108,40,0,69,0,85,108,152,108,137,0,166,0,181,108,235,108,235,136,185,136,195,203,16383,16383,166,203,156,136,89,136,100,203, 90,331,75,230,85,108,85,108,75,230,71,203,85,108,71,203,69,0,69,0,71,203,60,136,69,0,60,136,56,108,56,108,60,136,3,136,56,108,3,136,3,108,17,230,17,203,71,203,17,230,71,203,75,230,90,331,85,108,89,136,90,331,89,136,100,203,90,331,100,203,104,230,90,331,104,230,119,331,185,331,171,230,181,108,181,108,171,230,166,203,181,108,166,203,166,0,166,0,166,203,156,136,166,0,156,136,152,108,152,108,156,136,89,136,152,108,89,136,85,108,104,230,100,203,166,203,104,230,166,203,171,230,200,230,214,331,195,203,195,203,214,331,185,331,195,203,185,331,185,136,185,136,185,331,181,108,185,136,181,108,235,108,200,230,195,203,248,203,200,230,248,203,248,230,185,136,235,108,235,136,166,0,152,108,137,0,69,0,56,108,40,0, 132,319,154,314,172,304,186,291,197,273,205,250,213,250,213,305,202,314,189,321,173,326,155,330,132,332,132,363,115,363,115,332,88,328,64,319,44,304,31,283,26,257,29,234,38,214,54,196,79,177,115,155,115,14,90,17,69,27,52,42,38,63,30,90,22,90,22,26,38,16,54,9,71,4,91,1,115,0,115,-43,132,-43,132,0,164,6,191,17,211,32,224,54,229,85,228,96,227,105,225,115,222,123,219,130,210,141,199,152,185,164,163,178,132,195,16383,16383,115,204,93,219,79,232,69,243,64,254,63,266,65,281,71,293,81,304,96,313,115,319,16383,16383,132,147,156,132,172,118,182,105,188,90,189,74,187,55,181,40,170,28,154,20,132,14, 132,319,154,314,155,330,155,330,154,314,172,304,155,330,172,304,173,326,173,326,172,304,186,291,173,326,186,291,189,321,189,321,186,291,197,273,189,321,197,273,202,314,202,314,197,273,205,250,202,314,205,250,213,305,213,305,205,250,213,250,228,96,227,105,229,85,229,85,227,105,225,115,229,85,225,115,224,54,224,54,225,115,222,123,224,54,222,123,219,130,211,32,224,54,219,130,211,32,219,130,210,141,211,32,210,141,199,152,211,32,199,152,191,17,191,17,199,152,189,74,191,17,189,74,187,55,191,17,187,55,181,40,191,17,181,40,170,28,191,17,170,28,164,6,188,90,189,74,199,152,188,90,199,152,185,164,188,90,185,164,182,105,132,147,156,132,163,178,163,178,156,132,172,118,163,178,172,118,185,164,185,164,172,118,182,105,132,14,132,147,132,195,132,14,132,195,115,155,132,14,115,155,132,-43,132,332,132,363,115,155,132,332,115,155,132,195,132,332,132,195,132,319,132,332,132,319,155,330,115,0,115,155,115,14,115,0,115,14,91,1,91,1,115,14,90,17,91,1,90,17,71,4,71,4,90,17,69,27,71,4,69,27,54,9,54,9,69,27,52,42,54,9,52,42,38,63,38,16,54,9,38,63,38,16,38,63,30,90,38,16,30,90,22,90,38,16,22,90,22,26,132,363,115,363,115,319,115,319,115,363,115,332,115,319,115,155,132,363,71,293,81,304,88,328,88,328,81,304,96,313,88,328,96,313,115,332,115,332,96,313,115,319,64,319,44,304,54,196,64,319,54,196,63,266,64,319,63,266,65,281,64,319,65,281,71,293,64,319,71,293,88,328,63,266,54,196,64,254,64,254,54,196,79,177,64,254,79,177,69,243,69,243,79,177,79,232,26,257,29,234,31,283,31,283,29,234,38,214,31,283,38,214,44,304,44,304,38,214,54,196,79,232,79,177,93,219,93,219,79,177,115,155,93,219,115,155,115,204,115,204,115,155,115,319,164,6,170,28,154,20,164,6,154,20,132,14,164,6,132,14,132,0,132,-43,115,155,115,0,132,-43,115,0,115,-43,132,195,132,147,163,178, 343,107,341,127,335,143,325,155,312,163,295,165,267,159,241,143,220,120,206,91,200,60,203,38,212,18,225,4,242,-5,261,-8,286,-2,309,14,327,39,339,71,343,107,16383,16383,331,108,328,77,318,48,303,25,285,10,265,4,255,6,248,10,242,18,238,27,237,38,239,59,244,82,252,103,263,123,276,140,280,144,284,147,290,149,295,151,300,151,311,149,319,143,326,134,330,122,331,108,16383,16383,310,353,289,353,265,331,248,317,235,309,221,305,194,305,185,307,176,311,167,317,157,324,150,330,144,334,138,336,133,338,127,338,97,332,71,317,50,293,36,264,31,232,34,209,42,191,54,176,70,166,89,163,99,164,108,166,116,169,132,181,146,197,157,215,165,234,171,255,172,276,172,289,171,294,171,299,179,296,187,294,194,292,201,292,209,291,223,292,236,295,247,301,258,309,269,320,72,-8,95,-8,16383,16383,161,285,157,251,148,222,133,198,115,182,94,176,85,178,77,183,71,190,67,200,66,211,67,228,70,245,75,262,82,278,90,293,95,302,101,309,107,314,115,319,126,325,135,316,140,312,144,310,148,307,153,305,157,301,159,297,160,292,161,285, 326,134,330,122,335,143,335,143,330,122,331,108,339,71,331,108,328,77,339,71,328,77,327,39,327,39,328,77,318,48,327,39,318,48,309,14,309,14,318,48,303,25,309,14,303,25,286,-2,286,-2,303,25,285,10,286,-2,285,10,265,4,265,4,255,6,261,-8,261,-8,255,6,248,10,261,-8,248,10,242,18,242,-5,261,-8,242,18,242,-5,242,18,238,27,242,-5,238,27,237,38,242,-5,237,38,225,4,244,82,252,103,267,159,267,159,252,103,263,123,267,159,263,123,276,140,276,140,280,144,295,165,295,165,280,144,284,147,295,165,284,147,290,149,241,143,220,120,225,4,241,143,225,4,237,38,241,143,237,38,239,59,241,143,239,59,244,82,241,143,244,82,267,159,200,60,203,38,206,91,206,91,203,38,212,18,206,91,212,18,220,120,220,120,212,18,225,4,326,134,325,155,319,143,319,143,325,155,312,163,319,143,312,163,311,149,311,149,312,163,300,151,295,151,300,151,295,165,295,151,295,165,290,149,295,165,267,159,276,140,312,163,295,165,300,151,339,71,343,107,341,127,339,71,341,127,335,143,339,71,335,143,331,108,265,4,261,-8,286,-2,67,228,70,245,71,317,71,317,70,245,75,262,71,317,75,262,97,332,97,332,75,262,82,278,97,332,82,278,90,293,90,293,95,302,97,332,97,332,95,302,101,309,97,332,101,309,127,338,127,338,101,309,107,314,127,338,107,314,115,319,77,183,89,163,85,178,85,178,89,163,94,176,115,182,94,176,99,164,115,182,99,164,108,166,71,190,67,200,70,166,71,190,70,166,89,163,71,190,89,163,77,183,67,200,66,211,70,166,70,166,66,211,54,176,54,176,66,211,71,317,71,317,66,211,67,228,148,307,153,305,150,330,148,307,150,330,144,310,144,310,150,330,144,334,144,310,144,334,140,312,140,312,144,334,138,336,140,312,138,336,135,316,135,316,138,336,133,338,135,316,133,338,131,320,131,320,133,338,127,338,131,320,127,338,126,325,247,301,248,317,236,295,236,295,248,317,235,309,236,295,235,309,223,292,223,292,235,309,221,305,223,292,221,305,209,291,209,291,221,305,205,305,194,305,185,307,187,294,194,305,187,294,194,292,194,305,194,292,201,292,194,305,201,292,205,305,176,311,171,299,179,296,176,311,179,296,185,307,185,307,179,296,187,294,167,317,157,324,157,301,167,317,157,301,159,297,167,317,159,297,160,292,167,317,160,292,161,285,167,317,161,285,165,234,167,317,165,234,171,255,167,317,171,255,171,299,167,317,171,299,176,311,124,175,132,181,133,198,133,198,132,181,146,197,133,198,146,197,148,222,148,222,146,197,157,215,148,222,157,215,157,251,157,251,157,215,165,234,157,251,165,234,161,285,310,353,289,353,269,320,269,320,289,353,265,331,269,320,265,331,258,309,258,309,265,331,248,317,258,309,248,317,247,301,269,320,72,-8,95,-8,269,320,95,-8,310,353,172,276,172,281,172,285,172,276,172,285,172,289,172,276,172,289,171,294,172,276,171,294,171,299,172,276,171,299,171,255,116,169,124,175,133,198,116,169,133,198,115,182,116,169,115,182,108,166,157,324,150,330,153,305,157,324,153,305,157,301,31,232,34,209,36,264,36,264,34,209,42,191,36,264,42,191,50,293,50,293,42,191,54,176,50,293,54,176,71,317,94,176,89,163,99,164,127,338,115,319,126,325,209,291,205,305,201,292,325,155,326,134,335,143, 368,55,359,45,350,38,342,33,332,30,321,29,304,31,288,36,274,46,259,58,246,75,260,96,273,115,284,134,296,152,309,173,316,184,323,192,332,198,342,201,355,203,355,213,248,213,248,203,261,201,270,197,276,193,279,187,280,179,278,165,273,150,264,133,251,113,234,89,218,107,205,126,192,146,180,167,168,192,199,207,221,222,235,238,243,256,246,276,242,298,233,315,218,328,199,335,177,338,153,335,132,325,116,309,105,288,101,263,101,250,103,237,106,223,111,207,118,189,99,177,72,158,50,138,34,116,24,92,21,69,25,42,36,20,53,5,77,-3,107,-6,130,-4,151,0,172,9,193,22,214,39,233,22,250,9,266,0,283,-4,300,-6,319,-3,336,3,352,14,365,30,375,50,16383,16383,219,278,217,261,211,246,200,233,183,220,161,208,152,225,146,239,143,253,141,266,141,281,142,294,148,306,156,315,167,320,180,322,193,320,204,314,212,304,217,292,219,278,16383,16383,202,52,185,40,170,31,155,25,142,21,129,20,109,23,92,31,79,45,70,64,67,87,69,106,75,124,86,140,103,155,126,171,142,141,156,115,170,92,202,52, 153,335,132,325,142,294,142,294,132,325,141,281,142,141,141,281,132,325,142,141,132,325,126,171,118,189,103,155,126,171,118,189,126,171,132,325,118,189,132,325,116,309,118,189,116,309,111,207,99,177,72,158,75,124,99,177,75,124,86,140,99,177,86,140,103,155,99,177,103,155,118,189,72,158,50,138,53,5,72,158,53,5,67,87,72,158,67,87,69,106,72,158,69,106,75,124,79,45,70,64,77,-3,77,-3,70,64,67,87,53,5,50,138,36,20,36,20,50,138,34,116,36,20,34,116,25,42,25,42,34,116,24,92,25,42,24,92,21,69,101,250,103,237,105,288,105,288,103,237,106,223,105,288,106,223,116,309,116,309,106,223,111,207,185,40,170,31,172,9,172,9,170,31,155,25,172,9,155,25,151,0,151,0,155,25,142,21,151,0,142,21,130,-4,130,-4,142,21,129,20,109,23,92,31,107,-6,109,23,107,-6,130,-4,109,23,130,-4,129,20,79,45,77,-3,107,-6,79,45,107,-6,92,31,246,75,251,113,234,89,246,75,234,89,250,9,250,9,234,89,233,22,233,22,234,89,218,107,233,22,218,107,214,39,214,39,218,107,205,126,214,39,205,126,202,52,202,52,205,126,192,146,202,52,192,146,186,72,186,72,192,146,180,167,186,72,180,167,170,92,170,92,180,167,168,192,170,92,168,192,161,208,156,115,170,92,161,208,156,115,161,208,152,225,156,115,152,225,146,239,156,115,146,239,143,253,156,115,143,253,142,141,141,266,141,281,142,141,141,266,142,141,143,253,142,294,148,306,153,335,153,335,148,306,156,315,153,335,156,315,177,338,177,338,156,315,167,320,177,338,167,320,180,322,180,322,193,320,199,335,199,335,193,320,204,314,199,335,204,314,218,328,218,328,204,314,212,304,218,328,212,304,217,292,217,261,221,222,219,278,219,278,221,222,233,315,233,315,221,222,235,238,233,315,235,238,242,298,242,298,235,238,243,256,242,298,243,256,246,276,218,328,217,292,219,278,218,328,219,278,233,315,199,335,177,338,180,322,183,220,168,192,199,207,183,220,199,207,200,233,200,233,199,207,221,222,200,233,221,222,211,246,211,246,221,222,217,261,183,220,161,208,168,192,193,22,214,39,202,52,193,22,202,52,185,40,193,22,185,40,172,9,246,75,250,9,259,58,259,58,250,9,266,0,259,58,266,0,274,46,274,46,266,0,283,-4,274,46,283,-4,288,36,288,36,283,-4,300,-6,288,36,300,-6,304,31,304,31,300,-6,319,-3,304,31,319,-3,321,29,321,29,319,-3,336,3,321,29,336,3,332,30,270,197,276,193,355,213,355,213,276,193,279,187,355,213,279,187,280,179,280,179,284,134,296,152,280,179,296,152,309,173,309,173,316,184,280,179,280,179,316,184,323,192,280,179,323,192,332,198,342,201,355,203,355,213,342,201,355,213,332,198,332,198,355,213,280,179,261,201,270,197,355,213,261,201,355,213,248,213,261,201,248,213,248,203,280,179,278,165,284,134,284,134,278,165,273,150,284,134,273,150,273,115,273,115,273,150,264,133,273,115,264,133,260,96,260,96,264,133,251,113,260,96,251,113,246,75,375,50,368,55,365,30,365,30,368,55,359,45,365,30,359,45,352,14,352,14,359,45,350,38,352,14,350,38,342,33,342,33,332,30,336,3,342,33,336,3,352,14,77,-3,67,87,53,5,101,250,105,288,101,263, 50,215,56,244,60,269,64,290,66,306,66,324,63,330,59,334,53,337,46,338,39,337,33,334,28,330,25,324,24,317,25,306,27,289,31,268,35,243,40,215, 24,317,25,306,25,324,25,324,25,306,27,289,25,324,27,289,28,330,28,330,27,289,31,268,28,330,31,268,33,334,33,334,31,268,35,243,33,334,35,243,39,337,39,337,35,243,40,215,39,337,40,215,46,338,46,338,40,215,50,215,46,338,50,215,53,337,53,337,50,215,56,244,53,337,56,244,59,334,59,334,56,244,60,269,59,334,60,269,63,330,63,330,60,269,64,290,63,330,64,290,66,324,66,324,64,290,66,306,66,324,66,306,66,318, 152,-79,116,-44,92,-8,77,31,69,76,67,127,69,180,77,223,92,261,116,295,152,330,147,338,104,307,69,270,44,227,29,179,24,126,29,75,44,27,69,-17,103,-56,146,-88, 24,126,29,75,29,179,29,179,29,75,44,27,29,179,44,27,44,227,44,227,44,27,69,-17,44,227,69,-17,67,127,67,127,69,270,44,227,116,295,152,330,147,338,116,295,147,338,104,307,116,295,104,307,92,261,67,127,69,180,69,270,69,270,69,180,77,223,69,270,77,223,104,307,104,307,77,223,92,261,116,-44,92,-8,103,-56,116,-44,103,-56,146,-88,116,-44,146,-88,152,-79,77,31,69,76,69,-17,77,31,69,-17,103,-56,77,31,103,-56,92,-8,67,127,69,-17,69,76, 15,330,51,295,76,259,90,219,97,174,99,122,97,69,90,26,75,-11,51,-45,15,-79,19,-88,62,-56,97,-19,122,23,137,71,142,123,137,174,121,222,96,267,63,306,21,338, 97,174,99,122,99,122,122,23,99,122,97,69,122,23,97,69,97,-19,97,-19,97,69,90,26,97,-19,90,26,75,-11,97,174,99,122,121,222,121,222,99,122,122,23,121,222,122,23,137,174,137,174,122,23,137,71,137,174,137,71,142,123,96,267,63,306,76,259,96,267,76,259,90,219,96,267,90,219,97,174,96,267,97,174,121,222,51,295,76,259,63,306,51,295,63,306,21,338,51,295,21,338,15,330,15,-79,19,-88,51,-45,51,-45,19,-88,62,-56,51,-45,62,-56,75,-11,75,-11,62,-56,97,-19, 134,235,147,243,158,248,178,254,190,256,200,258,207,261,212,265,215,270,216,277,215,284,213,289,209,293,204,295,198,296,190,294,183,288,174,281,166,272,159,264,154,259,144,251,130,243,130,262,131,270,133,278,135,287,140,302,142,307,143,312,144,316,144,320,143,326,140,331,136,335,131,337,126,338,120,337,115,335,111,331,109,326,108,321,108,317,110,307,111,301,113,295,115,285,118,276,121,249,121,243,110,249,101,255,93,262,85,270,76,280,70,286,65,290,60,293,56,295,51,296,46,295,41,292,38,288,36,283,35,277,36,270,40,265,46,261,56,257,69,254,78,252,87,249,97,246,106,242,117,235,106,229,97,224,88,221,78,218,65,215,53,213,45,210,39,205,35,200,34,193,35,187,37,182,41,178,46,176,52,175,57,176,61,177,65,179,74,188,81,196,92,207,94,210,97,212,105,218,112,222,121,228,121,224,120,212,119,201,118,192,115,183,113,174,111,169,109,163,108,159,107,154,107,151,108,145,110,140,114,136,119,133,124,132,130,133,136,136,140,141,143,146,145,152,144,154,144,157,143,161,141,164,140,169,136,179,130,212,130,228,134,225,140,221,147,217,153,212,161,205,169,196,175,188,182,182,187,178,193,175,199,175,205,176,210,178,216,188,217,194,215,201,212,206,206,210,198,213,186,215,176,218,165,220,147,228,138,233, 69,254,69,254,78,252,69,254,78,252,70,286,69,254,70,286,65,290,69,254,65,290,60,293,69,254,60,293,56,295,69,254,56,295,56,257,51,296,46,295,46,261,51,296,46,261,56,257,51,296,56,257,56,295,36,283,36,270,38,288,38,288,36,270,40,265,38,288,40,265,41,292,41,292,40,265,46,261,41,292,46,261,46,295,81,196,86,201,88,221,88,221,86,201,89,204,88,221,89,204,97,224,97,224,89,204,92,207,97,224,92,207,94,210,94,210,97,212,97,224,97,224,97,212,106,229,78,218,65,215,69,183,78,218,69,183,74,188,78,218,74,188,81,196,78,218,81,196,88,221,110,140,114,136,111,169,111,169,114,136,113,174,115,183,113,174,114,136,115,183,114,136,119,133,144,157,143,161,143,146,144,157,143,146,145,152,144,157,145,152,144,154,141,164,140,169,140,141,141,164,140,141,143,146,141,164,143,146,143,161,136,179,134,190,136,136,136,179,136,136,140,141,136,179,140,141,140,169,134,190,132,201,136,136,136,136,132,201,130,212,136,136,130,212,130,133,130,133,130,212,130,224,126,338,120,337,120,258,126,338,120,258,121,249,126,338,121,249,121,228,126,338,121,228,124,132,126,338,124,132,130,133,126,338,130,133,130,224,126,338,130,224,130,243,126,338,130,243,130,255,126,338,130,255,131,337,121,243,121,228,121,249,120,337,115,335,115,285,120,337,115,285,118,276,120,337,118,276,119,267,120,337,119,267,120,258,113,295,115,285,115,335,113,295,115,335,111,331,113,295,111,331,111,301,204,295,198,296,200,258,200,258,198,296,190,294,200,258,190,294,190,256,190,256,190,294,183,288,190,256,183,288,178,254,178,254,183,288,174,281,178,254,174,281,168,251,168,251,174,281,166,272,168,251,166,272,159,264,159,264,154,259,158,248,158,248,154,259,149,255,158,248,149,255,147,243,147,243,149,255,144,251,147,243,144,251,137,247,130,243,130,228,134,225,130,243,134,225,134,235,130,243,134,235,137,247,137,247,134,235,147,243,176,218,165,220,169,196,176,218,169,196,175,188,176,218,175,188,182,182,176,218,182,182,186,215,199,175,205,176,206,210,206,210,205,176,210,178,206,210,210,178,212,206,212,206,210,178,213,183,212,206,213,183,215,201,215,201,213,183,216,188,215,201,216,188,217,194,198,213,186,215,187,178,198,213,187,178,193,175,198,213,193,175,199,175,198,213,199,175,206,210,216,277,215,284,215,270,215,270,215,284,213,289,215,270,213,289,212,265,212,265,213,289,209,293,212,265,209,293,207,261,207,261,209,293,204,295,207,261,204,295,200,258,159,264,158,248,168,251,161,205,169,196,165,220,161,205,165,220,156,224,161,205,156,224,153,212,147,228,138,233,140,221,147,228,140,221,147,217,147,228,147,217,153,212,147,228,153,212,156,224,143,326,140,331,142,307,143,326,142,307,143,312,143,326,143,312,144,316,143,326,144,316,144,320,133,278,135,287,136,335,136,335,135,287,138,296,136,335,138,296,140,331,140,331,138,296,140,302,140,331,140,302,142,307,131,337,130,255,130,262,131,337,130,262,131,270,131,337,131,270,133,278,131,337,133,278,136,335,134,235,134,225,140,221,134,235,140,221,138,233,124,132,121,228,121,224,124,132,121,224,120,212,124,132,120,212,119,201,124,132,119,201,119,133,118,192,115,183,119,133,118,192,119,133,119,201,101,215,105,218,106,229,106,229,105,218,112,222,106,229,112,222,117,235,117,235,112,222,121,228,117,235,121,228,121,243,76,280,78,252,85,270,85,270,78,252,87,249,85,270,87,249,93,262,93,262,87,249,97,246,93,262,97,246,101,255,101,255,97,246,106,242,101,255,106,242,110,249,110,249,106,242,117,235,110,249,117,235,121,243,108,317,109,312,109,326,109,326,109,312,110,307,109,326,110,307,111,331,111,331,110,307,111,301,111,169,109,163,110,140,110,140,109,163,108,159,110,140,108,159,108,145,108,145,108,159,107,154,108,145,107,154,107,151,65,215,53,213,57,176,65,215,57,176,61,177,65,215,61,177,65,179,65,215,65,179,69,183,34,193,35,187,35,200,35,200,35,187,37,182,35,200,37,182,39,205,39,205,37,182,41,178,39,205,41,178,45,210,45,210,41,178,46,176,45,210,46,176,53,213,53,213,46,176,52,175,53,213,52,175,57,176,70,286,78,252,76,280,106,229,97,212,101,215,108,317,109,326,108,321,187,178,186,215,182,182,36,270,36,283,35,277, 318,110,318,143,188,143,188,273,155,273,155,143,24,143,24,110,155,110,155,-20,188,-20,188,110, 188,273,155,273,188,-20,188,-20,155,273,155,143,188,-20,155,143,155,110,155,110,155,143,24,143,155,110,24,143,24,110,188,110,318,110,188,143,188,143,318,110,318,143,188,-20,155,110,155,-20, 41,-69,60,-58,76,-44,88,-27,95,-10,98,7,96,22,90,34,81,43,70,49,57,51,47,49,39,46,33,40,29,32,27,22,29,13,32,6,38,1,46,-1,56,-2,60,-2,63,-1,66,-1,68,0,73,0,75,-1,78,-4,78,-6,76,-16,71,-27,63,-38,51,-49,36,-60, 63,-1,66,-1,70,49,70,49,66,-1,68,0,70,49,68,0,71,0,71,0,73,0,81,43,81,43,73,0,75,-1,81,43,75,-1,77,-3,27,22,29,13,29,32,29,32,29,13,32,6,29,32,32,6,33,40,33,40,32,6,38,1,33,40,38,1,39,46,39,46,38,1,46,-1,39,46,46,-1,47,49,47,49,46,-1,56,-2,47,49,56,-2,57,51,57,51,56,-2,60,-2,57,51,60,-2,70,49,70,49,60,-2,63,-1,98,7,96,22,95,-10,95,-10,96,22,90,34,95,-10,90,34,88,-27,88,-27,90,34,81,43,88,-27,81,43,78,-6,78,-6,76,-16,88,-27,88,-27,76,-16,76,-44,81,43,77,-3,78,-4,81,43,78,-4,78,-6,81,43,70,49,71,0,36,-60,41,-69,51,-49,51,-49,41,-69,60,-58,51,-49,60,-58,63,-38,63,-38,60,-58,76,-44,63,-38,76,-44,71,-27,71,-27,76,-44,76,-16, 142,97,142,128,20,128,20,97, 142,97,142,128,20,128,142,97,20,128,20,97, 90,22,89,30,85,38,79,44,71,49,63,50,54,49,46,45,40,39,37,31,35,22,37,13,40,6,46,0,54,-3,63,-5,71,-3,79,0,85,6,89,13,90,22, 35,22,37,13,37,31,37,31,37,13,40,6,37,31,40,6,40,39,40,39,40,6,46,0,40,39,46,0,46,45,46,45,46,0,54,-3,46,45,54,-3,54,49,54,49,54,-3,62,-5,54,49,62,-5,63,50,63,50,62,-5,71,-3,63,50,71,-3,71,49,71,49,71,-3,79,0,71,49,79,0,79,44,79,44,79,0,85,6,79,44,85,6,85,38,85,38,85,6,89,13,85,38,89,13,89,30,89,30,89,13,90,22, 143,338,110,338,-3,-6,30,-6, 143,338,110,338,-3,-6,143,338,-3,-6,30,-6, 238,165,232,222,218,270,194,307,164,330,127,338,84,329,52,304,29,266,16,220,12,168,16,118,27,71,48,31,80,3,125,-6,168,2,200,29,222,67,234,114,238,165,16383,16383,190,162,187,108,179,65,166,33,148,13,125,6,102,13,84,33,71,65,63,109,60,165,63,220,71,265,84,298,101,318,124,325,148,318,166,298,179,265,187,219,190,162, 101,318,124,325,124,325,127,338,124,325,148,318,127,338,148,318,164,330,164,330,148,318,166,298,164,330,166,298,194,307,194,307,166,298,179,265,194,307,179,265,187,219,166,33,168,2,179,65,179,65,168,2,200,29,179,65,200,29,187,108,187,108,200,29,190,162,194,307,190,162,200,29,194,307,200,29,218,270,218,270,200,29,222,67,218,270,222,67,232,222,232,222,222,67,234,114,232,222,234,114,238,165,125,6,125,-6,148,13,148,13,125,-6,168,2,148,13,168,2,166,33,71,265,84,298,84,329,84,329,84,298,101,318,84,329,101,318,127,338,127,338,101,318,124,325,12,168,16,118,16,220,16,220,16,118,27,71,16,220,27,71,29,266,29,266,27,71,48,31,29,266,48,31,52,304,52,304,48,31,63,109,52,304,63,109,60,165,60,165,63,220,52,304,52,304,63,220,71,265,52,304,71,265,84,329,102,13,84,33,80,3,102,13,80,3,125,-6,102,13,125,-6,125,6,80,3,84,33,71,65,80,3,71,65,63,109,80,3,63,109,48,31,194,307,187,219,190,162, 197,0,197,7,178,8,164,12,155,18,151,27,150,38,150,336,145,338,55,292,55,286,69,291,74,293,84,295,88,296,92,296,97,295,101,293,104,288,106,281,107,272,107,47,105,33,100,22,92,14,78,10,59,7,59,0, 100,22,92,14,197,0,197,0,92,14,78,10,197,0,78,10,59,7,79,294,84,295,145,338,145,338,84,295,88,296,145,338,88,296,92,296,92,296,97,295,145,338,145,338,97,295,101,293,145,338,101,293,104,288,164,12,155,18,107,47,107,47,155,18,151,27,107,47,151,27,107,272,106,281,107,272,145,338,106,281,145,338,104,288,145,338,55,292,69,291,145,338,69,291,74,293,145,338,74,293,79,294,150,38,150,336,145,338,150,38,145,338,107,272,150,38,107,272,151,27,197,0,197,7,178,8,197,0,178,8,164,12,197,0,164,12,105,33,197,0,105,33,100,22,197,0,59,7,59,0,105,33,164,12,107,47,69,291,55,292,55,286, 237,69,230,71,221,57,212,48,203,42,193,39,182,38,65,38,147,126,171,153,189,179,202,203,209,226,211,250,207,278,195,302,176,321,150,334,119,338,86,333,59,320,39,299,24,271,15,238,26,236,38,262,50,280,63,292,79,299,99,301,123,298,142,289,156,275,165,255,169,230,166,205,159,181,146,155,128,129,103,100,15,6,15,0,210,0, 26,236,38,262,39,299,39,299,38,262,50,280,39,299,50,280,59,320,59,320,50,280,63,292,59,320,63,292,86,333,86,333,63,292,79,299,86,333,79,299,99,301,99,301,123,298,119,338,119,338,123,298,150,334,24,271,15,238,26,236,24,271,26,236,39,299,166,205,171,153,169,230,169,230,171,153,176,321,176,321,171,153,189,179,176,321,189,179,195,302,195,302,189,179,202,203,195,302,202,203,207,278,207,278,202,203,209,226,207,278,209,226,211,250,176,321,150,334,156,275,176,321,156,275,165,255,176,321,165,255,169,230,150,334,123,298,142,289,150,334,142,289,156,275,159,181,146,155,147,126,159,181,147,126,171,153,159,181,171,153,166,205,15,0,210,0,15,6,15,6,210,0,65,38,15,6,65,38,103,100,103,100,65,38,147,126,103,100,147,126,128,129,128,129,147,126,146,155,119,338,86,333,99,301,212,48,203,42,210,0,210,0,203,42,193,39,210,0,193,39,182,38,210,0,182,38,65,38,237,69,230,71,221,57,237,69,221,57,212,48,237,69,212,48,210,0, 31,255,43,275,57,290,71,300,87,306,105,308,123,306,138,300,149,290,157,275,159,257,157,240,152,224,143,211,132,199,118,190,112,186,105,183,96,179,87,176,76,172,76,165,92,165,104,164,113,163,121,162,127,160,146,152,161,141,171,127,178,109,180,88,176,63,167,42,153,26,135,15,114,11,106,11,99,13,90,15,82,20,71,26,64,31,57,35,51,38,41,40,34,39,29,36,25,32,22,27,21,22,23,12,30,4,41,-1,57,-5,76,-6,103,-4,130,0,154,9,175,22,193,40,200,52,207,65,211,79,214,94,215,109,214,125,212,139,207,152,201,164,194,174,187,180,181,185,173,190,164,195,152,200,170,213,183,226,192,241,197,255,199,270,195,292,184,311,168,326,146,335,121,338,92,334,68,323,48,306,33,284,22,257, 22,257,31,255,33,284,33,284,31,255,43,275,33,284,43,275,48,306,48,306,43,275,57,290,48,306,57,290,68,323,68,323,57,290,71,300,68,323,71,300,92,334,92,334,71,300,87,306,92,334,87,306,105,308,105,308,123,306,121,338,121,338,123,306,146,335,123,306,138,300,146,335,146,335,138,300,149,290,146,335,149,290,168,326,168,326,149,290,157,275,168,326,157,275,159,257,159,257,157,240,170,213,170,213,157,240,152,200,170,213,183,226,184,311,184,311,183,226,192,241,184,311,192,241,195,292,195,292,192,241,197,255,195,292,197,255,199,270,170,213,184,311,168,326,170,213,168,326,159,257,152,200,157,240,152,224,152,200,152,224,146,152,152,200,146,152,161,141,152,200,161,141,164,195,164,195,171,127,173,190,173,190,171,127,178,109,173,190,178,109,181,185,181,185,178,109,180,88,193,40,180,88,176,63,193,40,176,63,175,22,175,22,176,63,167,42,175,22,167,42,154,9,154,9,167,42,153,26,154,9,153,26,135,15,132,199,127,160,146,152,132,199,146,152,143,211,143,211,146,152,152,224,215,109,214,125,214,94,214,94,214,125,212,139,214,94,212,139,211,79,211,79,212,139,207,152,211,79,207,152,207,65,207,65,207,152,201,164,207,65,201,164,200,52,200,52,201,164,194,174,200,52,194,174,193,40,193,40,194,174,187,180,193,40,187,180,181,185,103,-4,130,0,106,11,106,11,130,0,114,11,135,15,114,11,130,0,135,15,130,0,154,9,87,176,76,172,92,165,87,176,92,165,96,179,96,179,92,165,104,164,96,179,104,164,105,183,105,183,104,164,113,163,105,183,113,163,112,186,112,186,113,163,118,190,132,199,118,190,121,162,132,199,121,162,127,160,121,338,92,334,105,308,118,190,113,163,121,162,103,-4,106,11,99,13,103,-4,99,13,90,15,103,-4,90,15,82,20,103,-4,82,20,76,-6,76,-6,82,20,71,26,76,-6,71,26,64,31,76,-6,64,31,57,35,76,-6,57,35,57,-5,57,35,51,38,57,-5,57,-5,51,38,46,39,57,-5,46,39,41,-1,41,-1,46,39,41,40,41,-1,41,40,34,39,30,4,41,-1,34,39,30,4,34,39,29,36,30,4,29,36,25,32,30,4,25,32,23,12,22,27,21,22,23,12,22,27,23,12,25,32,92,165,76,172,76,165,180,88,193,40,181,185,164,195,161,141,171,127, 237,84,237,116,185,116,185,338,163,338,6,116,6,84,146,84,146,0,185,0,185,84,16383,16383,146,116,26,116,146,287, 6,84,146,84,6,116,6,116,146,84,26,116,6,116,26,116,163,338,163,338,26,116,146,287,163,338,146,287,185,0,185,0,146,287,146,116,185,0,146,116,146,84,146,84,146,116,26,116,163,338,185,0,185,338,185,116,185,84,237,84,185,116,237,84,237,116,185,0,146,84,146,0, 219,340,214,344,210,339,206,335,202,333,197,331,87,331,32,213,32,208,34,206,38,206,65,204,89,199,110,191,129,182,145,171,156,159,166,146,172,131,177,114,178,96,174,71,164,48,149,29,131,16,110,12,104,12,98,14,90,17,83,21,75,27,66,34,58,39,51,41,45,43,38,43,30,42,24,40,19,36,17,31,16,24,19,13,27,5,40,-1,58,-5,79,-6,99,-5,117,-2,134,1,149,8,164,17,182,33,196,51,206,71,211,95,213,122,213,137,211,150,207,162,202,174,195,185,178,205,159,220,137,232,108,241,70,249,90,291,188,291,192,292,198,294,200,296,201,298, 211,95,213,122,213,137,211,95,213,137,211,150,211,95,211,150,207,162,211,95,207,162,206,71,178,205,178,96,182,33,178,205,182,33,195,185,195,185,182,33,196,51,195,185,196,51,202,174,202,174,196,51,206,71,202,174,206,71,207,162,149,8,164,17,164,48,164,48,164,17,182,33,164,48,182,33,174,71,174,71,182,33,178,96,110,12,117,-2,131,16,131,16,117,-2,134,1,131,16,134,1,149,29,149,29,134,1,149,8,149,29,149,8,164,48,202,333,197,331,198,294,202,333,198,294,200,296,202,333,200,296,201,298,202,333,201,298,219,340,202,333,219,340,206,335,190,331,192,292,197,331,197,331,192,292,195,293,197,331,195,293,198,294,210,339,206,335,219,340,210,339,219,340,214,344,87,331,70,249,90,291,87,331,90,291,190,331,190,331,90,291,188,291,190,331,188,291,192,292,38,206,65,204,70,249,70,249,65,204,89,199,70,249,89,199,108,241,108,241,89,199,110,191,108,241,110,191,137,232,137,232,110,191,129,182,137,232,129,182,145,171,145,171,156,159,159,220,159,220,156,159,166,146,159,220,166,146,178,205,178,205,166,146,172,131,178,205,172,131,177,114,87,331,32,213,33,207,87,331,33,207,34,206,87,331,34,206,36,206,87,331,36,206,38,206,87,331,38,206,70,249,32,213,32,212,33,207,33,207,32,212,32,208,32,208,32,212,32,211,79,-6,99,-5,83,21,79,-6,83,21,75,27,79,-6,75,27,66,34,79,-6,66,34,58,39,79,-6,58,39,58,-5,58,39,51,41,58,-5,58,-5,51,41,45,43,58,-5,45,43,40,-1,40,-1,45,43,38,43,40,-1,38,43,30,42,27,5,40,-1,30,42,27,5,30,42,24,40,27,5,24,40,19,36,27,5,19,36,19,13,17,31,16,24,19,13,17,31,19,13,19,36,104,12,98,14,99,-5,104,12,99,-5,117,-2,104,12,117,-2,110,12,159,220,137,232,145,171,90,17,83,21,99,-5,90,17,99,-5,98,14,178,205,177,114,178,96,32,208,32,211,32,210, 223,342,185,337,152,329,123,317,97,300,71,277,52,254,37,229,26,201,19,171,17,140,18,118,21,98,26,78,33,60,41,44,53,26,68,12,86,1,106,-4,129,-6,148,-5,166,0,182,7,196,17,209,30,218,43,225,57,230,73,233,91,234,109,230,145,217,174,198,196,172,209,140,214,127,213,115,211,103,207,90,201,76,191,89,234,111,270,142,300,180,321,224,334,16383,16383,189,94,187,65,180,41,169,23,154,11,134,7,109,13,89,30,75,56,66,91,64,133,67,157,76,173,89,184,105,189,122,191,146,187,165,175,179,156,187,128,189,94, 140,214,127,213,146,187,146,187,127,213,122,191,105,189,122,191,115,211,105,189,115,211,103,207,64,133,67,157,71,277,71,277,67,157,76,173,71,277,76,173,76,191,76,191,76,173,89,184,76,191,89,184,90,201,90,201,89,184,105,189,90,201,105,189,103,207,127,213,115,211,122,191,187,65,180,41,182,7,182,7,180,41,169,23,182,7,169,23,166,0,166,0,169,23,154,11,166,0,154,11,148,-5,148,-5,154,11,134,7,148,-5,134,7,129,-6,129,-6,134,7,109,13,129,-6,109,13,106,-4,106,-4,109,13,89,30,106,-4,89,30,86,1,86,1,89,30,75,56,86,1,75,56,68,12,68,12,75,56,66,91,68,12,66,91,64,133,53,26,68,12,64,133,64,133,71,277,53,26,53,26,71,277,52,254,53,26,52,254,41,44,41,44,52,254,37,229,41,44,37,229,33,60,33,60,37,229,26,78,218,43,225,57,230,145,230,145,225,57,230,73,230,145,230,73,234,109,234,109,230,73,233,91,189,94,196,17,198,196,198,196,196,17,209,30,198,196,209,30,217,174,217,174,209,30,218,43,217,174,218,43,230,145,146,187,165,175,172,209,172,209,165,175,179,156,172,209,179,156,198,196,198,196,179,156,187,128,198,196,187,128,189,94,187,65,182,7,196,17,187,65,196,17,189,94,76,191,89,234,97,300,97,300,89,234,111,270,97,300,111,270,123,317,123,317,111,270,142,300,123,317,142,300,152,329,152,329,142,300,180,321,152,329,180,321,185,337,185,337,180,321,224,334,185,337,224,334,223,342,97,300,71,277,76,191,17,140,18,118,19,171,19,171,18,118,21,98,19,171,21,98,26,201,26,201,21,98,26,78,26,201,26,78,37,229,140,214,146,187,172,209, 224,323,224,331,40,331,10,257,19,253,30,270,40,282,51,289,62,293,78,294,185,294,86,-3,118,-3, 118,-3,224,323,185,294,185,294,224,323,224,331,185,294,224,331,78,294,62,293,78,294,224,331,62,293,224,331,40,331,40,331,10,257,19,253,40,331,19,253,30,270,40,331,30,270,40,282,40,331,40,282,51,289,40,331,51,289,62,293,118,-3,185,294,86,-3, 223,78,220,100,213,121,199,141,177,162,145,185,171,200,190,215,203,229,210,246,212,267,208,289,197,309,179,324,156,334,128,338,97,335,70,324,49,308,36,287,31,260,33,242,38,225,49,208,67,189,93,166,66,145,47,127,35,111,30,94,28,75,32,48,45,25,66,8,92,-2,124,-6,157,-2,185,8,205,26,218,49,223,78,16383,16383,177,267,176,249,171,234,162,220,149,207,131,195,107,210,90,225,77,240,70,257,68,275,71,292,78,305,89,316,104,322,123,324,142,322,157,314,168,302,175,286,177,267,16383,16383,136,136,154,122,167,109,177,95,183,79,185,62,182,44,175,29,163,17,148,10,129,7,108,10,91,19,77,34,69,54,66,79,67,97,71,113,79,128,90,142,106,156, 167,109,177,162,154,122,154,122,177,162,145,185,154,122,145,185,136,136,136,136,145,185,149,207,136,136,149,207,131,195,131,195,107,210,136,136,136,136,107,210,106,156,90,142,106,156,93,166,66,8,69,54,66,79,66,79,67,97,66,145,66,145,67,97,71,113,66,145,71,113,93,166,93,166,71,113,79,128,93,166,79,128,90,142,30,94,32,48,35,111,35,111,32,48,45,25,35,111,45,25,47,127,47,127,45,25,66,8,47,127,66,8,66,145,66,145,66,8,66,79,107,210,90,225,93,166,107,210,93,166,106,156,90,225,77,240,93,166,93,166,77,240,70,257,93,166,70,257,67,189,67,189,70,257,68,275,70,324,68,275,71,292,70,324,71,292,78,305,128,338,123,324,142,322,128,338,142,322,156,334,156,334,142,322,157,314,156,334,157,314,179,324,179,324,157,314,168,302,179,324,168,302,175,286,182,44,175,29,185,8,185,8,175,29,163,17,185,8,163,17,157,-2,157,-2,163,17,148,10,157,-2,148,10,129,7,129,7,108,10,124,-6,124,-6,108,10,92,-2,92,-2,108,10,91,19,92,-2,91,19,77,34,92,-2,77,34,69,54,92,-2,69,54,66,8,78,305,89,316,97,335,97,335,89,316,104,322,97,335,104,322,128,338,128,338,104,322,123,324,49,308,36,287,38,225,49,308,38,225,49,208,49,308,49,208,67,189,49,308,67,189,68,275,49,308,68,275,70,324,36,287,31,260,33,242,36,287,33,242,38,225,171,200,190,215,176,249,176,249,190,215,177,267,179,324,177,267,190,215,179,324,190,215,197,309,197,309,190,215,203,229,197,309,203,229,208,289,208,289,203,229,210,246,208,289,210,246,212,267,171,200,176,249,171,234,171,200,171,234,162,220,171,200,162,220,149,207,171,200,149,207,145,185,223,78,220,100,218,49,218,49,220,100,213,121,218,49,213,121,205,26,205,26,213,121,199,141,205,26,199,141,185,62,185,62,199,141,183,79,177,95,183,79,199,141,177,95,199,141,177,162,177,95,177,162,167,109,185,62,185,8,205,26,129,7,124,-6,157,-2,182,44,185,8,185,62,179,324,175,286,177,267,70,324,78,305,97,335,32,48,30,94,28,75, 30,-10,65,-4,95,3,121,13,145,28,170,49,191,72,208,100,220,130,227,163,229,197,228,221,224,244,217,265,209,284,198,300,185,313,171,324,155,332,138,337,119,338,85,332,57,316,35,291,20,258,15,220,19,186,31,158,50,137,75,123,105,118,122,119,138,122,153,128,167,136,180,147,164,101,140,63,109,33,71,12,28,0,16383,16383,181,177,177,163,167,153,153,146,137,141,123,140,102,144,85,157,72,177,64,204,61,237,62,253,64,269,68,284,73,297,79,307,84,313,91,318,98,321,106,323,115,324,139,319,157,304,170,278,178,243,181,197, 62,253,64,269,57,316,57,316,64,269,68,284,57,316,68,284,85,332,85,332,68,284,73,297,85,332,73,297,79,307,79,307,84,313,85,332,85,332,84,313,91,318,85,332,91,318,119,338,119,338,91,318,98,321,119,338,98,321,106,323,119,338,106,323,115,324,115,324,139,319,119,338,119,338,139,319,138,337,123,140,105,118,122,119,123,140,122,119,138,122,123,140,102,144,105,118,85,157,72,177,75,123,85,157,75,123,105,118,85,157,105,118,102,144,61,237,62,253,57,316,61,237,57,316,50,137,61,237,50,137,64,204,64,204,50,137,75,123,64,204,75,123,72,177,15,220,19,186,20,258,20,258,19,186,31,158,20,258,31,158,35,291,35,291,31,158,50,137,35,291,50,137,57,316,137,141,123,140,138,122,137,141,138,122,153,146,153,146,138,122,153,128,153,146,153,128,167,153,167,153,153,128,167,136,167,153,167,136,177,163,177,163,167,136,180,147,177,163,180,147,181,177,181,177,180,147,191,72,181,177,191,72,181,197,178,243,181,197,185,313,178,243,185,313,171,324,138,337,139,319,155,332,155,332,139,319,157,304,155,332,157,304,171,324,171,324,157,304,170,278,171,324,170,278,178,243,229,197,228,221,227,163,227,163,228,221,224,244,227,163,224,244,220,130,220,130,224,244,217,265,220,130,217,265,209,284,220,130,209,284,208,100,208,100,209,284,198,300,208,100,198,300,191,72,191,72,198,300,185,313,191,72,185,313,181,197,30,-10,65,-4,71,12,71,12,65,-4,95,3,71,12,95,3,109,33,109,33,95,3,121,13,109,33,121,13,140,63,140,63,121,13,145,28,140,63,145,28,164,101,164,101,145,28,170,49,164,101,170,49,180,147,180,147,170,49,191,72,71,12,28,0,30,-10, 96,201,95,210,91,218,85,224,77,228,69,229,60,228,52,224,46,218,42,211,41,201,42,193,46,185,52,179,60,176,69,174,77,176,85,179,91,185,95,193,96,201,16383,16383,96,22,95,31,91,38,85,45,77,49,69,50,60,49,52,45,46,39,42,31,41,22,42,13,46,6,52,0,60,-3,69,-5,77,-3,85,0,91,6,95,13,96,22, 42,211,42,193,46,218,46,218,42,193,46,185,46,218,46,185,52,224,52,224,46,185,52,179,52,224,52,179,60,228,60,228,52,179,60,176,60,228,60,176,69,229,69,229,60,176,69,174,69,229,69,174,77,228,77,228,69,174,77,176,77,228,77,176,85,224,85,224,77,176,85,179,85,224,85,179,91,218,91,218,85,179,91,185,91,218,91,185,95,210,95,210,91,185,95,193,95,210,95,193,96,201,42,31,42,13,46,39,46,39,42,13,46,6,46,39,46,6,52,45,52,45,46,6,52,0,52,45,52,0,60,49,60,49,52,0,60,-3,60,49,60,-3,69,50,69,50,60,-3,69,-5,69,50,69,-5,77,49,77,49,69,-5,77,-3,77,49,77,-3,85,45,85,45,77,-3,85,0,85,45,85,0,91,38,91,38,85,0,91,6,91,38,91,6,95,31,95,31,91,6,95,13,95,31,95,13,96,22,42,13,42,31,41,22,42,193,42,211,41,201, 95,201,94,210,90,218,84,224,77,228,68,229,59,228,51,224,45,218,42,211,40,201,42,193,46,185,52,179,59,176,68,174,77,176,84,179,90,185,94,193,95,201,16383,16383,54,-69,73,-58,88,-44,100,-28,107,-11,109,7,107,22,102,34,93,43,82,49,70,51,60,49,52,46,46,40,42,32,40,23,41,14,45,7,51,2,59,-1,69,-2,72,-2,75,-1,78,-1,81,0,85,0,87,-2,89,-3,90,-5,90,-7,88,-17,83,-28,75,-38,63,-49,49,-60, 42,211,42,193,45,218,45,218,42,193,46,185,45,218,46,185,51,224,51,224,46,185,52,179,51,224,52,179,59,228,59,228,52,179,59,176,59,228,59,176,68,229,68,229,59,176,68,174,68,229,68,174,77,228,77,228,68,174,77,176,77,228,77,176,84,224,84,224,77,176,84,179,84,224,84,179,90,218,90,218,84,179,90,185,90,218,90,185,94,210,94,210,90,185,94,193,94,210,94,193,95,201,75,-1,78,-1,82,49,82,49,78,-1,81,0,82,49,81,0,83,0,83,0,85,0,93,43,93,43,85,0,87,-2,93,43,87,-2,89,-3,40,23,41,14,42,32,42,32,41,14,45,7,42,32,45,7,46,40,46,40,45,7,51,2,46,40,51,2,52,46,52,46,51,2,59,-1,52,46,59,-1,60,49,60,49,59,-1,69,-2,60,49,69,-2,70,51,70,51,69,-2,72,-2,70,51,72,-2,82,49,82,49,72,-2,75,-1,109,7,107,22,107,-11,107,-11,107,22,102,34,107,-11,102,34,100,-28,100,-28,102,34,93,43,100,-28,93,43,90,-7,90,-7,88,-44,100,-28,93,43,89,-3,90,-5,93,43,90,-5,90,-7,93,43,82,49,83,0,88,-44,90,-7,88,-17,88,-44,88,-17,83,-28,88,-44,83,-28,75,-38,88,-44,75,-38,73,-58,63,-49,49,-60,54,-69,63,-49,54,-69,73,-58,63,-49,73,-58,75,-38,42,193,42,211,40,201, 310,-11,310,20,94,127,310,234,310,267,28,129,28,124, 94,127,310,234,310,267,94,127,310,267,28,129,94,127,28,129,310,-11,94,127,310,-11,310,20,310,-11,28,129,28,124, 319,160,319,193,24,193,24,160,16383,16383,319,60,319,93,24,93,24,60, 24,193,24,160,319,160,24,193,319,160,319,193,24,93,24,60,319,60,24,93,319,60,319,93, 310,124,310,129,28,267,28,234,244,127,28,20,28,-11, 310,124,310,129,28,267,310,124,28,267,28,234,310,124,28,234,244,127,310,124,244,127,28,20,310,124,28,20,28,-11, 122,82,126,101,131,118,137,133,145,147,155,161,176,187,191,208,201,226,206,242,207,259,202,286,189,308,169,324,144,335,116,338,89,335,66,325,49,310,38,290,34,267,35,255,38,246,44,239,50,235,58,233,65,234,71,237,75,242,78,248,79,255,77,264,72,270,66,276,62,283,60,292,62,301,69,310,80,317,92,321,107,323,124,320,139,312,151,300,159,283,161,264,160,246,156,227,150,209,136,171,126,147,120,127,116,109,114,95,113,82,16383,16383,145,22,144,30,140,38,134,44,127,48,119,49,110,48,103,44,97,38,93,31,92,22,93,14,97,7,102,1,110,-2,119,-3,127,-2,135,1,140,7,144,14,145,22, 60,292,60,292,60,292,60,292,66,325,49,310,60,292,49,310,50,235,60,292,50,235,58,233,144,335,116,338,124,320,124,320,116,338,107,323,92,321,107,323,116,338,92,321,116,338,89,335,60,292,62,301,66,325,66,325,62,301,69,310,66,325,69,310,89,335,89,335,69,310,80,317,89,335,80,317,92,321,34,267,35,255,38,290,38,290,35,255,38,246,38,290,38,246,49,310,49,310,38,246,44,239,49,310,44,239,50,235,62,283,65,234,66,276,66,276,65,234,71,237,66,276,71,237,72,270,72,270,71,237,75,242,72,270,75,242,77,264,77,264,75,242,78,248,77,264,78,248,79,255,65,234,62,283,60,292,65,234,60,292,58,233,119,49,119,-3,127,48,127,48,119,-3,127,-2,127,48,127,-2,134,44,134,44,127,-2,135,1,134,44,135,1,140,38,140,38,135,1,140,7,140,38,140,7,144,30,144,30,140,7,144,14,144,30,144,14,145,22,92,22,93,14,93,31,93,31,93,14,97,7,93,31,97,7,97,38,97,38,97,7,102,1,97,38,102,1,103,44,103,44,102,1,110,-2,103,44,110,-2,110,48,110,48,110,-2,119,-3,110,48,119,-3,119,49,124,320,139,312,144,335,144,335,139,312,151,300,144,335,151,300,169,324,169,324,151,300,159,283,169,324,159,283,161,264,161,264,160,246,176,187,176,187,160,246,156,227,176,187,156,227,155,161,155,161,156,227,150,209,155,161,150,209,145,147,145,147,150,209,143,190,145,147,143,190,137,133,137,133,143,190,136,171,137,133,136,171,131,118,131,118,136,171,126,147,131,118,126,147,126,101,126,101,126,147,122,82,202,286,189,308,191,208,202,286,191,208,201,226,202,286,201,226,206,242,202,286,206,242,207,259,176,187,191,208,189,308,176,187,189,308,169,324,176,187,169,324,161,264,122,82,126,147,120,127,122,82,120,127,116,109,122,82,116,109,114,95,122,82,114,95,113,82, 344,36,323,27,303,20,283,16,263,13,243,12,196,19,156,40,126,71,107,112,100,161,101,184,105,206,112,227,120,247,131,265,148,285,167,301,189,313,214,320,241,323,286,316,326,296,357,267,377,229,384,186,381,157,372,130,358,108,341,94,321,88,314,89,308,92,304,96,301,103,300,112,300,115,301,117,301,120,334,247,300,247,295,228,294,228,289,238,284,245,276,250,268,253,257,254,242,252,229,248,216,241,204,231,194,219,183,203,174,185,167,167,162,147,161,128,163,109,169,93,179,82,191,75,204,72,219,74,232,78,245,86,257,96,267,108,268,108,271,96,279,86,288,78,300,73,313,71,341,78,366,95,386,121,400,154,405,191,396,238,374,279,338,310,293,331,241,338,215,337,191,333,169,326,148,316,128,304,105,282,86,257,71,228,61,197,58,164,67,108,93,61,132,24,182,1,241,-6,261,-5,281,-2,302,2,324,10,350,22,16383,16383,286,202,285,187,282,171,277,155,271,138,264,123,257,113,250,105,242,99,234,95,226,94,216,96,207,101,201,110,197,122,196,137,197,150,199,163,203,175,208,186,214,197,223,209,234,219,244,226,254,231,263,232,271,231,277,227,282,221,285,213,286,202, 156,40,126,71,132,24,132,24,126,71,107,112,132,24,107,112,93,61,93,61,107,112,100,161,105,282,100,161,101,184,105,282,101,184,105,206,105,206,112,227,128,304,128,304,112,227,120,247,128,304,120,247,131,265,131,265,148,285,148,316,148,316,148,285,167,301,148,316,167,301,169,326,169,326,167,301,189,313,169,326,189,313,191,333,191,333,189,313,214,320,191,333,214,320,215,337,215,337,214,320,241,323,215,337,241,323,241,338,241,338,241,323,293,331,93,61,100,161,105,282,93,61,105,282,86,257,93,61,86,257,71,228,93,61,71,228,67,108,61,197,58,164,67,108,61,197,67,108,71,228,384,186,386,121,396,238,384,186,396,238,377,229,377,229,396,238,374,279,377,229,374,279,357,267,357,267,374,279,338,310,357,267,338,310,326,296,326,296,338,310,293,331,326,296,293,331,286,316,286,316,293,331,241,323,148,316,128,304,131,265,344,36,323,27,324,10,324,10,323,27,303,20,324,10,303,20,302,2,302,2,303,20,283,16,302,2,283,16,281,-2,281,-2,283,16,263,13,281,-2,263,13,261,-5,261,-5,263,13,243,12,261,-5,243,12,241,-6,241,-6,243,12,196,19,241,-6,196,19,182,1,182,1,196,19,156,40,182,1,156,40,132,24,276,250,268,253,271,231,271,231,268,253,263,232,254,231,263,232,257,254,254,231,257,254,244,226,244,226,257,254,242,252,244,226,242,252,234,219,234,219,242,252,229,248,234,219,229,248,223,209,223,209,229,248,216,241,223,209,216,241,214,197,199,163,203,175,204,231,204,231,203,175,208,186,204,231,208,186,216,241,216,241,208,186,214,197,194,219,196,137,197,150,194,219,197,150,204,231,204,231,197,150,199,163,201,110,204,72,207,101,207,101,204,72,219,74,207,101,219,74,216,96,216,96,219,74,226,94,234,95,226,94,232,78,234,95,232,78,245,86,197,122,196,137,191,75,197,122,191,75,204,72,197,122,204,72,201,110,196,137,194,219,191,75,191,75,194,219,183,203,191,75,183,203,179,82,179,82,183,203,174,185,179,82,174,185,169,93,169,93,174,185,167,167,169,93,167,167,163,109,163,109,167,167,162,147,163,109,162,147,161,128,268,253,257,254,263,232,267,108,268,108,271,138,267,108,271,138,264,123,264,123,257,113,267,108,267,108,257,113,257,96,308,92,304,96,312,71,312,71,304,96,301,103,312,71,301,103,300,73,300,73,301,103,300,112,300,115,301,117,300,247,300,247,301,117,301,119,300,247,301,119,301,120,301,120,334,247,300,247,300,247,295,228,300,73,300,247,300,73,300,112,300,247,300,112,300,114,300,247,300,114,300,115,295,228,294,228,300,73,300,73,294,228,289,238,300,73,289,238,288,78,288,78,289,238,286,202,288,78,286,202,285,187,288,78,285,187,282,171,285,213,286,202,289,238,285,213,289,238,284,245,285,213,284,245,282,221,277,227,282,221,284,245,277,227,284,245,276,250,277,227,276,250,271,231,384,186,381,157,386,121,386,121,381,157,372,130,386,121,372,130,366,95,366,95,372,130,358,108,366,95,358,108,341,78,341,78,358,108,341,94,341,78,341,94,321,88,321,88,314,89,341,78,341,78,314,89,312,71,396,238,386,121,400,154,396,238,400,154,405,191,288,78,282,171,279,86,279,86,282,171,277,155,279,86,277,155,271,96,271,96,277,155,271,138,271,96,271,138,268,108,250,105,242,99,245,86,250,105,245,86,257,96,250,105,257,96,257,113,226,94,219,74,232,78,234,95,245,86,242,99,308,92,312,71,314,89,344,36,324,10,350,22,105,282,105,206,128,304, 353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0, 211,175,225,178,236,182,245,185,259,195,266,203,272,213,276,224,279,235,280,248,274,277,258,300,232,317,195,327,148,331,8,331,8,321,29,320,43,316,51,308,55,295,56,275,56,56,55,37,51,24,42,16,29,11,8,9,8,0,177,0,217,4,250,15,275,34,291,58,296,89,295,102,292,115,287,126,281,137,272,147,263,154,254,160,242,166,229,170,211,174,16383,16383,108,183,108,303,109,307,112,310,115,312,119,313,140,313,172,309,197,301,214,287,225,268,228,245,225,223,217,205,202,193,181,186,153,183,16383,16383,108,163,139,162,162,161,181,158,198,152,215,143,224,136,231,126,235,115,238,103,239,89,238,77,236,66,232,56,227,47,220,40,207,30,194,24,179,20,161,19,138,18,126,19,118,21,112,26,109,32,108,41, 51,24,42,16,177,0,177,0,42,16,29,11,177,0,29,11,8,9,55,295,56,275,112,310,55,295,112,310,148,331,148,331,112,310,115,312,148,331,115,312,119,313,148,331,119,313,140,313,148,331,140,313,172,309,207,30,194,24,217,4,217,4,194,24,179,20,217,4,179,20,177,0,177,0,179,20,161,19,177,0,161,19,138,18,138,18,126,19,177,0,177,0,126,19,118,21,177,0,118,21,55,37,55,37,118,21,56,56,258,300,232,317,236,182,236,182,232,317,228,245,236,182,228,245,225,223,236,182,225,223,225,178,225,178,225,223,217,205,225,178,217,205,211,175,211,175,217,205,202,193,211,175,202,193,211,174,211,174,202,193,215,143,211,174,215,143,229,170,229,170,215,143,224,136,153,183,162,161,181,186,181,186,162,161,181,158,181,186,181,158,202,193,202,193,181,158,198,152,202,193,198,152,215,143,236,66,232,56,250,15,250,15,232,56,227,47,250,15,227,47,220,40,220,40,207,30,217,4,162,161,153,183,139,162,139,162,153,183,108,183,139,162,108,183,108,163,109,32,108,41,56,275,109,32,56,275,56,56,56,56,118,21,112,26,56,56,112,26,109,32,272,147,263,154,275,34,275,34,263,154,254,160,275,34,254,160,250,15,250,15,254,160,242,166,250,15,242,166,239,89,239,89,238,77,250,15,250,15,238,77,236,66,242,166,229,170,231,126,242,166,231,126,235,115,242,166,235,115,238,103,242,166,238,103,239,89,232,317,195,327,197,301,232,317,197,301,214,287,232,317,214,287,225,268,232,317,225,268,228,245,195,327,148,331,172,309,195,327,172,309,197,301,56,275,108,41,108,296,56,275,108,296,108,303,56,275,108,303,109,307,56,275,109,307,112,310,148,331,8,331,29,320,148,331,29,320,43,316,148,331,43,316,51,308,148,331,51,308,55,295,266,203,272,213,274,277,274,277,272,213,276,224,274,277,276,224,280,248,280,248,276,224,279,235,245,185,252,190,258,300,258,300,252,190,259,195,258,300,259,195,274,277,274,277,259,195,266,203,292,115,287,126,291,58,292,115,291,58,296,89,292,115,296,89,295,102,281,137,272,147,275,34,281,137,275,34,291,58,281,137,291,58,287,126,220,40,217,4,250,15,258,300,236,182,245,185,29,320,8,331,8,321,229,170,224,136,231,126,177,0,8,9,8,0,51,24,177,0,55,37, 307,65,285,47,265,32,244,23,222,17,197,15,177,17,157,21,139,28,123,38,108,51,95,68,85,88,78,112,73,140,72,171,77,219,93,260,117,291,151,311,192,318,211,316,228,311,244,304,259,293,272,280,279,272,285,263,290,252,295,240,299,224,310,224,305,338,296,338,293,332,290,328,285,324,280,322,275,321,269,322,262,324,254,326,240,330,228,333,204,337,192,338,180,338,153,336,127,330,102,320,80,305,59,286,44,266,31,243,22,218,16,191,14,162,16,133,22,106,32,80,45,57,62,37,81,22,103,9,127,0,153,-4,180,-6,214,-4,245,3,273,16,297,34,316,56, 62,37,73,140,72,171,72,171,80,305,62,37,62,37,80,305,59,286,62,37,59,286,45,57,45,57,59,286,44,266,45,57,44,266,32,80,32,80,44,266,31,243,32,80,31,243,22,106,22,106,31,243,22,218,22,106,22,218,16,133,16,133,22,218,16,191,16,133,16,191,14,162,78,112,81,22,85,88,85,88,81,22,103,9,85,88,103,9,95,68,95,68,103,9,108,51,123,38,108,51,127,0,123,38,127,0,139,28,139,28,127,0,153,-4,139,28,153,-4,157,21,157,21,153,-4,180,-6,157,21,180,-6,177,17,177,17,180,-6,197,15,222,17,197,15,214,-4,222,17,214,-4,245,3,73,140,62,37,81,22,73,140,81,22,78,112,108,51,103,9,127,0,254,326,259,293,262,324,262,324,259,293,272,280,262,324,272,280,269,322,269,322,272,280,275,321,280,322,275,321,279,272,280,322,279,272,285,263,275,321,272,280,279,272,228,333,228,311,240,330,240,330,228,311,244,304,240,330,244,304,247,328,247,328,244,304,259,293,247,328,259,293,254,326,216,335,204,337,211,316,216,335,211,316,228,311,216,335,228,311,228,333,204,337,192,338,211,316,211,316,192,338,192,318,151,311,192,318,153,336,151,311,153,336,127,330,310,224,305,338,299,224,299,224,305,338,296,338,299,224,296,338,295,240,295,240,296,338,293,332,295,240,293,332,290,252,290,252,293,332,290,328,290,252,290,328,285,263,285,263,290,328,285,324,285,263,285,324,280,322,316,56,307,65,297,34,297,34,307,65,285,47,297,34,285,47,273,16,273,16,285,47,265,32,273,16,265,32,245,3,245,3,265,32,244,23,245,3,244,23,222,17,197,15,180,-6,214,-4,192,318,192,338,180,338,192,318,180,338,153,336,72,171,77,219,80,305,80,305,77,219,93,260,80,305,93,260,102,320,102,320,93,260,117,291,102,320,117,291,127,330,127,330,117,291,151,311, 8,331,8,321,27,320,40,316,47,308,51,295,52,275,52,57,51,38,48,25,40,16,27,12,8,9,8,0,148,0,178,1,206,6,231,12,254,21,275,32,299,51,318,75,331,102,340,133,343,167,341,196,334,223,324,247,310,267,293,286,270,302,244,314,214,323,180,329,143,331,16383,16383,103,291,104,300,107,306,112,310,119,312,129,313,157,311,182,308,203,301,222,291,241,278,257,260,271,241,280,219,286,193,288,164,286,132,280,104,270,81,255,61,236,45,218,34,200,27,179,22,155,19,127,18,117,19,110,22,106,26,104,33,103,42, 48,25,40,16,148,0,148,0,40,16,27,12,148,0,27,12,8,9,52,57,51,38,110,22,110,22,51,38,148,0,110,22,148,0,117,19,117,19,148,0,127,18,155,19,127,18,148,0,155,19,148,0,178,1,104,300,107,306,52,275,52,275,107,306,112,310,52,275,112,310,143,331,143,331,112,310,119,312,143,331,119,312,129,313,129,313,119,312,129,312,129,313,129,312,157,311,129,313,157,311,143,331,143,331,157,311,180,329,206,6,231,12,218,34,218,34,231,12,236,45,255,61,236,45,254,21,255,61,254,21,275,32,155,19,178,1,179,22,179,22,178,1,206,6,179,22,206,6,200,27,200,27,206,6,218,34,244,314,241,278,257,260,244,314,257,260,270,302,270,302,257,260,271,241,270,302,271,241,293,286,293,286,271,241,280,219,293,286,280,219,286,193,182,308,203,301,214,323,214,323,203,301,222,291,214,323,222,291,244,314,244,314,222,291,241,278,180,329,157,311,182,308,180,329,182,308,214,323,343,167,341,196,340,133,340,133,341,196,334,223,340,133,334,223,331,102,331,102,334,223,324,247,331,102,324,247,318,75,318,75,324,247,310,267,318,75,310,267,299,51,299,51,310,267,293,286,299,51,293,286,288,164,288,164,286,132,299,51,299,51,286,132,280,104,299,51,280,104,275,32,275,32,280,104,270,81,275,32,270,81,255,61,236,45,231,12,254,21,110,22,106,26,52,57,52,57,106,26,104,33,52,57,104,33,52,275,52,275,104,33,103,42,52,275,103,42,103,291,40,316,47,308,143,331,143,331,47,308,51,295,143,331,51,295,52,275,27,320,40,316,143,331,27,320,143,331,8,331,27,320,8,331,8,321,148,0,8,9,8,0,48,25,148,0,51,38,104,300,52,275,103,291,293,286,286,193,288,164, 299,84,285,84,271,57,255,38,234,26,206,20,169,18,151,18,132,19,117,21,108,25,102,31,100,42,100,164,176,164,198,162,213,158,222,150,229,136,233,115,244,115,244,232,233,232,229,212,222,198,213,190,198,185,176,184,100,184,100,294,101,302,103,307,106,310,111,312,184,312,213,311,234,306,247,297,255,282,261,259,273,259,271,331,6,331,6,321,25,320,38,315,45,307,49,294,50,275,50,57,49,37,45,24,38,16,25,12,6,9,6,0,276,0, 45,24,38,16,276,0,276,0,38,16,25,12,276,0,25,12,6,9,49,294,50,275,106,310,49,294,106,310,45,307,45,307,106,310,111,312,45,307,111,312,271,331,271,331,111,312,118,312,45,24,117,21,49,37,49,37,117,21,108,25,49,37,108,25,50,57,50,57,108,25,102,31,50,57,102,31,50,275,50,275,102,31,100,42,50,275,100,42,100,294,100,184,100,164,176,164,100,184,176,164,176,184,198,185,176,184,198,162,198,185,198,162,213,190,213,190,198,162,213,158,213,190,213,158,222,198,222,198,213,158,222,150,222,198,222,150,229,212,229,212,222,150,229,136,229,212,229,136,233,232,233,232,229,136,233,115,233,232,233,115,244,115,271,331,118,312,184,312,271,331,184,312,213,311,271,331,213,311,234,306,271,331,234,306,247,297,271,331,247,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,50,275,100,294,101,302,50,275,101,302,103,307,50,275,103,307,106,310,271,331,6,331,25,320,271,331,25,320,38,315,271,331,38,315,45,307,255,38,234,26,276,0,276,0,234,26,206,20,276,0,206,20,169,18,276,0,299,84,285,84,276,0,285,84,271,57,276,0,271,57,255,38,276,0,169,18,151,18,276,0,151,18,132,19,276,0,132,19,117,21,276,0,117,21,45,24,276,0,6,9,6,0,25,320,6,331,6,321,176,184,176,164,198,162,233,232,244,115,244,232, 273,259,271,331,6,331,6,321,25,319,38,315,45,307,49,294,50,276,50,61,49,40,45,25,37,16,25,12,6,9,6,0,146,0,146,9,127,12,113,16,105,24,102,37,100,56,100,164,171,164,193,162,209,158,219,150,225,136,228,115,239,115,239,232,228,232,225,212,218,198,208,190,193,185,171,184,100,184,100,292,101,300,102,306,105,310,110,311,118,312,184,312,214,311,234,306,247,297,255,282,261,259, 38,315,45,307,271,331,271,331,45,307,110,311,271,331,110,311,118,312,271,331,118,312,184,312,271,331,184,312,214,311,50,276,102,37,100,56,100,184,100,164,171,164,100,184,171,164,171,184,193,185,171,184,193,162,193,185,193,162,208,190,208,190,193,162,209,158,208,190,209,158,218,198,218,198,209,158,219,150,218,198,219,150,225,212,225,212,219,150,225,136,225,212,225,136,228,232,228,232,225,136,228,115,228,232,228,115,239,115,271,331,214,311,234,306,271,331,234,306,247,297,271,331,247,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,50,276,100,56,100,292,50,276,100,292,101,300,50,276,101,300,102,306,50,276,102,306,105,310,50,276,105,310,49,294,110,311,45,307,49,294,110,311,49,294,105,310,25,319,38,315,271,331,25,319,271,331,6,331,25,319,6,331,6,321,146,0,146,9,127,12,146,0,127,12,113,16,146,0,113,16,49,40,146,0,49,40,45,25,146,0,45,25,37,16,146,0,37,16,25,12,146,0,25,12,6,9,146,0,6,9,6,0,50,61,49,40,113,16,50,61,113,16,105,24,50,61,105,24,102,37,50,61,102,37,50,276,171,184,171,164,193,162,228,232,239,115,239,232, 354,177,227,177,227,168,246,166,259,162,267,154,270,142,271,122,271,44,268,34,259,25,244,19,226,14,204,13,161,19,124,39,97,69,79,111,73,162,75,191,79,219,86,244,97,266,112,283,125,295,140,305,157,312,175,317,195,318,211,317,227,314,242,308,256,300,268,291,276,282,283,273,290,262,296,249,304,233,315,233,311,338,300,338,298,333,294,328,289,325,283,322,277,321,274,322,270,322,266,323,261,325,256,326,243,331,230,334,218,336,204,338,189,338,161,336,135,331,111,322,89,310,70,295,51,275,36,251,25,225,19,195,16,164,18,135,23,110,31,86,42,65,57,46,79,28,105,13,133,2,162,-4,193,-6,223,-5,251,0,278,6,301,16,320,28,320,128,321,144,324,156,330,162,340,166,354,168, 16,164,18,135,19,195,19,195,18,135,23,110,19,195,23,110,25,225,25,225,23,110,31,86,25,225,31,86,36,251,36,251,31,86,42,65,36,251,42,65,51,275,51,275,42,65,57,46,51,275,57,46,70,295,70,295,57,46,73,162,157,312,161,336,140,305,140,305,161,336,135,331,140,305,135,331,125,295,125,295,135,331,112,283,97,266,112,283,111,322,97,266,111,322,89,310,89,310,70,295,75,191,89,310,75,191,79,219,89,310,79,219,86,244,89,310,86,244,97,266,193,-6,204,13,162,-4,162,-4,204,13,161,19,162,-4,161,19,133,2,133,2,161,19,124,39,133,2,124,39,105,13,105,13,124,39,97,69,105,13,97,69,79,28,79,28,97,69,79,111,79,28,79,111,73,162,259,25,244,19,251,0,251,0,244,19,226,14,251,0,226,14,223,-5,223,-5,226,14,204,13,73,162,57,46,79,28,268,291,266,323,261,325,268,291,261,325,256,300,268,291,270,322,266,323,204,338,195,318,211,317,204,338,211,317,218,336,218,336,211,317,227,314,218,336,227,314,230,334,230,334,227,314,242,308,230,334,242,308,243,331,243,331,242,308,256,300,243,331,256,300,256,326,256,326,256,300,261,325,270,322,276,282,274,322,274,322,276,282,277,321,283,322,277,321,283,273,283,322,283,273,290,262,268,291,276,282,270,322,304,233,315,233,311,338,304,233,311,338,300,338,304,233,300,338,298,333,304,233,298,333,296,249,294,328,289,325,290,262,294,328,290,262,296,249,294,328,296,249,298,333,277,321,276,282,283,273,340,166,354,168,354,177,340,166,354,177,330,162,330,162,354,177,270,142,330,162,270,142,271,122,278,6,271,122,271,44,278,6,271,44,268,34,330,162,271,122,324,156,324,156,271,122,278,6,324,156,278,6,321,144,321,144,278,6,301,16,321,144,301,16,320,128,320,128,301,16,320,28,354,177,227,177,246,166,354,177,246,166,259,162,354,177,259,162,267,154,354,177,267,154,270,142,259,25,251,0,278,6,259,25,278,6,268,34,189,338,161,336,175,317,189,338,175,317,195,318,189,338,195,318,204,338,135,331,111,322,112,283,161,336,157,312,175,317,223,-5,204,13,193,-6,246,166,227,177,227,168,283,322,290,262,289,325,75,191,70,295,73,162, 352,0,352,9,333,12,320,17,312,25,308,37,307,55,307,274,308,293,312,307,320,315,333,319,352,321,352,331,211,331,211,321,231,319,244,315,251,307,255,294,256,274,256,180,104,180,104,274,106,294,110,307,118,315,130,319,149,321,149,331,9,331,9,321,28,319,41,315,49,307,53,294,54,274,54,61,53,39,49,25,42,16,29,12,9,9,9,0,148,0,148,9,129,12,117,17,109,25,105,38,104,56,104,157,256,157,256,62,255,41,252,26,244,17,232,12,212,9,212,0, 49,25,42,16,148,0,148,0,42,16,29,12,148,0,29,12,9,9,149,331,9,331,28,319,149,331,28,319,41,315,149,331,41,315,49,307,149,331,49,307,53,294,149,331,53,294,118,315,149,331,118,315,130,319,149,331,130,319,149,321,54,274,105,38,104,56,104,180,104,157,256,157,104,180,256,157,256,180,256,180,256,157,312,25,256,180,312,25,308,37,54,274,104,56,104,274,54,274,104,274,106,294,54,274,106,294,110,307,54,274,110,307,118,315,54,274,118,315,53,294,252,26,244,17,352,0,352,0,244,17,232,12,352,0,232,12,212,9,333,319,352,321,352,331,333,319,352,331,320,315,320,315,352,331,255,294,320,315,255,294,256,274,308,37,256,274,256,180,307,55,307,274,256,274,256,274,307,274,308,293,256,274,308,293,312,307,352,331,211,331,231,319,352,331,231,319,244,315,352,331,244,315,251,307,352,331,251,307,255,294,352,0,352,9,333,12,352,0,333,12,320,17,352,0,320,17,255,41,352,0,255,41,252,26,256,62,255,41,320,17,256,62,320,17,312,25,256,62,312,25,256,157,148,0,148,9,129,12,148,0,129,12,117,17,148,0,117,17,53,39,148,0,53,39,49,25,54,61,53,39,117,17,54,61,117,17,109,25,54,61,109,25,105,38,54,61,105,38,54,274,148,0,9,9,9,0,352,0,212,9,212,0,256,274,308,37,307,55,231,319,211,331,211,321,320,315,256,274,312,307,28,319,9,331,9,321, 157,0,157,9,137,11,122,16,114,24,109,37,108,56,108,276,109,295,113,308,122,316,136,320,157,321,157,331,9,331,9,321,30,320,44,316,53,308,57,295,57,56,56,36,52,23,44,15,30,11,9,9,9,0, 52,23,44,15,157,0,157,0,44,15,30,11,157,0,30,11,9,9,157,331,9,331,30,320,157,331,30,320,44,316,157,331,44,316,53,308,157,331,53,308,57,295,157,331,57,295,122,316,157,331,122,316,136,320,157,331,136,320,157,321,122,16,114,24,57,56,57,56,114,24,109,37,57,56,109,37,57,276,57,276,109,37,108,56,57,276,108,56,108,276,57,276,108,276,109,295,57,276,109,295,113,308,57,276,113,308,122,316,57,276,122,316,57,295,157,0,157,9,137,11,157,0,137,11,122,16,157,0,122,16,56,36,157,0,56,36,52,23,157,0,9,9,9,0,56,36,122,16,57,56,30,320,9,331,9,321, 177,331,33,331,33,321,54,319,67,315,75,308,79,295,80,275,80,47,79,34,78,24,75,17,69,13,61,12,56,13,53,16,51,21,48,27,46,34,42,41,38,47,33,52,28,54,22,55,14,54,7,50,2,44,-1,37,-2,29,0,16,6,6,17,0,31,-5,47,-6,76,-2,100,8,117,28,128,56,131,93,131,275,132,294,136,307,143,315,157,319,177,321, 78,24,75,17,76,-2,76,-2,75,17,69,13,76,-2,69,13,61,12,61,12,56,13,76,-2,76,-2,56,13,47,-6,157,319,177,321,177,331,157,319,177,331,143,315,143,315,177,331,79,295,143,315,79,295,80,275,100,8,80,275,80,47,100,8,80,47,79,34,131,275,132,294,117,28,131,275,117,28,128,56,131,275,128,56,131,93,132,294,136,307,80,275,132,294,80,275,100,8,132,294,100,8,117,28,177,331,33,331,54,319,177,331,54,319,67,315,177,331,67,315,75,308,177,331,75,308,79,295,78,24,76,-2,100,8,78,24,100,8,79,34,47,-6,56,13,53,16,47,-6,53,16,51,21,47,-6,51,21,48,27,47,-6,48,27,46,34,47,-6,46,34,42,41,47,-6,42,41,38,47,47,-6,38,47,33,52,47,-6,33,52,31,-5,33,52,28,54,31,-5,31,-5,28,54,22,55,31,-5,22,55,17,0,17,0,22,55,14,54,17,0,14,54,7,50,17,0,7,50,6,6,6,6,7,50,2,44,6,6,2,44,0,16,0,16,2,44,-1,37,0,16,-1,37,-2,29,54,319,33,331,33,321,143,315,80,275,136,307, 362,0,362,9,349,11,336,16,322,25,305,41,283,64,166,192,259,281,278,298,292,309,305,316,320,320,338,321,338,331,208,331,208,321,220,321,229,320,235,318,238,315,240,311,241,305,239,298,234,289,226,280,202,256,113,174,113,293,117,307,124,315,137,319,158,321,158,331,17,331,17,321,37,319,50,315,57,306,61,293,62,275,62,63,61,40,57,26,50,17,36,12,17,9,17,0,157,0,157,9,139,12,126,16,118,23,114,36,113,55,113,148,126,158,176,107,198,84,217,63,232,46,241,32,244,22,244,18,241,15,237,12,231,11,224,10,210,9,210,0, 158,321,158,321,137,319,137,319,158,321,158,331,137,319,158,331,124,315,124,315,158,331,61,293,124,315,61,293,62,275,114,36,62,275,62,63,114,36,62,63,118,23,118,23,62,63,126,16,62,275,114,36,113,55,113,174,113,148,126,158,113,174,126,158,202,256,202,256,126,158,166,192,202,256,166,192,259,281,62,275,113,55,113,274,62,275,113,274,113,293,62,275,113,293,117,307,62,275,117,307,124,315,158,331,17,331,37,319,158,331,37,319,50,315,158,331,50,315,57,306,158,331,57,306,61,293,234,289,226,280,259,281,259,281,226,280,215,269,259,281,215,269,202,256,338,331,208,331,220,321,338,331,220,321,229,320,338,331,229,320,235,318,338,331,235,318,238,315,338,331,238,315,240,311,338,331,240,311,241,305,338,331,241,305,305,316,338,331,305,316,320,320,338,331,320,320,338,321,241,305,259,281,278,298,241,305,278,298,292,309,241,305,292,309,305,316,239,298,234,289,259,281,239,298,259,281,241,305,241,15,237,12,362,0,362,0,237,12,231,11,362,0,231,11,224,10,244,22,362,0,336,16,244,22,336,16,322,25,244,22,322,25,305,41,244,22,305,41,283,64,244,22,283,64,241,32,283,64,166,192,176,107,283,64,176,107,198,84,283,64,198,84,217,63,283,64,217,63,232,46,283,64,232,46,241,32,349,11,336,16,362,0,349,11,362,0,362,9,244,18,241,15,362,0,244,18,362,0,244,22,210,9,210,0,362,0,210,9,362,0,224,10,157,0,157,9,139,12,157,0,139,12,126,16,157,0,126,16,61,40,157,0,61,40,57,26,157,0,57,26,50,17,157,0,50,17,36,12,157,0,36,12,17,9,157,0,17,9,17,0,61,40,126,16,62,63,176,107,166,192,126,158,220,321,208,331,208,321,37,319,17,331,17,321, 299,87,286,87,277,69,273,62,265,50,254,39,239,30,223,24,203,21,180,20,127,20,114,22,106,26,102,32,100,42,100,274,101,294,105,307,113,315,127,319,147,321,147,331,6,331,6,321,26,319,38,314,46,306,49,292,50,273,50,57,49,38,45,25,37,16,25,12,6,9,6,0,275,0, 147,321,147,321,127,319,127,319,147,321,147,331,127,319,147,331,113,315,113,315,147,331,49,292,113,315,49,292,50,273,102,32,50,273,50,57,102,32,50,57,106,26,106,26,50,57,49,38,106,26,49,38,114,22,114,22,49,38,45,25,114,22,45,25,127,20,127,20,45,25,275,0,127,20,275,0,146,20,146,20,275,0,180,20,100,42,100,274,50,273,50,273,100,274,101,294,50,273,101,294,105,307,147,331,6,331,26,319,147,331,26,319,38,314,147,331,38,314,46,306,147,331,46,306,49,292,277,69,273,62,275,0,275,0,273,62,269,56,275,0,269,56,265,50,265,50,254,39,275,0,275,0,254,39,239,30,275,0,239,30,223,24,299,87,286,87,281,77,299,87,281,77,277,69,299,87,277,69,275,0,203,21,180,20,275,0,203,21,275,0,223,24,275,0,45,25,37,16,275,0,37,16,25,12,275,0,25,12,6,9,275,0,6,9,6,0,50,273,102,32,100,42,26,319,6,331,6,321,113,315,50,273,105,307, 432,0,432,9,413,12,401,17,393,25,389,38,388,56,388,275,389,294,393,307,401,316,413,320,431,321,431,331,332,331,222,80,106,331,7,331,7,321,28,319,42,315,50,307,54,294,55,275,55,75,54,47,49,29,41,18,27,12,6,9,6,0,123,0,123,9,103,12,90,18,82,29,78,48,76,75,76,275,203,0,209,0,337,286,337,61,336,40,333,26,325,17,312,12,292,9,292,0, 49,29,41,18,123,0,123,0,41,18,27,12,123,0,27,12,6,9,333,26,325,17,432,0,432,0,325,17,312,12,432,0,312,12,292,9,413,320,431,321,431,331,413,320,431,331,401,316,401,316,431,331,337,286,401,316,337,286,393,307,393,307,337,286,389,294,401,17,393,25,337,61,337,61,393,25,389,38,337,61,389,38,337,286,337,286,389,38,388,56,337,286,388,56,388,275,203,0,209,0,222,80,222,80,209,0,337,286,222,80,337,286,332,331,332,331,337,286,431,331,106,331,7,331,28,319,106,331,28,319,42,315,106,331,42,315,50,307,106,331,50,307,54,294,106,331,54,294,55,275,106,331,55,275,76,275,106,331,76,275,203,0,106,331,203,0,222,80,76,75,76,275,55,275,76,75,55,275,78,48,78,48,55,275,55,75,78,48,55,75,82,29,82,29,55,75,54,47,82,29,54,47,90,18,90,18,54,47,49,29,90,18,49,29,123,0,432,0,432,9,413,12,432,0,413,12,401,17,432,0,401,17,336,40,432,0,336,40,333,26,103,12,90,18,123,0,103,12,123,0,123,9,123,0,6,9,6,0,432,0,292,9,292,0,336,40,401,17,337,61,28,319,7,331,7,321,389,294,337,286,388,275, 353,331,235,331,235,321,247,320,256,319,263,317,275,309,278,303,281,295,283,285,284,274,284,89,91,331,6,331,6,321,19,321,29,318,37,313,46,306,55,295,55,75,54,48,49,30,41,19,27,13,6,9,6,0,123,0,123,9,103,13,90,20,82,31,78,49,76,75,76,269,297,-5,306,-5,306,274,308,289,311,299,315,307,320,313,324,315,329,318,335,319,343,320,353,321, 49,30,41,19,123,0,123,0,41,19,27,13,123,0,27,13,6,9,256,319,263,317,353,331,353,331,263,317,269,313,353,331,269,313,275,309,275,309,278,303,353,331,353,331,278,303,281,295,353,331,281,295,324,315,324,315,281,295,320,313,324,315,320,313,320,312,320,312,320,313,315,307,315,307,320,313,284,274,315,307,284,274,284,259,297,-5,284,259,284,89,297,-5,284,89,91,331,353,331,324,315,329,318,353,331,329,318,335,319,353,331,335,319,343,320,353,331,343,320,353,321,306,-5,306,253,297,-5,297,-5,306,253,306,274,297,-5,306,274,284,259,284,259,306,274,308,289,284,259,308,289,311,299,283,285,284,274,320,313,283,285,320,313,281,295,247,320,256,319,353,331,247,320,353,331,235,331,247,320,235,331,235,321,91,331,6,331,19,321,91,331,19,321,29,318,91,331,29,318,37,313,91,331,37,313,46,306,91,331,46,306,55,295,91,331,55,295,76,269,91,331,76,269,297,-5,55,295,78,49,76,75,54,48,49,30,90,20,90,20,49,30,123,0,90,20,123,0,103,13,103,13,123,0,123,9,55,75,54,48,82,31,55,75,82,31,78,49,55,75,78,49,55,295,123,0,6,9,6,0,54,48,90,20,82,31,19,321,6,331,6,321,76,269,55,295,76,75,315,307,284,259,311,299, 344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,81,24,74,166,46,61,223,19,234,1,235,26,130,25,180,-6,142,19, 8,331,8,321,27,319,39,315,46,307,49,294,50,276,50,39,47,25,40,16,27,12,8,9,8,0,148,0,148,9,128,12,114,16,106,24,102,37,101,56,101,146,109,145,115,145,122,144,136,144,164,145,188,147,208,153,225,161,243,175,253,185,260,197,266,210,270,225,271,240,270,254,267,268,262,280,255,291,246,300,231,310,213,319,191,325,166,329,137,331,16383,16383,101,295,101,302,103,307,106,310,111,312,118,313,155,310,182,302,202,288,213,266,217,238,213,213,202,192,185,177,162,167,132,164,120,164,114,165,108,165,101,166, 111,312,118,312,118,313,137,331,118,313,155,310,137,331,155,310,166,329,166,329,155,310,182,302,166,329,182,302,191,325,191,325,182,302,202,288,191,325,202,288,213,319,213,319,202,288,213,266,213,319,213,266,231,310,231,310,213,266,217,238,231,310,217,238,225,161,225,161,213,213,208,153,208,153,213,213,202,192,208,153,202,192,188,147,188,147,202,192,185,177,188,147,185,177,164,145,164,145,185,177,162,167,164,145,162,167,136,144,136,144,162,167,132,164,136,144,132,164,128,144,128,144,132,164,126,164,128,144,126,164,122,144,122,144,126,164,120,164,122,144,120,164,115,145,115,145,120,164,114,165,115,145,114,165,109,145,109,145,114,165,108,165,109,145,108,165,101,166,101,56,101,166,50,276,101,56,50,276,102,37,102,37,50,276,50,61,101,166,101,146,109,145,271,240,270,254,270,225,270,225,270,254,267,268,270,225,267,268,266,210,266,210,267,268,262,280,266,210,262,280,260,197,260,197,262,280,255,291,260,197,255,291,253,185,253,185,255,291,246,300,253,185,246,300,243,175,243,175,246,300,231,310,243,175,231,310,225,161,137,331,8,331,27,319,137,331,27,319,39,315,137,331,39,315,46,307,137,331,46,307,49,294,137,331,49,294,50,276,137,331,50,276,106,310,137,331,106,310,111,312,137,331,111,312,118,313,101,295,101,302,50,276,101,295,50,276,101,166,103,307,106,310,50,276,103,307,50,276,101,302,148,0,148,9,128,12,148,0,128,12,114,16,148,0,114,16,50,39,148,0,50,39,47,25,148,0,47,25,40,16,148,0,40,16,27,12,148,0,27,12,8,9,148,0,8,9,8,0,50,61,50,39,114,16,50,61,114,16,106,24,50,61,106,24,102,37,27,319,8,331,8,321,213,213,225,161,217,238,155,310,118,313,118,312, 350,-88,350,-78,318,-74,288,-65,261,-51,236,-30,213,-2,232,1,248,6,263,12,277,21,290,32,309,54,324,77,335,104,342,133,344,166,336,224,314,272,279,308,234,330,180,338,127,330,82,308,47,272,25,224,17,166,18,140,23,115,31,92,42,70,55,50,67,36,79,25,94,16,111,7,132,0,153,-25,177,-48,206,-66,241,-78,282,-85,326,-88,16383,16383,287,169,285,139,281,111,275,85,266,64,255,47,243,35,230,25,215,18,198,13,180,11,163,13,146,18,129,26,115,37,103,50,93,68,85,89,79,113,75,139,74,167,76,196,80,222,87,247,96,268,107,285,119,297,133,307,147,314,163,318,179,320,193,319,206,316,219,312,231,306,242,297,257,280,270,258,279,232,285,202,287,169, 79,113,79,25,85,89,85,89,79,25,94,16,85,89,94,16,93,68,93,68,94,16,103,50,115,37,103,50,111,7,115,37,111,7,132,0,79,113,75,139,79,25,79,25,75,139,74,167,67,36,74,167,76,196,67,36,76,196,55,50,55,50,76,196,82,308,55,50,82,308,47,272,147,314,180,338,133,307,133,307,180,338,127,330,133,307,127,330,119,297,119,297,127,330,107,285,96,268,107,285,127,330,96,268,127,330,82,308,129,26,132,0,146,18,146,18,132,0,153,-25,146,18,153,-25,163,13,163,13,153,-25,177,-48,163,13,177,-48,180,11,180,11,177,-48,206,-66,180,11,206,-66,198,13,234,330,180,338,193,319,193,319,180,338,179,320,163,318,179,320,180,338,163,318,180,338,147,314,206,316,219,312,234,330,234,330,219,312,231,306,234,330,231,306,242,297,242,297,257,280,279,308,279,308,257,280,270,258,279,308,270,258,279,232,232,1,248,6,243,35,243,35,248,6,255,47,266,64,255,47,263,12,266,64,263,12,277,21,236,-30,213,-2,241,-78,215,18,213,-2,232,1,215,18,232,1,230,25,230,25,232,1,243,35,206,-66,241,-78,213,-2,206,-66,213,-2,215,18,206,-66,215,18,198,13,336,224,314,272,324,77,336,224,324,77,335,104,336,224,335,104,342,133,336,224,342,133,344,166,285,139,290,32,287,169,287,169,290,32,314,272,314,272,290,32,309,54,314,272,309,54,324,77,285,202,287,169,314,272,285,202,314,272,279,308,285,202,279,308,279,232,279,308,234,330,242,297,281,111,275,85,277,21,281,111,277,21,290,32,281,111,290,32,285,139,255,47,248,6,263,12,326,-88,350,-88,350,-78,326,-88,350,-78,318,-74,326,-88,318,-74,288,-65,326,-88,288,-65,282,-85,261,-51,236,-30,241,-78,261,-51,241,-78,282,-85,261,-51,282,-85,288,-65,82,308,76,196,80,222,82,308,80,222,87,247,82,308,87,247,96,268,18,140,23,115,25,224,25,224,23,115,31,92,25,224,31,92,47,272,47,272,31,92,42,70,47,272,42,70,55,50,103,50,94,16,111,7,18,140,25,224,17,166,266,64,277,21,275,85,234,330,193,319,206,316,115,37,132,0,129,26,79,25,74,167,67,36, 330,0,330,9,318,11,308,13,299,17,291,24,283,33,183,160,216,168,242,180,260,197,270,217,273,242,272,255,270,268,265,281,258,292,249,301,234,311,217,319,196,326,172,330,145,331,8,331,8,321,28,319,40,315,47,307,50,294,51,276,51,62,50,40,47,25,39,16,27,12,8,9,8,0,147,0,147,9,127,12,114,16,107,24,103,37,102,56,102,153,130,154,249,0,16383,16383,102,291,103,300,106,306,111,310,118,312,127,313,161,310,186,302,205,289,215,270,219,246,218,231,214,218,208,206,200,196,190,189,177,182,163,177,147,174,128,172,102,171, 118,312,127,312,127,313,145,331,127,313,161,310,145,331,161,310,172,330,172,330,161,310,186,302,172,330,186,302,196,326,196,326,186,302,205,289,196,326,205,289,217,319,217,319,205,289,215,270,217,319,215,270,219,246,214,218,208,206,216,168,216,168,208,206,200,196,216,168,200,196,190,189,190,189,177,182,183,160,183,160,177,182,163,177,183,160,163,177,249,0,249,0,163,177,147,174,249,0,147,174,130,154,130,154,147,174,128,172,130,154,128,172,102,171,265,281,258,292,260,197,260,197,258,292,249,301,260,197,249,301,242,180,242,180,249,301,234,311,242,180,234,311,219,246,219,246,234,311,217,319,214,218,216,168,218,231,218,231,216,168,242,180,218,231,242,180,219,246,270,217,273,242,272,255,270,217,272,255,270,268,270,217,270,268,265,281,270,217,265,281,260,197,190,189,183,160,216,168,318,11,308,13,330,0,330,0,308,13,299,17,330,0,299,17,249,0,249,0,299,17,291,24,249,0,291,24,283,33,102,56,102,171,51,276,102,56,51,276,103,37,103,37,51,276,51,62,102,171,102,153,130,154,145,331,8,331,28,319,145,331,28,319,40,315,145,331,40,315,47,307,145,331,47,307,50,294,145,331,50,294,51,276,145,331,51,276,111,310,145,331,111,310,118,312,145,331,118,312,127,313,102,291,103,300,51,276,102,291,51,276,102,171,106,306,111,310,51,276,106,306,51,276,103,300,147,0,147,9,127,12,147,0,127,12,114,16,147,0,114,16,50,40,147,0,50,40,47,25,147,0,47,25,39,16,147,0,39,16,27,12,147,0,27,12,8,9,147,0,8,9,8,0,51,62,50,40,114,16,51,62,114,16,107,24,51,62,107,24,103,37,28,319,8,331,8,321,183,160,249,0,283,33,318,11,330,0,330,9,161,310,127,313,127,312, 234,232,224,338,213,338,211,332,209,327,206,324,202,322,197,321,194,321,190,322,185,323,175,327,164,331,154,334,134,338,123,338,95,334,71,323,52,305,40,281,36,251,38,232,44,214,56,196,73,180,97,165,116,154,135,142,152,130,168,118,180,107,185,100,189,93,192,85,194,77,195,67,192,49,184,33,172,21,155,14,136,11,109,15,85,25,65,42,47,67,32,99,22,99,36,-6,47,-6,48,0,50,4,53,7,57,9,61,10,64,10,79,7,84,4,96,0,107,-2,131,-6,143,-6,176,-2,204,10,226,29,240,55,246,86,243,108,233,128,218,148,196,166,168,185,139,202,114,218,95,234,83,251,79,270,81,286,88,299,98,309,112,315,129,318,146,316,162,310,177,302,190,291,201,278,206,271,211,263,215,254,218,244,222,232, 50,4,53,7,65,42,65,42,53,7,57,9,65,42,57,9,61,10,61,10,64,10,65,42,65,42,64,10,69,9,65,42,69,9,85,25,85,25,69,9,74,8,85,25,74,8,79,7,95,234,83,251,97,165,97,165,83,251,79,270,73,180,79,270,71,323,73,180,71,323,56,196,56,196,71,323,52,305,56,196,52,305,44,214,44,214,52,305,40,281,44,214,40,281,38,232,38,232,40,281,36,251,81,286,88,299,95,334,95,334,88,299,98,309,95,334,98,309,123,338,123,338,98,309,112,315,123,338,112,315,129,318,129,318,146,316,134,338,134,338,146,316,144,336,81,286,95,334,71,323,81,286,71,323,79,270,134,338,123,338,129,318,144,336,146,316,154,334,154,334,146,316,162,310,154,334,162,310,164,331,164,331,162,310,177,302,164,331,177,302,175,327,175,327,177,302,180,325,95,234,97,165,114,218,114,218,97,165,116,154,114,218,116,154,139,202,139,202,116,154,135,142,139,202,135,142,152,130,136,11,119,-4,131,-6,136,11,131,-6,143,-6,136,11,109,15,119,-4,79,7,84,4,85,25,85,25,84,4,96,0,85,25,96,0,109,15,109,15,96,0,107,-2,109,15,107,-2,119,-4,36,-6,47,-6,47,67,47,67,47,-6,48,0,47,67,48,0,65,42,65,42,48,0,50,4,32,99,22,99,36,-6,32,99,36,-6,47,67,139,202,152,130,168,185,168,185,152,130,168,118,168,185,168,118,180,107,180,107,185,100,196,166,196,166,185,100,189,93,196,166,189,93,192,85,246,86,243,108,240,55,240,55,243,108,233,128,240,55,233,128,226,29,226,29,233,128,218,148,226,29,218,148,204,10,204,10,218,148,196,166,204,10,196,166,195,67,195,67,192,49,204,10,204,10,192,49,184,33,204,10,184,33,176,-2,176,-2,184,33,172,21,176,-2,172,21,155,14,196,166,192,85,194,77,196,166,194,77,195,67,196,166,168,185,180,107,155,14,136,11,143,-6,155,14,143,-6,176,-2,190,291,201,278,194,321,194,321,201,278,197,321,202,322,197,321,201,278,190,291,194,321,190,322,190,291,190,322,185,323,190,291,185,323,180,325,190,291,180,325,177,302,224,338,213,338,215,254,224,338,215,254,218,244,224,338,218,244,222,232,224,338,222,232,234,232,206,324,206,271,209,327,209,327,206,271,211,263,209,327,211,263,211,332,211,332,211,263,215,254,211,332,215,254,213,338,202,322,201,278,206,271,202,322,206,271,206,324,97,165,79,270,73,180, 296,246,293,331,12,331,8,246,21,246,27,274,37,292,50,303,70,309,97,310,127,310,127,61,126,39,123,25,115,16,101,12,80,9,80,0,226,0,226,9,205,11,192,16,183,23,179,36,178,55,178,310,208,310,235,309,254,303,268,292,277,274,285,246, 293,331,12,331,70,309,293,331,70,309,97,310,293,331,97,310,127,310,293,331,127,310,178,310,293,331,178,310,208,310,293,331,208,310,235,309,293,331,235,309,254,303,293,331,254,303,268,292,293,331,268,292,277,274,293,331,277,274,285,246,293,331,285,246,296,246,192,16,183,23,127,61,127,61,183,23,179,36,127,61,179,36,127,310,127,310,179,36,178,55,127,310,178,55,178,310,12,331,8,246,21,246,12,331,21,246,27,274,12,331,27,274,37,292,12,331,37,292,50,303,12,331,50,303,70,309,226,0,226,9,205,11,226,0,205,11,192,16,226,0,192,16,126,39,226,0,126,39,123,25,226,0,123,25,115,16,226,0,115,16,101,12,226,0,101,12,80,9,226,0,80,9,80,0,126,39,192,16,127,61, 353,331,237,331,237,321,257,319,270,312,279,301,282,283,283,257,283,103,282,85,279,70,273,57,265,45,254,34,241,26,225,20,208,16,189,15,173,16,158,19,146,24,135,30,125,37,115,50,109,63,105,79,104,97,103,118,103,275,104,293,108,306,115,314,128,319,148,321,148,331,7,331,7,321,27,319,40,315,47,308,51,297,52,280,52,124,53,95,58,69,66,48,78,30,93,16,106,8,121,1,138,-3,157,-5,177,-6,204,-5,227,0,247,6,264,17,278,30,290,45,297,62,302,81,305,104,305,258,306,282,310,300,318,311,331,318,353,321, 105,79,106,8,109,63,109,63,106,8,121,1,109,63,121,1,115,50,115,50,121,1,125,37,135,30,125,37,138,-3,135,30,138,-3,146,24,146,24,138,-3,157,-5,146,24,157,-5,158,19,158,19,157,-5,177,-6,158,19,177,-6,173,16,173,16,177,-6,189,15,208,16,189,15,204,-5,208,16,204,-5,227,0,103,118,103,275,93,16,103,118,93,16,104,97,104,97,93,16,106,8,104,97,106,8,105,79,125,37,121,1,138,-3,283,103,282,85,290,45,290,45,282,85,279,70,290,45,279,70,278,30,278,30,279,70,273,57,278,30,273,57,265,45,265,45,254,34,264,17,264,17,254,34,247,6,241,26,225,20,227,0,241,26,227,0,247,6,241,26,247,6,254,34,353,331,237,331,257,319,353,331,257,319,270,312,353,331,270,312,279,301,353,331,279,301,318,311,353,331,318,311,331,318,353,331,331,318,353,321,305,258,306,282,297,62,305,258,297,62,302,81,305,258,302,81,305,104,305,258,305,104,305,131,290,45,297,62,306,282,290,45,306,282,283,257,290,45,283,257,283,125,290,45,283,125,283,103,310,300,318,311,282,283,310,300,282,283,283,257,310,300,283,257,306,282,265,45,264,17,278,30,189,15,177,-6,204,-5,128,319,148,321,148,331,128,319,148,331,115,314,115,314,148,331,51,297,115,314,51,297,52,280,53,95,52,280,52,124,58,69,66,48,104,293,104,293,66,48,78,30,104,293,78,30,103,275,103,275,78,30,93,16,104,293,108,306,52,280,104,293,52,280,53,95,104,293,53,95,58,69,148,331,7,331,27,319,148,331,27,319,40,315,148,331,40,315,47,308,148,331,47,308,51,297,27,319,7,331,7,321,115,314,52,280,108,306,257,319,237,331,237,321,318,311,279,301,282,283,208,16,227,0,225,20, 349,331,247,331,247,321,258,321,268,319,276,316,281,310,282,301,282,295,281,289,279,282,276,274,273,265,200,80,123,252,116,269,110,283,106,292,104,300,104,305,105,310,107,314,112,317,118,319,127,320,141,321,141,331,8,331,8,321,21,320,31,316,41,307,50,291,62,267,184,-5,191,-5,302,276,311,295,319,308,328,316,338,320,349,321, 62,267,184,-5,62,267,62,267,184,-5,104,300,62,267,104,300,104,305,104,305,105,310,62,267,62,267,105,310,107,314,62,267,107,314,50,291,141,331,8,331,21,320,141,331,21,320,31,316,141,331,31,316,41,307,141,331,41,307,50,291,141,331,50,291,112,317,141,331,112,317,118,319,141,331,118,319,127,320,141,331,127,320,141,321,281,289,279,282,302,276,302,276,279,282,276,274,302,276,276,274,273,265,273,265,200,80,302,276,302,276,200,80,191,-5,349,331,247,331,258,321,349,331,258,321,268,319,349,331,268,319,276,316,349,331,276,316,281,310,349,331,281,310,282,301,349,331,282,301,328,316,349,331,328,316,338,320,349,331,338,320,349,321,282,301,302,276,311,295,282,301,311,295,319,308,282,301,319,308,328,316,282,295,281,289,302,276,282,295,302,276,282,301,184,-5,191,-5,200,80,184,-5,200,80,123,252,184,-5,123,252,116,269,184,-5,116,269,110,283,184,-5,110,283,106,292,184,-5,106,292,104,300,258,321,247,331,247,321,21,320,8,331,8,321,112,317,50,291,107,314, 466,331,368,331,368,321,381,320,391,318,397,314,401,308,402,301,402,294,401,287,399,280,397,271,394,262,331,93,259,275,255,289,253,295,252,300,251,304,253,310,257,315,265,318,276,320,290,321,290,331,157,331,157,321,171,320,182,317,191,309,199,295,208,273,222,236,170,94,98,282,96,288,95,293,93,298,93,311,96,316,102,319,111,321,124,321,124,331,2,331,2,321,16,320,27,314,36,303,45,286,55,262,73,210,92,157,132,49,151,-5,158,-5,235,206,251,165,267,123,299,37,315,-5,323,-5,344,61,361,111,377,158,397,212,425,286,430,299,436,308,443,314,453,318,466,321, 16,320,27,314,124,331,124,331,27,314,36,303,124,331,36,303,96,316,96,316,36,303,45,286,96,316,45,286,55,262,55,262,73,210,93,311,93,311,73,210,93,306,93,302,93,306,92,157,93,302,92,157,112,103,111,321,124,321,124,331,111,321,124,331,102,319,102,319,124,331,96,316,93,306,73,210,92,157,96,316,55,262,93,311,2,331,2,321,16,320,2,331,16,320,124,331,251,165,267,123,251,304,251,304,253,310,222,236,222,236,253,310,208,273,199,295,208,273,257,315,199,295,257,315,290,331,290,331,257,315,265,318,290,331,265,318,276,320,276,320,290,321,290,331,251,304,222,236,235,206,251,304,235,206,251,165,257,315,208,273,253,310,290,331,157,331,171,320,290,331,171,320,182,317,290,331,182,317,191,309,290,331,191,309,199,295,394,262,361,111,377,158,394,262,377,158,397,212,394,262,331,93,344,61,394,262,344,61,361,111,331,93,259,275,267,123,331,93,267,123,283,80,331,93,283,80,299,37,331,93,299,37,315,-5,331,93,315,-5,323,-5,331,93,323,-5,344,61,267,123,259,275,257,282,267,123,257,282,255,289,267,123,255,289,253,295,267,123,253,295,252,300,267,123,252,300,251,304,402,294,401,287,425,286,425,286,401,287,399,280,425,286,399,280,397,212,397,212,399,280,397,271,397,212,397,271,394,262,402,301,425,286,430,299,402,301,430,299,436,308,402,301,436,308,443,314,402,301,443,314,466,331,402,301,466,331,401,308,402,294,425,286,402,301,453,318,466,321,466,331,453,318,466,331,443,314,466,331,368,331,381,320,466,331,381,320,391,318,466,331,391,318,397,314,466,331,397,314,401,308,170,94,98,282,112,103,170,94,112,103,132,49,170,94,132,49,151,-5,170,94,151,-5,158,-5,170,94,158,-5,235,206,170,94,235,206,222,236,112,103,98,282,96,288,112,103,96,288,95,293,112,103,95,293,93,298,112,103,93,298,93,302,381,320,368,331,368,321,171,320,157,331,157,321, 352,0,352,9,338,12,327,16,317,22,307,32,296,46,200,184,272,272,289,292,303,305,316,314,331,319,348,321,348,331,229,331,229,321,243,320,253,319,259,316,262,311,263,305,263,301,260,296,257,290,251,282,243,272,188,202,166,234,151,255,139,272,131,286,126,297,124,306,125,312,128,316,133,319,139,320,147,321,161,321,161,331,11,331,11,321,29,319,44,312,59,299,78,276,103,242,156,164,78,66,58,42,43,26,31,17,19,12,5,9,5,0,121,0,121,9,106,11,95,13,88,17,84,21,83,26,84,31,87,38,92,46,100,57,109,70,169,145,217,74,226,60,233,48,238,38,241,31,242,25,241,20,238,16,233,14,226,12,217,11,204,9,204,0, 31,17,121,0,43,26,43,26,121,0,88,17,43,26,88,17,58,42,58,42,88,17,84,21,58,42,84,21,83,26,83,26,84,31,78,66,78,66,84,31,87,38,78,66,87,38,156,164,156,164,87,38,92,46,156,164,92,46,100,57,103,242,156,164,126,297,103,242,126,297,124,306,124,306,125,312,103,242,156,164,100,57,109,70,109,70,169,145,156,164,156,164,169,145,166,234,156,164,166,234,151,255,78,66,58,42,83,26,103,242,125,312,78,276,78,276,125,312,128,316,78,276,128,316,59,299,59,299,128,316,133,319,59,299,133,319,161,331,161,331,133,319,139,320,161,331,139,320,147,321,147,321,161,321,161,331,161,331,11,331,29,319,161,331,29,319,44,312,161,331,44,312,59,299,260,296,257,290,272,272,272,272,257,290,251,282,272,272,251,282,243,272,243,272,188,202,200,184,200,184,188,202,217,74,200,184,217,74,296,46,296,46,217,74,226,60,296,46,226,60,233,48,348,331,229,331,243,320,348,331,243,320,253,319,348,331,253,319,259,316,348,331,259,316,262,311,348,331,262,311,263,305,348,331,263,305,316,314,348,331,316,314,331,319,348,331,331,319,348,321,263,305,272,272,289,292,263,305,289,292,303,305,263,305,303,305,316,314,263,301,260,296,272,272,263,301,272,272,263,305,243,272,200,184,272,272,238,16,233,14,352,0,352,0,233,14,226,12,352,0,226,12,217,11,242,25,352,0,327,16,242,25,327,16,317,22,242,25,317,22,307,32,242,25,307,32,296,46,242,25,296,46,241,31,296,46,233,48,238,38,296,46,238,38,241,31,188,202,166,234,169,145,188,202,169,145,217,74,338,12,327,16,352,0,338,12,352,0,352,9,241,20,238,16,352,0,241,20,352,0,242,25,204,9,204,0,352,0,204,9,352,0,217,11,156,164,151,255,139,272,156,164,139,272,131,286,156,164,131,286,126,297,121,0,121,9,106,11,121,0,106,11,95,13,121,0,95,13,88,17,19,12,5,9,121,0,19,12,121,0,31,17,121,0,5,9,5,0,243,320,229,331,229,321,29,319,11,331,11,321, 352,331,243,331,243,321,256,321,266,319,272,316,275,312,276,306,276,302,274,294,272,290,270,285,197,174,124,285,121,289,118,294,116,299,115,304,115,308,116,312,119,316,123,318,130,320,138,321,151,321,151,331,11,331,11,321,24,319,37,313,50,299,68,277,92,243,157,147,157,61,156,39,152,25,144,16,129,12,107,9,107,0,260,0,260,9,239,11,224,15,215,23,210,36,209,55,209,151,282,266,297,288,310,303,322,313,336,319,352,321, 121,289,118,294,157,147,157,147,118,294,116,299,157,147,116,299,92,243,92,243,116,299,115,304,92,243,115,304,115,308,115,308,116,312,92,243,151,331,11,331,24,319,151,331,24,319,37,313,151,331,37,313,50,299,151,331,50,299,123,318,151,331,123,318,130,320,151,331,130,320,138,321,151,331,138,321,151,321,123,318,50,299,119,316,119,316,50,299,68,277,119,316,68,277,116,312,116,312,68,277,92,243,209,55,209,151,197,174,209,55,197,174,210,36,210,36,197,174,157,147,210,36,157,147,215,23,215,23,157,147,157,61,215,23,157,61,224,15,224,15,157,61,156,39,224,15,156,39,260,0,260,0,156,39,152,25,260,0,152,25,144,16,275,298,274,294,282,266,282,266,274,294,272,290,282,266,272,290,270,285,270,285,197,174,209,151,352,331,243,331,256,321,352,331,256,321,266,319,352,331,266,319,272,316,352,331,272,316,275,312,352,331,275,312,276,306,352,331,276,306,322,313,352,331,322,313,336,319,352,331,336,319,352,321,276,306,282,266,297,288,276,306,297,288,310,303,276,306,310,303,322,313,282,266,276,306,276,302,282,266,276,302,275,298,270,285,209,151,282,266,239,11,224,15,260,0,239,11,260,0,260,9,129,12,107,9,260,0,129,12,260,0,144,16,124,285,121,289,157,147,124,285,157,147,197,174,260,0,107,9,107,0,256,321,243,331,243,321,24,319,11,331,11,321, 299,88,287,88,282,72,278,59,273,49,266,40,257,33,249,28,240,24,228,21,215,20,199,19,73,19,289,324,289,331,26,331,16,246,29,246,32,260,35,271,38,279,43,287,50,295,58,301,68,306,81,309,97,311,117,312,224,312,5,7,5,0,286,0, 35,271,38,279,26,331,26,331,38,279,43,287,26,331,43,287,50,295,50,295,58,301,26,331,26,331,58,301,68,306,26,331,68,306,81,309,73,19,289,324,224,312,224,312,289,324,289,331,224,312,289,331,117,312,97,311,117,312,289,331,97,311,289,331,26,331,26,331,16,246,29,246,26,331,29,246,32,260,26,331,32,260,35,271,224,312,5,7,73,19,73,19,5,7,286,0,73,19,286,0,199,19,199,19,286,0,215,20,278,59,273,49,286,0,286,0,273,49,266,40,286,0,266,40,257,33,257,33,249,28,286,0,286,0,249,28,240,24,286,0,240,24,228,21,286,0,299,88,287,88,286,0,287,88,282,72,286,0,282,72,278,59,286,0,5,7,5,0,215,20,286,0,228,21,26,331,81,309,97,311, 150,-77,150,-64,108,-64,99,-63,92,-61,86,-56,83,-48,82,-38,82,295,83,304,86,311,92,315,99,318,108,319,150,319,150,331,44,331,44,-77, 86,311,92,315,44,331,44,331,92,315,99,318,44,331,99,318,150,331,150,331,99,318,108,319,82,-38,82,295,44,331,82,-38,44,331,44,-77,82,-38,44,-77,83,-48,83,304,86,311,44,331,83,304,44,331,82,295,150,-64,108,-64,150,-77,150,-77,108,-64,99,-63,150,-77,99,-63,44,-77,44,-77,99,-63,92,-61,44,-77,92,-61,86,-56,83,-48,44,-77,86,-56,150,331,108,319,150,319, 143,-6,29,338,-3,338,109,-6, 143,-6,29,338,-3,338,143,-6,-3,338,109,-6, 123,-77,123,331,17,331,17,319,59,319,69,318,76,314,81,309,83,301,84,291,84,-50,81,-56,77,-61,70,-63,61,-64,17,-64,17,-77, 123,-77,123,331,84,291,123,-77,84,291,84,-41,123,-77,84,-41,84,-50,123,-77,84,-50,81,-56,123,-77,81,-56,77,-61,123,-77,77,-61,70,-63,123,-77,70,-63,61,-64,123,-77,61,-64,17,-64,123,-77,17,-64,17,-77,76,314,81,309,123,331,123,331,81,309,83,301,123,331,83,301,84,291,123,331,17,331,59,319,123,331,59,319,69,318,123,331,69,318,76,314,59,319,17,331,17,319, 223,148,132,331,103,331,12,148,46,148,118,293,189,148, 12,148,46,148,103,331,103,331,46,148,118,293,103,331,118,293,132,331,132,331,118,293,189,148,132,331,189,148,223,148, 250,-62,250,-36,0,-36,0,-62, 250,-62,250,-36,0,-36,250,-62,0,-36,0,-62, 121,253,49,328,44,332,40,335,35,337,27,339,21,338,16,336,12,333,10,329,9,323,10,318,12,314,15,309,19,305,24,301,101,253, 101,253,121,253,49,328,101,253,49,328,44,332,101,253,44,332,40,335,101,253,40,335,35,337,101,253,35,337,31,338,101,253,31,338,27,339,101,253,27,339,24,301,9,323,10,318,10,329,10,329,10,318,12,314,10,329,12,314,12,333,12,333,12,314,15,309,12,333,15,309,16,336,16,336,15,309,19,305,16,336,19,305,21,338,21,338,19,305,24,301,21,338,24,301,27,339, 221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,184,56,186,-3,185,44,29,167,29,183,28,175, 76,340,74,342,62,338,51,334,41,331,29,328,17,324,2,320,2,311,5,311,6,312,10,312,21,311,28,309,32,304,34,296,35,283,35,28,39,18,52,9,71,2,93,-2,117,-4,155,1,187,18,212,44,228,78,234,120,230,155,218,185,199,209,174,224,144,230,126,228,110,223,96,214,85,202,76,188,16383,16383,76,159,79,171,86,182,97,191,111,197,126,199,137,198,146,195,155,190,164,183,171,175,177,163,183,149,186,133,189,116,190,99,189,82,187,67,183,54,178,42,171,32,164,25,156,19,147,15,136,12,125,11,110,12,97,16,86,21,79,28,76,37, 5,311,6,312,17,324,17,324,6,312,8,312,17,324,8,312,10,312,10,312,21,311,17,324,17,324,21,311,29,328,97,16,86,21,93,-2,93,-2,86,21,79,28,93,-2,79,28,71,2,71,2,79,28,76,37,71,2,76,37,74,342,74,342,76,37,76,188,74,342,76,188,76,340,62,338,51,334,52,9,52,9,51,334,41,331,52,9,41,331,39,18,39,18,41,331,35,283,39,18,35,283,35,28,3,311,5,311,17,324,3,311,17,324,2,320,3,311,2,320,2,311,156,19,147,15,155,1,155,1,147,15,136,12,155,1,136,12,125,11,125,11,110,12,117,-4,117,-4,110,12,97,16,117,-4,97,16,93,-2,62,338,52,9,71,2,62,338,71,2,74,342,21,311,28,309,29,328,29,328,28,309,32,304,29,328,32,304,41,331,41,331,32,304,34,296,41,331,34,296,35,283,126,228,126,199,137,198,126,228,137,198,144,230,144,230,137,198,146,195,144,230,146,195,174,224,174,224,146,195,155,190,174,224,155,190,164,183,76,159,79,171,85,202,85,202,79,171,86,182,85,202,86,182,96,214,96,214,86,182,97,191,96,214,97,191,110,223,110,223,97,191,111,197,110,223,111,197,126,228,126,228,111,197,126,199,76,159,85,202,76,188,76,159,76,188,76,37,174,224,171,175,177,163,174,224,177,163,199,209,199,209,177,163,183,149,199,209,183,149,186,133,187,67,183,54,187,18,187,18,183,54,178,42,187,18,178,42,171,32,171,32,164,25,187,18,187,18,164,25,156,19,187,18,156,19,155,1,234,120,230,155,228,78,228,78,230,155,218,185,228,78,218,185,212,44,212,44,218,185,199,209,212,44,199,209,190,99,190,99,199,209,189,116,187,67,187,18,189,82,189,82,187,18,212,44,189,82,212,44,190,99,125,11,117,-4,155,1,199,209,186,133,189,116,174,224,164,183,171,175, 199,78,185,60,172,46,159,38,144,33,128,31,103,36,81,49,65,69,54,96,51,128,54,157,63,181,78,200,96,211,119,215,128,215,136,212,141,208,145,201,148,191,151,180,154,172,159,166,163,161,169,158,175,157,183,158,189,161,195,166,198,172,199,179,195,195,184,209,167,220,146,227,122,230,108,229,94,226,80,221,67,213,55,204,40,189,28,172,19,152,14,130,12,106,17,70,30,39,50,15,76,0,108,-4,120,-3,132,-1,144,3,155,9,165,16,174,24,181,32,189,43,197,57,206,74, 81,49,65,69,76,0,76,0,65,69,54,96,76,0,54,96,50,15,50,15,54,96,51,128,55,204,51,128,54,157,55,204,54,157,63,181,128,31,108,-4,120,-3,128,31,120,-3,132,-1,128,31,103,36,108,-4,81,49,76,0,108,-4,81,49,108,-4,103,36,136,212,141,208,146,227,146,227,141,208,145,201,146,227,145,201,148,191,148,191,151,180,167,220,167,220,151,180,154,172,167,220,154,172,159,166,122,230,119,215,128,215,122,230,128,215,146,227,146,227,128,215,136,212,195,195,184,209,189,161,195,195,189,161,195,166,195,195,195,166,198,172,195,195,198,172,199,179,184,209,167,220,169,158,184,209,169,158,175,157,184,209,175,157,183,158,184,209,183,158,189,161,167,220,159,166,163,161,167,220,163,161,169,158,167,220,146,227,148,191,174,24,181,32,185,60,185,60,181,32,189,43,185,60,189,43,199,78,199,78,189,43,197,57,199,78,197,57,206,74,132,-1,144,3,144,33,144,33,144,3,155,9,144,33,155,9,159,38,159,38,155,9,165,16,159,38,165,16,172,46,172,46,165,16,174,24,172,46,174,24,185,60,144,33,128,31,132,-1,96,211,119,215,108,229,96,211,108,229,94,226,96,211,94,226,80,221,96,211,80,221,78,200,67,213,55,204,63,181,67,213,63,181,78,200,67,213,78,200,80,221,40,189,28,172,30,39,40,189,30,39,50,15,40,189,50,15,51,128,40,189,51,128,55,204,19,152,14,130,17,70,19,152,17,70,30,39,19,152,30,39,28,172,119,215,122,230,108,229,17,70,14,130,12,106, 246,21,246,29,239,29,237,28,234,28,225,29,218,32,215,37,213,45,212,57,212,340,209,342,195,337,169,329,154,324,136,320,136,311,138,312,147,312,156,311,163,309,167,304,170,297,170,209,159,217,149,223,139,227,129,229,118,230,85,223,56,206,34,178,19,143,13,103,18,67,30,37,49,14,75,0,106,-4,122,-3,136,0,148,7,160,16,170,28,170,-2,172,-4,16383,16383,170,51,170,49,169,46,165,40,162,37,157,31,150,27,143,24,135,22,126,21,102,26,83,39,69,60,60,88,56,123,59,154,67,180,80,199,98,212,119,216,135,213,149,206,160,195,167,181,170,166, 170,209,159,217,160,195,160,195,159,217,149,223,160,195,149,223,149,206,149,206,149,223,139,227,149,206,139,227,135,213,135,213,139,227,129,229,135,213,129,229,119,216,67,180,80,199,85,223,85,223,80,199,98,212,85,223,98,212,118,230,118,230,98,212,119,216,118,230,119,216,129,229,13,103,18,67,19,143,19,143,18,67,30,37,19,143,30,37,34,178,34,178,30,37,49,14,34,178,49,14,56,206,56,206,49,14,56,123,56,206,56,123,59,154,56,206,59,154,67,180,56,206,67,180,85,223,126,21,106,-4,122,-3,126,21,122,-3,136,0,126,21,102,26,106,-4,83,39,69,60,75,0,83,39,75,0,106,-4,83,39,106,-4,102,26,60,88,56,123,49,14,60,88,49,14,75,0,60,88,75,0,69,60,169,46,167,43,170,28,170,28,167,43,165,40,170,28,165,40,162,37,162,37,157,31,160,16,160,16,157,31,150,27,160,16,150,27,148,7,148,7,150,27,143,24,148,7,143,24,136,0,136,0,143,24,135,22,136,0,135,22,126,21,140,312,142,312,154,324,154,324,142,312,145,312,154,324,145,312,147,312,147,312,156,311,154,324,154,324,156,311,169,329,154,324,136,320,138,312,154,324,138,312,140,312,170,209,170,166,170,28,170,209,170,28,170,286,170,297,170,286,182,333,170,297,182,333,169,329,170,209,160,195,167,181,170,209,167,181,170,166,172,-4,246,21,225,29,172,-4,225,29,218,32,172,-4,218,32,215,37,172,-4,215,37,213,45,172,-4,213,45,182,333,172,-4,182,333,170,28,172,-4,170,28,170,-2,170,28,170,166,170,51,170,28,170,51,170,49,170,28,170,49,169,46,162,37,160,16,170,28,212,57,212,340,209,342,212,57,209,342,195,337,212,57,195,337,213,45,239,29,237,28,246,21,246,21,237,28,235,28,246,21,235,28,234,28,234,28,225,29,246,21,241,29,239,29,246,21,241,29,246,21,246,29,169,329,156,311,163,309,169,329,163,309,167,304,169,329,167,304,170,297,138,312,136,320,136,311,182,333,170,286,170,28,182,333,213,45,195,337, 204,82,190,62,176,48,162,37,146,31,127,30,114,31,101,34,90,39,80,47,71,57,62,71,56,85,52,100,50,118,49,138,203,138,201,153,198,166,195,177,185,195,175,207,163,217,149,224,133,228,116,230,81,224,52,207,31,182,17,148,12,108,17,70,29,39,49,15,75,0,108,-4,136,-1,160,9,181,26,198,49,212,79,16383,16383,50,155,55,175,63,191,74,203,87,210,103,212,120,210,133,203,141,192,147,176,151,155, 52,100,50,118,49,15,49,15,50,118,49,138,49,15,49,138,31,182,49,15,31,182,29,39,29,39,31,182,17,148,29,39,17,148,17,70,17,70,17,148,12,108,133,228,116,230,120,210,120,210,116,230,103,212,87,210,103,212,116,230,87,210,116,230,81,224,190,62,176,48,181,26,181,26,176,48,162,37,181,26,162,37,160,9,160,9,162,37,146,31,160,9,146,31,136,-1,136,-1,146,31,127,30,203,138,201,153,198,166,203,138,198,166,195,177,203,138,195,177,190,186,203,138,190,186,185,195,203,138,185,195,175,207,203,138,175,207,163,217,203,138,163,217,151,155,203,138,151,155,50,155,203,138,50,155,49,138,141,192,147,176,149,224,149,224,147,176,151,155,149,224,151,155,163,217,198,49,212,79,204,82,198,49,204,82,190,62,198,49,190,62,181,26,114,31,101,34,108,-4,114,31,108,-4,136,-1,114,31,136,-1,127,30,101,34,90,39,108,-4,108,-4,90,39,80,47,108,-4,80,47,75,0,75,0,80,47,71,57,133,228,120,210,133,203,133,228,133,203,141,192,133,228,141,192,149,224,50,155,55,175,52,207,52,207,55,175,63,191,52,207,63,191,81,224,81,224,63,191,74,203,81,224,74,203,87,210,52,207,31,182,49,138,52,207,49,138,50,155,75,0,71,57,62,71,75,0,62,71,56,85,75,0,56,85,52,100,75,0,52,100,49,15, 11,225,11,209,51,209,51,52,50,34,47,21,40,13,28,9,10,7,10,0,140,0,140,7,119,9,106,13,98,21,95,33,94,52,94,209,155,209,155,225,94,225,94,283,95,299,98,311,104,320,111,326,122,328,128,327,133,325,138,321,143,316,148,308,153,301,157,296,161,293,166,291,171,290,177,291,183,294,188,298,190,304,191,310,189,321,182,329,171,336,156,340,140,342,121,340,105,335,90,328,78,318,69,305,62,292,57,279,54,264,52,247,51,225, 57,279,54,264,95,33,95,33,54,264,52,247,95,33,52,247,51,209,51,209,52,247,51,225,51,209,51,225,11,225,78,318,95,33,94,52,94,225,94,209,155,209,94,225,155,209,155,225,133,325,140,342,128,327,128,327,140,342,122,328,111,326,122,328,121,340,111,326,121,340,105,335,94,283,95,299,90,328,90,328,95,299,98,311,90,328,98,311,105,335,105,335,98,311,104,320,105,335,104,320,111,326,90,328,78,318,94,52,90,328,94,52,94,283,189,321,182,329,183,294,189,321,183,294,188,298,189,321,188,298,190,304,189,321,190,304,191,310,166,291,171,290,171,336,171,336,171,290,177,291,171,336,177,291,182,329,182,329,177,291,183,294,148,308,153,301,156,340,156,340,153,301,157,296,156,340,157,296,171,336,171,336,157,296,161,293,171,336,161,293,166,291,143,316,148,308,156,340,143,316,156,340,140,342,143,316,140,342,138,321,140,342,121,340,122,328,140,0,140,7,119,9,140,0,119,9,106,13,140,0,106,13,50,34,140,0,50,34,47,21,140,0,47,21,40,13,140,0,40,13,28,9,140,0,28,9,10,7,140,0,10,7,10,0,95,33,78,318,69,305,95,33,69,305,62,292,95,33,62,292,57,279,51,52,50,34,106,13,51,52,106,13,98,21,51,52,98,21,95,33,51,52,95,33,51,209,51,209,11,225,11,209,140,342,133,325,138,321, 235,194,235,214,185,214,180,215,175,217,169,219,158,223,134,229,126,230,118,230,91,226,68,214,51,197,39,174,35,148,36,131,41,116,50,103,63,92,81,81,77,77,72,73,60,61,51,53,44,46,40,39,37,33,36,27,37,21,40,16,44,11,52,6,63,1,44,-13,30,-26,21,-37,16,-48,14,-59,18,-75,31,-88,49,-98,73,-105,100,-108,122,-106,144,-102,165,-96,184,-87,200,-76,211,-66,220,-56,226,-46,229,-35,230,-24,228,-6,220,7,207,18,190,26,170,29,105,32,91,33,80,35,72,38,68,41,66,46,68,52,73,60,80,67,88,73,97,77,106,76,111,75,125,75,136,76,146,78,157,82,167,87,177,94,186,103,194,113,199,124,202,137,203,152,203,160,202,168,200,176,194,194,16383,16383,76,169,78,185,82,198,90,208,100,214,113,216,122,215,130,212,137,207,144,201,150,193,155,181,159,169,162,157,164,145,165,132,163,117,158,104,150,95,140,89,127,87,110,91,96,102,85,118,78,141,76,167,16383,16383,217,-31,212,-47,200,-60,180,-71,153,-77,122,-79,97,-78,77,-73,62,-65,52,-55,49,-43,50,-36,52,-30,56,-22,63,-13,74,0,86,-2,102,-4,138,-6,155,-6,178,-7,196,-10,208,-14,214,-21,217,-31, 85,118,81,81,88,73,88,73,81,81,80,67,80,67,81,81,77,77,80,67,77,77,73,60,73,60,77,77,72,73,73,60,72,73,68,52,68,52,72,73,68,69,68,52,68,69,66,46,66,46,64,65,63,-13,63,-13,64,65,63,1,116,75,127,87,111,75,111,75,127,87,110,91,111,75,110,91,106,76,106,76,110,91,97,77,88,73,97,77,96,102,88,73,96,102,85,118,118,230,113,216,122,215,118,230,122,215,126,230,126,230,122,215,130,212,126,230,130,212,134,229,134,229,130,212,137,207,134,229,137,207,142,227,142,227,137,207,144,201,142,227,144,201,150,225,150,225,144,201,150,193,127,87,116,75,120,75,127,87,120,75,123,75,127,87,123,75,125,75,127,87,125,75,136,76,110,91,96,102,97,77,169,219,158,223,159,169,169,219,159,169,162,157,169,219,162,157,164,145,169,219,164,145,165,132,169,219,165,132,167,87,169,219,167,87,177,94,169,219,177,94,175,217,167,87,165,132,163,117,167,87,163,117,158,104,167,87,158,104,157,82,127,87,136,76,140,89,140,89,136,76,146,78,140,89,146,78,150,95,150,95,146,78,157,82,150,95,157,82,158,104,82,198,90,208,91,226,91,226,90,208,100,214,91,226,100,214,118,230,118,230,100,214,113,216,76,167,76,169,68,214,68,214,76,169,78,185,68,214,78,185,91,226,91,226,78,185,82,198,81,81,85,118,78,141,81,81,78,141,76,167,81,81,76,167,68,214,81,81,68,214,63,92,51,197,39,174,41,116,51,197,41,116,50,103,51,197,50,103,63,92,51,197,63,92,68,214,39,174,35,148,36,131,39,174,36,131,41,116,51,53,44,46,44,11,51,53,44,11,52,6,51,53,52,6,60,61,36,27,37,21,37,33,37,33,37,21,40,16,37,33,40,16,40,39,40,39,40,16,44,11,40,39,44,11,44,46,30,-26,31,-88,44,-13,44,-13,31,-88,49,-98,44,-13,49,-98,49,-43,49,-43,50,-36,44,-13,44,-13,50,-36,52,-30,44,-13,52,-30,63,1,63,1,52,-30,56,-22,63,1,56,-22,63,-13,74,0,72,38,68,41,74,0,68,41,66,46,74,0,66,46,63,-13,74,0,80,35,72,38,60,61,52,6,63,1,60,61,63,1,64,65,62,-65,73,-105,77,-73,77,-73,73,-105,100,-108,77,-73,100,-108,97,-78,97,-78,100,-108,122,-79,153,-77,122,-79,122,-106,153,-77,122,-106,144,-102,52,-55,49,-43,49,-98,52,-55,49,-98,73,-105,52,-55,73,-105,62,-65,21,-37,16,-48,18,-75,21,-37,18,-75,31,-88,21,-37,31,-88,30,-26,196,214,191,214,194,194,196,214,194,194,235,194,196,214,235,194,235,214,202,137,203,152,203,160,202,137,203,160,202,168,202,137,202,168,200,176,202,137,200,176,199,124,197,185,194,194,194,113,197,185,194,113,199,124,197,185,199,124,200,176,191,214,185,214,186,103,191,214,186,103,194,113,191,214,194,113,194,194,180,215,175,217,177,94,180,215,177,94,186,103,180,215,186,103,185,214,155,181,159,169,158,223,155,181,158,223,150,225,155,181,150,225,150,193,208,-14,214,-21,220,7,220,7,214,-21,217,-31,220,-56,217,-31,212,-47,138,-6,155,-6,170,29,170,29,155,-6,178,-7,170,29,178,-7,190,26,190,26,178,-7,196,-10,190,26,196,-10,207,18,207,18,196,-10,208,-14,207,18,208,-14,220,7,228,-6,220,7,220,-56,228,-6,220,-56,226,-46,228,-6,226,-46,229,-35,228,-6,229,-35,230,-24,153,-77,165,-96,180,-71,180,-71,165,-96,184,-87,180,-71,184,-87,200,-60,200,-60,184,-87,200,-76,200,-60,200,-76,212,-47,212,-47,200,-76,211,-66,212,-47,211,-66,220,-56,138,-6,170,29,120,-5,120,-5,170,29,105,32,120,-5,105,32,102,-4,102,-4,105,32,91,33,102,-4,91,33,86,-2,86,-2,91,33,80,35,86,-2,80,35,74,0,122,-79,100,-108,122,-106,153,-77,144,-102,165,-96,217,-31,220,-56,220,7,18,-75,16,-48,14,-59,64,65,66,46,68,69, 243,0,243,7,230,10,221,15,216,22,214,34,214,151,211,179,204,201,191,217,174,227,152,230,135,228,120,224,106,216,92,204,79,188,79,340,76,342,66,338,46,332,34,328,18,324,5,320,5,311,6,312,11,312,22,311,29,309,34,305,36,297,36,33,33,22,28,15,19,10,4,7,4,0,113,0,113,7,98,10,88,14,82,22,79,34,79,171,90,184,101,193,112,199,123,202,134,203,148,201,158,195,165,184,170,169,171,150,171,34,168,22,162,14,152,10,137,7,137,0, 33,22,28,15,113,0,113,0,28,15,19,10,113,0,19,10,4,7,7,312,9,312,18,324,18,324,9,312,10,312,18,324,10,312,11,312,11,312,22,311,18,324,18,324,22,311,34,328,18,324,5,320,6,312,18,324,6,312,7,312,88,14,82,22,36,51,36,51,82,22,79,34,36,51,79,34,36,286,36,297,36,286,46,332,36,297,46,332,34,328,34,328,22,311,29,309,34,328,29,309,34,305,34,328,34,305,36,297,79,188,79,340,76,342,79,188,76,342,79,51,79,51,76,342,66,338,79,51,66,338,79,34,79,34,66,338,56,335,79,34,56,335,46,332,135,228,134,203,148,201,135,228,148,201,152,230,152,230,148,201,158,195,152,230,158,195,174,227,174,227,158,195,165,184,174,227,165,184,170,169,79,171,90,184,92,204,92,204,90,184,101,193,92,204,101,193,106,216,106,216,101,193,112,199,106,216,112,199,120,224,120,224,112,199,123,202,120,224,123,202,135,228,135,228,123,202,134,203,79,51,79,171,79,188,79,188,79,171,92,204,168,22,162,14,243,0,243,0,162,14,152,10,243,0,152,10,137,7,174,227,170,169,171,150,216,22,171,150,171,51,216,22,171,51,221,15,221,15,171,51,171,34,221,15,171,34,243,0,243,0,171,34,168,22,214,51,214,151,211,179,214,51,211,179,204,201,214,51,204,201,214,34,230,10,221,15,243,0,230,10,243,0,243,7,171,150,216,22,174,227,174,227,216,22,214,34,174,227,214,34,191,217,191,217,214,34,204,201,113,0,113,7,98,10,113,0,98,10,88,14,113,0,88,14,36,33,113,0,36,33,33,22,113,0,4,7,4,0,36,33,88,14,36,51,36,286,79,34,46,332,243,0,137,7,137,0,6,312,5,320,5,311, 90,316,89,324,85,331,80,337,73,340,65,342,56,340,49,336,44,331,40,324,39,316,40,308,44,301,49,295,56,292,64,291,73,292,80,295,85,301,89,308,90,316,16383,16383,127,0,127,7,110,9,99,14,93,21,90,34,89,52,89,228,88,230,10,203,10,195,20,197,31,197,38,196,42,193,45,187,47,178,47,33,43,20,37,13,25,9,8,7,8,0, 39,316,40,308,40,324,40,324,40,308,44,301,40,324,44,301,44,331,44,331,44,301,49,295,44,331,49,295,49,336,49,336,49,295,56,292,49,336,56,292,56,340,56,340,56,292,64,291,56,340,64,291,65,342,65,342,64,291,73,292,65,342,73,292,73,340,73,340,73,292,80,295,73,340,80,295,80,337,80,337,80,295,85,301,80,337,85,301,85,331,85,331,85,301,89,308,85,331,89,308,89,324,89,324,89,308,90,316,43,20,37,13,127,0,127,0,37,13,25,9,127,0,25,9,8,7,20,197,24,197,88,230,88,230,24,197,28,197,88,230,28,197,31,197,31,197,38,196,88,230,88,230,38,196,42,193,88,230,42,193,45,187,43,20,127,0,47,33,47,33,127,0,99,14,47,33,99,14,47,52,47,52,99,14,93,21,47,52,93,21,47,166,47,178,47,166,88,230,47,178,88,230,45,187,15,196,20,197,88,230,15,196,88,230,10,203,15,196,10,203,10,195,89,52,89,228,88,230,89,52,88,230,47,166,89,52,47,166,90,34,110,9,99,14,127,0,110,9,127,0,127,7,127,0,8,7,8,0,47,166,93,21,90,34, 97,316,96,324,92,331,86,337,79,340,71,342,63,340,56,336,51,331,47,324,46,316,47,308,51,301,56,295,63,292,71,291,79,292,87,295,92,301,96,308,97,316,16383,16383,97,228,94,230,77,224,62,218,48,213,33,208,16,203,16,195,18,195,23,196,27,197,39,197,45,196,49,193,52,187,54,178,55,167,55,-21,54,-41,54,-56,52,-67,50,-76,47,-82,45,-85,39,-89,35,-91,26,-91,18,-87,14,-83,4,-71,0,-66,-4,-63,-9,-61,-14,-61,-20,-62,-26,-65,-30,-69,-33,-74,-34,-80,-32,-90,-26,-97,-16,-103,-3,-107,12,-108,42,-103,65,-90,83,-68,93,-38,97,0, 86,337,87,295,92,331,92,331,87,295,92,301,92,331,92,301,96,324,96,324,92,301,96,308,96,324,96,308,97,316,46,316,47,308,47,324,47,324,47,308,51,301,47,324,51,301,51,331,51,331,51,301,56,295,51,331,56,295,56,336,56,336,56,295,63,292,56,336,63,292,63,340,63,340,63,292,71,291,63,340,71,291,71,342,71,342,71,291,79,292,71,342,79,292,79,340,79,340,79,292,87,295,79,340,87,295,86,337,18,195,23,196,33,208,18,195,33,208,16,203,18,195,16,203,16,195,42,-87,39,-89,42,-103,42,-103,39,-89,35,-91,42,-103,35,-91,31,-91,31,-91,26,-91,42,-103,42,-103,26,-91,22,-89,42,-103,22,-89,18,-87,52,187,62,218,49,193,49,193,62,218,48,213,49,193,48,213,45,196,45,196,48,213,39,197,35,197,39,197,48,213,35,197,48,213,33,208,54,-56,52,-67,65,-90,65,-90,52,-67,50,-76,65,-90,50,-76,47,-82,47,-82,45,-85,65,-90,65,-90,45,-85,42,-87,65,-90,42,-87,42,-103,93,-38,94,230,83,-68,83,-68,94,230,77,224,83,-68,77,224,65,-90,65,-90,77,224,62,218,65,-90,62,218,55,167,55,167,62,218,54,178,33,208,23,196,27,197,33,208,27,197,32,197,33,208,32,197,35,197,97,0,97,228,94,230,97,0,94,230,93,-38,65,-90,55,167,55,-21,65,-90,55,-21,54,-41,65,-90,54,-41,54,-56,12,-108,42,-103,18,-87,12,-108,18,-87,14,-83,12,-108,14,-83,9,-77,12,-108,9,-77,4,-71,12,-108,4,-71,0,-66,12,-108,0,-66,-3,-107,-3,-107,0,-66,-4,-63,-3,-107,-4,-63,-9,-61,-3,-107,-9,-61,-14,-61,-3,-107,-14,-61,-16,-103,-20,-62,-26,-65,-26,-97,-20,-62,-26,-97,-16,-103,-20,-62,-16,-103,-14,-61,-30,-69,-33,-74,-32,-90,-30,-69,-32,-90,-26,-97,-30,-69,-26,-97,-26,-65,-32,-90,-33,-74,-34,-80,62,218,52,187,54,178, 252,0,252,7,240,9,228,13,217,20,206,30,194,44,118,141,132,155,164,183,188,201,206,212,222,217,240,218,240,225,138,225,138,218,148,218,155,217,160,215,162,212,163,209,161,203,155,195,151,191,83,131,83,340,81,342,70,338,48,332,35,328,18,324,3,320,3,311,7,312,17,312,20,313,28,312,34,309,38,303,40,294,41,282,41,41,40,28,38,20,32,14,21,11,3,7,3,0,121,0,121,7,110,8,100,9,92,12,87,17,84,24,83,33,83,126,158,26,160,24,162,21,163,19,163,17,164,15,163,13,162,10,153,7,143,7,143,0, 38,20,32,14,121,0,121,0,32,14,21,11,121,0,21,11,3,7,10,312,14,312,18,324,18,324,14,312,17,312,18,324,17,312,20,313,20,313,28,312,35,328,35,328,28,312,34,309,35,328,34,309,38,303,7,312,10,312,18,324,7,312,18,324,3,320,7,312,3,320,3,311,194,44,118,141,158,26,158,26,118,141,83,131,158,26,83,131,83,126,84,24,83,33,48,332,84,24,48,332,41,282,41,282,48,332,40,294,48,332,35,328,38,303,48,332,38,303,40,294,35,328,18,324,20,313,83,33,83,340,81,342,83,33,81,342,70,338,83,33,70,338,59,335,83,33,59,335,48,332,151,191,118,141,132,155,151,191,132,155,164,183,151,191,83,131,118,141,161,203,158,199,164,183,164,183,158,199,155,195,164,183,155,195,151,191,240,225,138,225,148,218,240,225,148,218,155,217,240,225,155,217,160,215,240,225,160,215,162,212,240,225,162,212,163,209,240,225,163,209,206,212,240,225,206,212,222,217,240,225,222,217,240,218,163,209,164,183,188,201,163,209,188,201,206,212,164,183,163,209,162,206,164,183,162,206,161,203,162,10,159,9,252,0,252,0,159,9,156,8,252,0,156,8,153,7,164,15,252,0,228,13,164,15,228,13,217,20,164,15,217,20,206,30,164,15,206,30,194,44,164,15,194,44,163,17,194,44,158,26,160,24,194,44,160,24,162,21,194,44,162,21,163,19,194,44,163,19,163,17,240,9,228,13,252,0,240,9,252,0,252,7,163,13,162,10,252,0,163,13,252,0,164,15,143,7,143,0,252,0,143,7,252,0,153,7,121,0,121,7,110,8,121,0,110,8,100,9,121,0,100,9,92,12,121,0,92,12,40,28,121,0,40,28,38,20,92,12,87,17,41,41,41,41,87,17,84,24,41,41,84,24,41,282,121,0,3,7,3,0,40,28,92,12,41,41,148,218,138,225,138,218, 128,0,128,7,112,9,101,13,95,20,92,29,91,44,91,339,89,342,74,337,59,333,45,329,28,324,9,320,9,311,14,312,25,312,28,313,36,311,42,308,46,302,48,293,49,281,49,46,48,32,45,21,38,14,27,10,11,7,11,0, 45,21,38,14,128,0,128,0,38,14,27,10,128,0,27,10,11,7,18,312,22,312,28,324,28,324,22,312,25,312,28,324,25,312,28,313,28,313,36,311,28,324,28,324,36,311,45,329,28,324,9,320,14,312,28,324,14,312,18,312,36,311,42,308,45,329,45,329,42,308,46,302,45,329,46,302,59,333,59,333,46,302,48,293,59,333,48,293,49,281,92,29,49,281,49,46,92,29,49,46,95,20,95,20,49,46,101,13,91,44,91,339,89,342,91,44,89,342,74,337,91,44,74,337,59,333,91,44,59,333,92,29,128,0,128,7,112,9,128,0,112,9,101,13,128,0,101,13,48,32,128,0,48,32,45,21,14,312,9,320,9,311,128,0,11,7,11,0,48,32,101,13,49,46,49,281,92,29,59,333, 387,0,387,7,374,8,366,10,360,13,356,19,354,27,353,39,353,140,351,172,344,197,333,215,317,226,295,230,278,228,262,224,246,215,230,204,214,188,207,203,199,215,188,223,176,228,161,230,147,229,133,226,119,220,103,208,84,191,83,191,83,228,79,230,51,220,25,212,9,208,9,199,13,200,16,200,19,201,26,201,32,200,37,196,41,190,42,181,43,168,43,44,42,29,39,19,32,12,22,9,8,7,8,0,119,0,119,7,105,8,96,11,89,16,86,24,85,35,85,175,99,189,109,195,121,200,133,203,145,204,156,202,165,195,172,183,176,168,177,148,177,43,176,28,173,18,167,12,157,9,143,7,143,0,255,0,255,7,240,9,230,12,223,19,220,31,219,47,219,174,228,185,237,194,248,200,259,203,272,204,287,202,298,196,305,185,310,169,311,148,311,45,310,30,307,20,302,14,293,10,278,7,278,0, 16,200,19,201,25,212,25,212,19,201,22,201,25,212,22,201,26,201,26,201,32,200,38,216,38,216,32,200,37,196,38,216,37,196,41,190,25,212,9,208,13,200,25,212,13,200,16,200,38,216,41,190,51,220,51,220,41,190,42,181,51,220,42,181,43,168,86,24,43,168,43,44,86,24,43,44,89,16,89,16,43,44,96,11,38,216,25,212,26,201,83,228,79,230,83,191,83,191,79,230,85,35,83,191,85,35,84,191,84,191,85,35,85,174,84,191,85,174,85,175,173,18,167,12,255,0,255,0,167,12,157,9,255,0,157,9,143,7,161,230,147,229,156,202,156,202,147,229,145,204,133,203,145,204,133,226,133,203,133,226,121,200,121,200,133,226,119,220,121,200,119,220,109,195,109,195,119,220,103,208,109,195,103,208,99,189,99,189,103,208,92,182,103,208,84,191,85,175,103,208,85,175,86,176,103,208,86,176,88,178,103,208,88,178,90,180,103,208,90,180,92,182,85,35,79,230,65,225,85,35,65,225,86,24,147,229,133,226,145,204,173,18,255,0,176,28,176,28,255,0,230,12,176,28,230,12,177,43,177,43,230,12,223,19,177,43,223,19,177,148,176,228,177,148,188,223,176,228,161,230,165,195,176,228,165,195,172,183,176,228,172,183,176,168,176,228,176,168,177,148,207,203,199,215,220,31,207,203,220,31,219,47,207,203,219,47,214,188,219,174,228,185,230,204,230,204,228,185,237,194,230,204,237,194,246,215,246,215,237,194,248,200,246,215,248,200,262,224,262,224,248,200,259,203,262,224,259,203,272,204,272,204,287,202,278,228,278,228,287,202,295,230,219,47,219,174,214,188,214,188,219,174,230,204,278,228,262,224,272,204,307,20,302,14,387,0,387,0,302,14,293,10,387,0,293,10,278,7,298,196,305,185,317,226,317,226,305,185,310,169,317,226,310,169,311,148,356,19,311,148,311,45,356,19,311,45,360,13,360,13,311,45,310,30,360,13,310,30,366,10,366,10,310,30,387,0,366,10,387,0,374,8,374,8,387,0,387,7,295,230,287,202,298,196,295,230,298,196,317,226,353,39,353,140,351,172,353,39,351,172,344,197,353,39,344,197,333,215,353,39,333,215,354,27,354,27,333,215,317,226,354,27,317,226,311,148,354,27,311,148,356,19,240,9,230,12,255,0,240,9,255,0,255,7,220,31,199,215,188,223,220,31,188,223,177,148,220,31,177,148,223,19,119,0,119,7,105,8,119,0,105,8,96,11,119,0,96,11,42,29,119,0,42,29,39,19,119,0,39,19,32,12,119,0,32,12,22,9,119,0,22,9,8,7,119,0,8,7,8,0,51,220,43,168,86,24,51,220,86,24,65,225,13,200,9,208,9,199,42,29,96,11,43,44,255,0,143,7,143,0,387,0,278,7,278,0,307,20,387,0,310,30,161,230,156,202,165,195, 243,0,243,7,230,9,221,13,216,19,213,29,212,42,212,153,210,180,202,201,190,217,174,227,153,230,139,229,125,224,111,216,96,205,81,190,80,190,80,228,76,230,50,220,37,216,23,212,8,208,8,199,10,200,13,200,16,201,22,201,30,200,35,197,38,191,40,181,40,47,39,32,37,21,31,14,22,9,9,7,9,0,114,0,114,7,101,9,92,13,86,18,83,26,82,36,82,174,95,186,105,194,115,199,124,202,133,203,147,201,157,195,164,185,169,171,170,152,170,52,169,35,166,23,161,15,152,10,139,7,138,0, 37,21,31,14,114,0,114,0,31,14,22,9,114,0,22,9,9,7,13,200,16,201,23,212,23,212,16,201,19,201,23,212,19,201,22,201,22,201,30,200,23,212,23,212,30,200,37,216,23,212,8,208,10,200,23,212,10,200,13,200,30,200,35,197,37,216,37,216,35,197,38,191,37,216,38,191,50,220,50,220,38,191,40,181,50,220,40,181,40,169,83,26,40,169,40,47,83,26,40,47,86,18,86,18,40,47,92,13,80,228,76,230,80,190,80,190,76,230,82,36,80,190,82,36,81,190,81,190,82,36,82,174,81,190,82,174,96,205,96,205,82,174,95,186,96,205,95,186,105,194,96,205,105,194,111,216,111,216,105,194,115,199,111,216,115,199,125,224,125,224,115,199,124,202,125,224,124,202,133,203,133,203,147,201,139,229,139,229,147,201,153,230,82,36,76,230,63,225,82,36,63,225,83,26,139,229,125,224,133,203,166,23,161,15,243,0,243,0,161,15,152,10,243,0,152,10,139,7,157,195,164,185,174,227,174,227,164,185,169,171,174,227,169,171,170,152,216,19,170,152,170,52,216,19,170,52,221,13,221,13,170,52,169,35,221,13,169,35,243,0,243,0,169,35,166,23,153,230,147,201,157,195,153,230,157,195,174,227,212,42,212,153,210,180,212,42,210,180,202,201,212,42,202,201,213,29,230,9,221,13,243,0,230,9,243,0,243,7,213,29,202,201,190,217,213,29,190,217,174,227,213,29,174,227,170,152,213,29,170,152,216,19,114,0,114,7,101,9,114,0,101,9,92,13,114,0,92,13,39,32,114,0,39,32,37,21,50,220,40,169,83,26,50,220,83,26,63,225,10,200,8,208,8,199,114,0,9,7,9,0,39,32,92,13,40,47,243,0,139,7,138,0, 235,116,230,154,215,186,191,210,162,225,127,230,90,225,58,209,35,185,20,153,15,114,20,75,35,42,58,17,88,1,123,-4,160,1,191,17,215,43,230,76,235,116,16383,16383,190,102,187,70,180,44,168,25,151,13,131,9,120,10,110,13,101,18,93,25,86,34,76,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,98,212,118,216,130,215,140,211,149,206,158,199,165,191,174,177,181,161,186,142,189,122,190,102, 64,91,58,17,69,70,69,70,58,17,88,1,69,70,88,1,76,51,76,51,88,1,86,34,93,25,86,34,88,1,93,25,88,1,123,-4,162,225,127,230,130,215,130,215,127,230,118,216,98,212,118,216,127,230,98,212,127,230,90,225,187,70,180,44,191,17,191,17,180,44,168,25,191,17,168,25,160,1,160,1,168,25,151,13,160,1,151,13,131,9,131,9,120,10,123,-4,123,-4,120,10,110,13,123,-4,110,13,101,18,140,211,149,206,162,225,162,225,149,206,158,199,162,225,158,199,165,191,165,191,174,177,191,210,191,210,174,177,181,161,191,210,181,161,186,142,230,154,215,186,215,43,230,154,215,43,230,76,230,154,230,76,235,116,187,70,191,17,190,102,190,102,191,17,191,210,191,210,191,17,215,43,191,210,215,43,215,186,191,210,186,142,189,122,191,210,189,122,190,102,191,210,162,225,165,191,131,9,123,-4,160,1,58,17,61,113,60,137,60,137,62,164,58,209,58,209,62,164,70,186,58,209,70,186,90,225,90,225,70,186,82,202,90,225,82,202,98,212,58,17,60,137,58,209,58,17,58,209,35,42,35,42,58,209,35,185,35,42,35,185,20,75,20,75,35,185,20,153,20,75,20,153,15,114,61,113,58,17,64,91,162,225,130,215,140,211,93,25,123,-4,101,18, 79,229,76,230,62,224,20,209,4,204,4,196,7,197,17,197,26,196,31,194,35,189,37,180,37,-78,34,-87,27,-93,17,-97,2,-99,2,-107,123,-107,123,-98,104,-97,92,-94,84,-88,80,-77,79,-61,79,17,90,8,99,2,108,-1,118,-3,130,-4,164,1,193,19,215,47,230,82,235,123,231,158,219,188,202,210,179,225,151,230,135,228,120,224,106,216,93,205,79,190,16383,16383,79,167,82,176,91,185,103,193,116,198,131,200,151,195,168,183,181,163,189,136,192,103,189,73,181,47,168,28,152,15,132,11,117,13,103,18,91,26,82,35,79,44, 34,-87,27,-93,123,-107,123,-107,27,-93,17,-97,123,-107,17,-97,2,-99,9,197,12,197,20,209,20,209,12,197,14,197,20,209,14,197,17,197,17,197,26,196,20,209,20,209,26,196,34,214,20,209,4,204,7,197,20,209,7,197,9,197,82,35,79,44,90,8,90,8,79,44,79,17,80,-77,79,-61,48,219,80,-77,48,219,37,169,37,169,48,219,37,180,26,196,31,194,34,214,34,214,31,194,35,189,34,214,35,189,48,219,48,219,35,189,37,180,79,190,79,229,76,230,79,190,76,230,79,-61,79,190,79,-61,79,167,79,190,79,167,82,176,79,190,82,176,93,205,235,123,231,158,230,82,230,82,231,158,219,188,230,82,219,188,215,47,215,47,219,188,202,210,215,47,202,210,193,19,193,19,202,210,192,103,193,19,192,103,189,73,193,19,189,73,181,47,202,210,179,225,181,163,202,210,181,163,189,136,202,210,189,136,192,103,135,228,131,200,151,195,135,228,151,195,151,230,151,230,151,195,168,183,151,230,168,183,179,225,179,225,168,183,181,163,108,-1,118,-3,117,13,117,13,118,-3,132,11,152,15,132,11,164,1,152,15,164,1,168,28,168,28,164,1,193,19,168,28,193,19,181,47,132,11,118,-3,130,-4,132,11,130,-4,164,1,123,-107,123,-98,104,-97,123,-107,104,-97,92,-94,123,-107,92,-94,37,-78,123,-107,37,-78,34,-87,62,224,48,219,79,-61,62,224,79,-61,76,230,92,-94,84,-88,37,-64,37,-64,84,-88,80,-77,37,-64,80,-77,37,169,82,176,91,185,93,205,93,205,91,185,103,193,93,205,103,193,106,216,106,216,103,193,116,198,106,216,116,198,120,224,120,224,116,198,131,200,120,224,131,200,135,228,82,35,90,8,91,26,91,26,90,8,99,2,91,26,99,2,103,18,103,18,99,2,108,-1,103,18,108,-1,117,13,7,197,4,204,4,196,123,-107,2,-99,2,-107,37,-78,92,-94,37,-64, 244,-107,244,-99,231,-97,222,-93,216,-88,213,-80,213,228,207,228,180,213,167,220,155,224,144,228,122,230,87,224,57,206,33,179,18,144,12,103,16,67,27,38,44,15,66,0,92,-4,109,-2,126,1,142,8,157,19,171,32,171,-61,169,-75,165,-86,157,-93,144,-97,126,-99,126,-107,16383,16383,171,64,170,57,170,52,168,47,167,44,165,41,149,31,140,28,130,26,112,26,96,30,89,34,83,39,74,50,66,64,60,81,56,100,55,121,58,153,67,179,81,199,100,211,124,215,141,214,154,208,163,198,169,184,171,166, 112,26,104,28,109,-2,109,-2,104,28,96,30,109,-2,96,30,92,-4,92,-4,96,30,89,34,92,-4,89,34,83,39,83,39,74,50,92,-4,92,-4,74,50,66,64,92,-4,66,64,66,0,66,0,66,64,60,81,66,0,60,81,56,100,109,-2,126,1,112,26,112,26,126,1,121,26,130,26,121,26,126,1,130,26,126,1,142,8,133,229,124,215,141,214,133,229,141,214,144,228,144,228,141,214,154,208,144,228,154,208,155,224,155,224,154,208,163,198,155,224,163,198,167,220,167,220,163,198,169,184,167,220,169,184,180,213,180,213,169,184,171,166,180,213,171,166,171,32,171,32,171,166,171,64,67,179,81,199,87,224,87,224,81,199,100,211,87,224,100,211,122,230,122,230,100,211,124,215,122,230,124,215,133,229,57,206,33,179,44,15,57,206,44,15,55,121,57,206,55,121,58,153,57,206,58,153,67,179,57,206,67,179,87,224,55,121,44,15,56,100,12,103,16,67,18,144,18,144,16,67,27,38,18,144,27,38,33,179,33,179,27,38,44,15,165,-86,157,-93,244,-107,244,-107,157,-93,144,-97,244,-107,144,-97,126,-99,170,52,168,47,171,32,171,32,168,47,167,44,171,32,167,44,165,41,165,41,157,36,171,32,171,32,157,36,157,19,170,57,170,52,171,32,170,57,171,32,171,64,149,31,140,28,142,8,149,31,142,8,157,19,149,31,157,19,157,36,213,-69,213,228,207,228,213,-69,207,228,180,213,213,-69,180,213,213,-80,244,-107,244,-99,231,-97,244,-107,231,-97,222,-93,244,-107,222,-93,169,-75,244,-107,169,-75,165,-86,171,32,216,-88,213,-80,171,32,213,-80,180,213,171,-61,169,-75,222,-93,171,-61,222,-93,216,-88,171,-61,216,-88,171,32,244,-107,126,-99,126,-107,56,100,44,15,66,0,130,26,142,8,140,28, 80,229,78,230,62,224,48,219,35,214,20,209,3,203,3,195,7,196,11,196,14,197,21,197,28,196,32,193,36,187,37,179,38,167,38,42,37,29,35,21,29,15,18,11,2,7,2,0,123,0,123,7,105,9,93,13,85,20,81,30,80,45,80,157,82,168,88,179,97,189,106,196,115,199,119,197,122,196,125,194,128,191,133,187,137,184,141,182,144,181,148,181,155,182,160,185,164,190,167,196,167,204,166,213,163,220,157,225,149,229,140,230,128,228,117,224,106,215,94,202,80,183, 11,196,14,197,20,209,20,209,14,197,18,197,20,209,18,197,21,197,21,197,28,196,35,214,35,214,28,196,32,193,35,214,32,193,36,187,20,209,3,203,7,196,20,209,7,196,11,196,80,183,80,229,78,230,80,183,78,230,80,45,80,45,78,230,62,224,80,45,62,224,81,30,81,30,62,224,48,219,81,30,48,219,38,167,38,167,48,219,37,179,48,219,35,214,36,187,48,219,36,187,37,179,35,214,20,209,21,197,122,196,128,228,119,197,119,197,128,228,117,224,119,197,117,224,117,198,117,198,117,224,115,199,106,196,115,199,117,224,106,196,117,224,106,215,137,184,140,230,133,187,133,187,140,230,128,228,133,187,128,228,128,191,128,191,128,228,125,194,144,181,148,181,149,229,149,229,148,181,155,182,149,229,155,182,157,225,157,225,155,182,160,185,157,225,160,185,163,220,163,220,160,185,164,190,163,220,164,190,166,213,166,213,164,190,167,196,166,213,167,196,167,204,141,182,144,181,149,229,141,182,149,229,140,230,141,182,140,230,137,184,82,168,88,179,94,202,94,202,88,179,97,189,94,202,97,189,106,215,106,215,97,189,106,196,80,45,80,157,80,183,80,183,80,157,82,168,80,183,82,168,94,202,123,0,123,7,105,9,123,0,105,9,93,13,123,0,93,13,37,29,123,0,37,29,35,21,123,0,35,21,29,15,123,0,29,15,18,11,123,0,18,11,2,7,123,0,2,7,2,0,93,13,85,20,38,42,38,42,85,20,81,30,38,42,81,30,38,167,7,196,3,203,3,195,37,29,93,13,38,42,128,228,122,196,125,194, 78,151,71,156,64,163,60,170,57,178,56,185,58,197,63,207,71,214,82,217,94,219,110,217,123,210,134,198,143,181,151,157,158,157,156,225,150,225,145,220,140,220,137,221,134,221,131,223,122,226,115,228,109,229,94,229,72,227,53,219,38,207,29,190,26,168,28,153,35,138,47,123,63,109,85,95,113,80,129,68,134,60,138,52,139,43,137,31,132,21,123,13,112,8,98,6,79,9,63,17,51,31,41,50,34,76,26,76,26,-1,32,-1,34,0,36,2,39,3,41,4,48,4,52,3,56,3,61,1,68,0,75,-2,82,-3,90,-4,104,-4,126,-1,145,7,160,21,170,38,174,57,173,73,168,86,159,97,147,108,130,119, 36,2,39,3,41,50,41,50,39,3,41,4,41,50,41,4,45,4,45,4,48,4,51,31,51,31,48,4,52,3,51,31,52,3,63,17,63,17,52,3,56,3,63,17,56,3,61,1,36,2,41,50,34,0,34,0,41,50,34,76,34,0,34,76,32,-1,32,-1,34,76,26,76,32,-1,26,76,26,-1,72,227,53,219,58,197,58,197,53,219,56,185,63,109,56,185,53,219,63,109,53,219,47,123,47,123,53,219,38,207,47,123,38,207,35,138,35,138,38,207,29,190,35,138,29,190,28,153,28,153,29,190,26,168,102,229,94,229,110,217,110,217,94,229,94,219,82,217,94,219,94,229,82,217,94,229,72,227,137,221,134,221,134,198,134,198,134,221,131,223,134,198,131,223,128,224,128,224,122,226,123,210,123,210,122,226,115,228,123,210,115,228,110,217,110,217,115,228,109,229,110,217,109,229,102,229,148,223,146,221,151,157,151,157,146,221,145,220,151,157,145,220,143,181,143,181,145,220,143,220,143,181,143,220,142,220,142,220,140,220,143,181,143,181,140,220,137,221,143,181,137,221,134,198,151,157,158,157,156,225,151,157,156,225,150,225,151,157,150,225,148,223,128,224,123,210,134,198,174,57,173,73,170,38,170,38,173,73,168,86,170,38,168,86,160,21,160,21,168,86,159,97,160,21,159,97,147,108,123,13,126,-1,132,21,132,21,126,-1,145,7,132,21,145,7,137,31,137,31,145,7,139,43,147,108,139,43,145,7,147,108,145,7,160,21,121,74,129,68,130,119,130,119,129,68,134,60,130,119,134,60,147,108,147,108,134,60,138,52,147,108,138,52,139,43,130,119,78,151,85,95,130,119,85,95,113,80,130,119,113,80,121,74,78,151,71,156,85,95,85,95,71,156,64,163,85,95,64,163,63,109,63,109,64,163,60,170,63,109,60,170,57,178,98,6,104,-4,112,8,112,8,104,-4,126,-1,112,8,126,-1,123,13,72,227,58,197,63,207,72,227,63,207,71,214,72,227,71,214,82,217,98,6,79,9,82,-3,98,6,82,-3,90,-4,98,6,90,-4,97,-4,98,6,97,-4,104,-4,79,9,63,17,68,0,79,9,68,0,75,-2,79,9,75,-2,82,-3,68,0,63,17,61,1,51,31,41,50,45,4,56,185,63,109,57,178, 133,39,127,32,121,27,115,24,109,22,103,21,93,23,86,28,81,36,78,49,77,66,77,209,127,209,127,225,77,225,77,286,76,287,76,289,75,289,74,290,72,287,69,284,65,278,64,276,53,260,42,247,32,236,23,228,15,222,12,220,8,216,7,214,7,210,8,210,8,209,35,209,35,59,37,36,42,18,51,5,64,-1,79,-4,93,-3,106,1,118,8,129,19,140,33, 42,247,32,236,35,209,35,209,32,236,23,228,35,209,23,228,15,222,53,260,42,247,42,18,53,260,42,18,51,5,53,260,51,5,64,-1,53,260,64,-1,64,276,37,36,42,18,42,247,37,36,42,247,35,209,37,36,35,209,35,59,7,210,8,210,8,216,8,216,8,210,8,209,8,216,8,209,10,218,10,218,8,209,35,209,10,218,35,209,12,220,12,220,35,209,15,222,7,214,7,213,7,212,7,214,7,212,7,211,7,214,7,211,7,210,7,214,7,210,8,216,69,284,79,-4,77,66,77,225,77,209,127,209,77,225,127,209,127,225,77,66,77,283,77,286,77,66,77,286,76,287,77,66,76,287,76,289,77,66,76,289,75,289,77,66,75,289,74,290,77,66,74,290,72,287,77,66,72,287,69,284,86,28,93,-3,93,23,93,23,93,-3,103,21,109,22,103,21,106,1,109,22,106,1,118,8,81,36,78,49,79,-4,81,36,79,-4,93,-3,81,36,93,-3,86,28,79,-4,69,284,67,281,79,-4,67,281,65,278,79,-4,65,278,64,276,79,-4,64,276,64,-1,129,19,140,33,133,39,129,19,133,39,127,32,129,19,127,32,121,27,129,19,121,27,118,8,115,24,109,22,118,8,115,24,118,8,121,27,103,21,93,-3,106,1,77,66,79,-4,78,49, 240,25,237,25,225,26,217,29,212,34,209,42,209,225,129,225,129,217,145,215,155,212,162,206,165,197,166,184,166,59,164,53,162,48,159,43,147,34,139,29,130,26,121,25,113,24,102,26,92,31,84,40,79,51,78,64,78,225,4,225,4,218,17,216,26,213,32,207,35,197,36,185,36,59,38,38,46,20,58,6,75,-1,97,-4,109,-3,123,0,138,8,153,21,168,38,169,38,169,-2,171,-3,186,1,199,6,225,14,240,18, 78,225,4,225,17,216,78,225,17,216,26,213,78,225,26,213,32,207,78,225,32,207,35,197,78,225,35,197,36,185,78,225,36,185,38,38,78,225,38,38,46,20,78,225,46,20,58,6,78,225,58,6,75,-1,78,225,75,-1,78,64,164,53,162,48,168,38,168,38,162,48,159,43,168,38,159,43,155,40,155,40,147,34,153,21,153,21,147,34,139,29,153,21,139,29,138,8,138,8,139,29,130,26,138,8,130,26,123,0,123,0,130,26,121,25,123,0,121,25,113,24,113,24,102,26,109,-3,109,-3,102,26,97,-4,97,-4,102,26,92,31,97,-4,92,31,84,40,97,-4,84,40,79,51,97,-4,79,51,75,-1,78,64,75,-1,79,51,113,24,109,-3,123,0,166,184,168,38,209,225,209,225,168,38,169,38,209,225,169,38,171,-3,171,-3,169,38,169,-2,168,38,166,184,166,69,168,38,166,69,166,59,168,38,166,59,164,53,155,40,153,21,168,38,225,26,217,29,225,14,225,14,217,29,212,34,225,14,212,34,212,10,212,10,212,34,209,42,212,10,209,42,199,6,199,6,209,42,209,54,199,6,209,54,209,225,209,225,171,-3,186,1,209,225,186,1,199,6,209,225,129,225,145,215,209,225,145,215,155,212,209,225,155,212,162,206,209,225,162,206,165,197,209,225,165,197,166,184,237,25,225,26,225,14,237,25,225,14,240,18,237,25,240,18,240,25,38,38,36,185,36,59,145,215,129,225,129,217,17,216,4,225,4,218, 238,225,169,225,169,218,178,216,184,214,189,211,192,207,193,201,192,198,192,195,191,192,191,189,190,186,140,57,89,185,87,190,86,194,85,197,84,201,84,204,85,209,88,212,92,215,99,216,108,218,108,225,9,225,9,218,19,216,27,212,35,202,44,186,55,160,115,17,116,14,118,10,118,8,119,6,121,1,123,-1,125,-4,126,-6,128,-6,130,-5,132,-3,135,1,138,8,142,18,206,179,213,195,219,206,224,213,231,216,238,218, 87,190,86,194,115,17,115,17,86,194,85,197,115,17,85,197,55,160,55,160,85,197,84,201,55,160,84,201,84,204,84,204,85,209,55,160,108,225,9,225,19,216,108,225,19,216,27,212,108,225,27,212,35,202,108,225,35,202,44,186,108,225,44,186,88,212,108,225,88,212,92,215,108,225,92,215,99,216,108,225,99,216,108,218,85,209,88,212,44,186,85,209,44,186,55,160,140,57,89,185,115,17,140,57,115,17,116,14,140,57,116,14,117,12,140,57,117,12,118,10,140,57,118,10,118,8,140,57,118,8,119,6,140,57,119,6,121,1,140,57,121,1,123,-1,140,57,123,-1,125,-4,140,57,125,-4,126,-6,140,57,126,-6,128,-6,140,57,128,-6,130,-5,140,57,130,-5,132,-3,140,57,132,-3,135,1,140,57,135,1,138,8,140,57,138,8,142,18,140,57,142,18,190,186,206,179,190,186,142,18,238,225,169,225,178,216,238,225,178,216,184,214,238,225,184,214,189,211,238,225,189,211,192,207,238,225,192,207,193,201,238,225,193,201,224,213,238,225,224,213,231,216,238,225,231,216,238,218,206,179,213,195,193,201,206,179,193,201,192,198,206,179,192,198,192,195,206,179,192,195,191,192,206,179,191,192,191,189,206,179,191,189,190,186,219,206,224,213,193,201,219,206,193,201,213,195,178,216,169,225,169,218,87,190,115,17,89,185,19,216,9,225,9,218, 347,225,286,225,286,218,294,215,301,213,305,210,307,207,307,197,306,191,302,177,299,169,254,58,209,178,206,185,204,195,204,205,207,210,212,213,221,215,233,218,233,225,131,225,131,218,141,216,148,212,155,206,160,196,166,183,175,155,130,55,80,186,79,189,79,192,78,195,78,206,81,211,85,214,91,216,100,218,100,225,11,225,11,218,17,216,22,214,26,208,31,199,37,186,104,15,108,7,111,0,113,-3,116,-5,118,-6,121,-3,123,0,126,5,130,12,186,132,232,15,235,5,238,0,241,-6,246,-6,250,0,253,7,257,17,326,190,331,200,334,207,338,212,342,215,347,218, 22,214,26,208,100,225,100,225,26,208,31,199,100,225,31,199,37,186,37,186,104,15,78,195,78,195,104,15,79,192,37,186,78,198,78,201,78,201,78,206,37,186,37,186,78,206,81,211,37,186,81,211,85,214,100,225,37,186,85,214,100,225,85,214,91,216,100,225,91,216,100,218,17,216,22,214,100,225,17,216,100,225,11,225,17,216,11,225,11,218,186,132,204,200,204,205,186,132,204,205,175,155,175,155,204,205,166,183,160,196,166,183,207,210,160,196,207,210,212,213,233,225,131,225,141,216,233,225,141,216,148,212,233,225,148,212,155,206,233,225,155,206,160,196,233,225,160,196,212,213,233,225,212,213,221,215,233,225,221,215,233,218,207,210,166,183,204,205,254,58,212,170,232,15,254,58,232,15,235,5,254,58,235,5,238,0,254,58,238,0,240,-4,254,58,240,-4,241,-6,254,58,241,-6,243,-6,254,58,243,-6,246,-6,254,58,246,-6,248,-3,254,58,248,-3,250,0,254,58,250,0,253,7,254,58,253,7,257,17,254,58,257,17,299,169,232,15,212,170,209,178,232,15,209,178,206,185,232,15,206,185,205,190,232,15,205,190,204,195,232,15,204,195,186,132,326,190,299,169,257,17,347,225,286,225,294,215,347,225,294,215,301,213,347,225,301,213,305,210,347,225,305,210,307,207,347,225,307,207,307,203,347,225,307,203,334,207,347,225,334,207,338,212,347,225,338,212,342,215,347,225,342,215,347,218,326,190,331,200,307,203,326,190,307,203,307,197,326,190,307,197,306,191,326,190,306,191,304,184,326,190,304,184,302,177,326,190,302,177,299,169,123,0,126,5,130,55,130,55,126,5,130,12,130,55,130,12,175,155,175,155,130,12,186,132,130,55,80,186,104,15,130,55,104,15,108,7,130,55,108,7,111,0,130,55,111,0,113,-3,130,55,113,-3,116,-5,130,55,116,-5,118,-6,130,55,118,-6,119,-5,130,55,119,-5,121,-3,130,55,121,-3,123,0,79,189,79,192,104,15,79,189,104,15,80,186,37,186,78,195,78,198,294,215,286,225,286,218,334,207,307,203,331,200,186,132,204,195,204,200,141,216,131,225,131,218, 239,0,239,7,230,8,222,12,215,18,207,26,199,37,134,136,176,195,182,203,190,209,198,214,207,216,217,218,217,225,137,225,137,218,145,217,151,215,155,213,157,210,157,202,154,197,150,191,145,184,136,169,133,165,130,160,124,152,123,154,121,156,119,160,117,162,109,174,103,185,98,194,95,201,94,206,95,210,97,213,101,216,107,217,116,218,116,225,12,225,12,218,17,218,25,217,32,214,39,208,47,200,55,187,55,188,102,116,45,33,37,22,31,15,24,11,17,9,8,7,8,0,81,0,81,7,73,8,68,9,64,11,62,13,61,17,61,19,62,22,64,26,67,31,71,37,110,99,156,28,157,27,159,23,159,15,157,12,153,9,147,8,139,7,139,0, 31,15,24,11,81,0,81,0,24,11,17,9,81,0,17,9,8,7,32,214,39,208,116,225,116,225,39,208,47,200,116,225,47,200,55,188,55,187,55,188,102,116,55,187,102,116,94,206,94,206,95,210,55,187,55,187,95,210,97,213,55,187,97,213,116,225,116,225,97,213,101,216,116,225,101,216,107,217,31,15,81,0,37,22,37,22,81,0,64,11,37,22,64,11,45,33,45,33,64,11,62,13,45,33,62,13,61,17,61,17,61,19,45,33,45,33,61,19,62,22,45,33,62,22,102,116,102,116,62,22,64,26,102,116,64,26,67,31,102,116,67,31,71,37,71,37,110,99,102,116,102,116,110,99,103,185,102,116,103,185,98,194,107,217,116,218,116,225,116,225,12,225,17,218,116,225,17,218,25,217,116,225,25,217,32,214,95,201,94,206,102,116,95,201,102,116,98,194,121,156,120,158,156,28,156,28,120,158,119,160,156,28,119,160,117,162,117,162,109,174,110,99,110,99,109,174,103,185,222,12,215,18,159,20,159,20,215,18,207,26,159,20,207,26,199,37,199,37,134,136,156,28,156,28,134,136,127,156,156,28,127,156,124,152,124,152,123,154,156,28,156,28,123,154,121,156,217,225,137,225,145,217,217,225,145,217,151,215,217,225,151,215,155,213,217,225,155,213,157,210,217,225,157,210,157,206,217,225,157,206,190,209,217,225,190,209,198,214,217,225,198,214,207,216,217,225,207,216,217,218,176,195,182,203,157,206,176,195,157,206,157,202,176,195,157,202,154,197,176,195,154,197,150,191,176,195,150,191,145,184,176,195,145,184,139,174,176,195,139,174,136,169,176,195,136,169,134,136,134,136,136,169,133,165,134,136,133,165,130,160,134,136,130,160,127,156,157,12,153,9,239,0,239,0,153,9,147,8,239,0,147,8,139,7,158,25,159,23,199,37,199,37,159,23,159,21,199,37,159,21,159,20,159,20,159,15,239,0,239,0,159,15,157,12,199,37,156,28,157,27,199,37,157,27,158,25,117,162,110,99,156,28,239,0,239,7,230,8,239,0,230,8,222,12,239,0,222,12,159,20,81,0,81,7,73,8,81,0,73,8,68,9,81,0,68,9,64,11,81,0,8,7,8,0,239,0,139,7,139,0,145,217,137,225,137,218,190,209,157,206,182,203,17,218,12,225,12,218,116,225,55,188,55,187, 238,225,171,225,171,218,179,217,186,216,190,213,193,210,194,205,194,202,193,201,193,198,192,196,143,59,88,184,82,196,81,201,81,204,82,209,85,212,90,215,98,217,109,218,109,225,7,225,7,218,14,217,21,214,26,211,30,206,33,200,99,60,105,47,111,35,116,24,121,9,119,2,116,-8,112,-21,106,-34,100,-44,96,-51,85,-62,80,-65,75,-66,71,-66,69,-65,66,-64,62,-63,63,-63,57,-60,52,-58,42,-56,36,-56,30,-57,24,-60,19,-65,16,-72,15,-79,17,-88,21,-96,28,-102,38,-106,50,-108,71,-105,90,-94,106,-76,122,-49,137,-11,213,192,217,202,221,208,226,213,231,216,238,218, 90,-57,85,-62,90,-94,90,-94,85,-62,80,-65,90,-94,80,-65,75,-66,75,-66,73,-66,90,-94,90,-94,73,-66,71,-105,90,-57,106,-76,96,-51,96,-51,106,-76,100,-44,106,-34,100,-44,106,-76,106,-34,106,-76,122,-49,143,59,88,184,99,60,143,59,99,60,105,47,143,59,105,47,111,35,143,59,111,35,116,24,143,59,116,24,119,15,143,59,119,15,121,9,143,59,121,9,122,-49,143,59,122,-49,137,-11,143,59,137,-11,213,192,143,59,213,192,192,196,122,-49,121,9,119,2,99,60,88,184,86,188,99,60,86,188,84,192,99,60,84,192,82,196,99,60,82,196,81,201,99,60,81,201,33,200,33,200,81,201,81,204,81,204,82,209,33,200,33,200,82,209,85,212,33,200,85,212,109,225,109,225,85,212,90,215,109,225,90,215,98,217,194,202,193,201,213,192,213,192,193,201,193,198,213,192,193,198,192,196,238,225,171,225,179,217,238,225,179,217,186,216,238,225,186,216,190,213,238,225,190,213,193,210,238,225,193,210,194,205,238,225,194,205,226,213,238,225,226,213,231,216,238,225,231,216,238,218,194,205,213,192,217,202,194,205,217,202,221,208,194,205,221,208,226,213,194,204,194,202,213,192,194,204,213,192,194,205,122,-49,119,2,116,-8,122,-49,116,-8,112,-21,122,-49,112,-21,106,-34,71,-105,73,-66,71,-66,71,-105,71,-66,69,-65,71,-105,69,-65,66,-64,71,-105,66,-64,63,-63,71,-105,63,-63,57,-60,71,-105,57,-60,52,-58,71,-105,52,-58,50,-108,52,-58,47,-57,50,-108,50,-108,47,-57,42,-56,50,-108,42,-56,38,-106,38,-106,42,-56,36,-56,38,-106,36,-56,30,-57,38,-106,30,-57,28,-102,28,-102,30,-57,24,-60,28,-102,24,-60,21,-96,21,-96,24,-60,19,-65,21,-96,19,-65,17,-88,17,-88,19,-65,16,-72,17,-88,16,-72,15,-79,98,217,109,218,109,225,109,225,7,225,14,217,109,225,14,217,21,214,109,225,21,214,26,211,109,225,26,211,30,206,109,225,30,206,33,200,66,-64,62,-63,63,-63,14,217,7,225,7,218,90,-57,90,-94,106,-76,179,217,171,225,171,218, 209,68,200,70,197,57,195,47,193,40,190,34,186,28,181,24,173,20,163,17,149,16,133,15,67,15,201,218,201,225,28,225,26,166,36,166,39,184,44,197,51,205,63,209,79,210,147,210,13,7,13,0,201,0, 67,15,201,218,147,210,147,210,201,218,201,225,147,210,201,225,79,210,63,209,79,210,201,225,63,209,201,225,28,225,28,225,26,166,36,166,28,225,36,166,39,184,28,225,39,184,44,197,28,225,44,197,51,205,28,225,51,205,63,209,147,210,13,7,67,15,67,15,13,7,201,0,67,15,201,0,133,15,133,15,201,0,149,16,195,47,193,40,201,0,201,0,193,40,190,34,201,0,190,34,186,28,186,28,181,24,201,0,201,0,181,24,173,20,201,0,173,20,163,17,201,0,209,68,200,70,201,0,200,70,197,57,201,0,197,57,195,47,201,0,13,7,13,0,149,16,201,0,163,17, 175,-84,157,-78,144,-69,136,-58,131,-42,129,-22,129,60,128,82,124,98,115,110,102,118,83,124,102,131,115,140,124,151,128,167,129,189,129,273,131,293,136,308,144,320,157,328,175,334,175,340,157,339,144,338,132,336,114,328,107,321,100,312,96,300,94,287,93,271,93,181,91,163,87,149,80,139,67,131,50,125,67,118,80,110,87,100,91,86,93,68,93,-20,94,-35,96,-49,101,-61,107,-70,114,-77,123,-82,132,-85,143,-87,157,-89,175,-89, 107,-70,114,-77,115,110,115,110,114,-77,123,-82,115,110,123,-82,124,98,124,98,123,-82,132,-85,124,98,132,-85,129,-22,129,-22,129,60,128,82,129,-22,128,82,124,98,157,-89,175,-89,175,-84,157,-89,175,-84,157,-78,157,-89,157,-78,144,-69,157,-89,144,-69,143,-87,136,-58,131,-42,132,-85,136,-58,132,-85,143,-87,136,-58,143,-87,144,-69,102,118,83,124,87,100,102,118,87,100,91,86,102,118,91,86,93,68,102,118,93,68,94,-35,102,118,94,-35,96,-49,102,118,96,-49,101,-61,102,118,101,-61,107,-70,102,118,107,-70,115,110,93,68,93,-20,94,-35,80,110,87,100,83,124,80,110,83,124,87,149,80,110,87,149,80,139,80,110,80,139,67,118,157,339,144,338,144,320,157,339,144,320,157,328,157,339,157,328,175,334,157,339,175,334,175,340,129,273,131,293,132,336,132,336,131,293,136,308,132,336,136,308,144,338,144,338,136,308,144,320,114,328,115,140,123,332,123,332,115,140,124,151,123,332,124,151,129,273,129,273,124,151,128,167,129,273,128,167,129,189,107,321,100,312,102,131,107,321,102,131,115,140,107,321,115,140,114,328,102,131,100,312,96,300,102,131,96,300,94,287,102,131,94,287,93,271,102,131,93,271,93,181,102,131,93,181,91,163,102,131,91,163,87,149,102,131,87,149,83,124,67,131,50,125,67,118,67,131,67,118,80,139,123,332,129,273,132,336,129,-22,132,-85,131,-42, 66,-6,66,338,33,338,33,-6, 66,-6,66,338,33,338,66,-6,33,338,33,-6, 147,270,146,286,144,300,139,312,133,321,126,328,108,336,97,338,83,339,65,340,65,334,83,328,96,320,104,308,109,293,110,273,110,189,112,167,116,151,125,139,138,131,157,125,138,118,125,110,116,98,112,82,110,60,110,-22,109,-42,104,-58,96,-69,83,-78,65,-84,65,-89,83,-89,96,-87,108,-85,117,-82,126,-77,133,-71,139,-61,144,-50,146,-36,147,-20,147,68,149,86,153,100,160,111,172,118,190,125,172,131,160,139,153,149,149,163,147,181, 110,273,112,167,110,273,110,273,112,167,117,332,110,273,117,332,109,293,109,293,117,332,108,336,109,293,108,336,104,308,104,308,108,336,97,338,104,308,97,338,96,320,96,320,97,338,83,339,96,320,83,339,83,328,83,328,83,339,65,340,83,328,65,340,65,334,147,181,147,270,146,286,147,181,146,286,144,300,147,181,144,300,139,312,147,181,139,312,138,131,147,181,138,131,149,163,172,118,190,125,172,131,172,118,172,131,160,111,160,111,172,131,160,139,160,111,160,139,157,125,157,125,160,139,153,149,157,125,153,149,149,163,112,167,116,151,117,332,117,332,116,151,125,139,117,332,125,139,126,328,126,328,125,139,138,131,126,328,138,131,133,321,133,321,138,131,139,312,157,125,138,118,149,86,157,125,149,86,153,100,157,125,153,100,160,111,147,68,149,86,138,118,147,68,138,118,139,-61,147,68,139,-61,144,-50,147,68,144,-50,146,-36,147,68,146,-36,147,-20,116,98,117,-82,125,110,125,110,117,-82,126,-77,125,110,126,-77,138,118,138,118,126,-77,133,-71,138,118,133,-71,139,-61,117,-82,116,98,112,82,117,-82,112,82,110,60,117,-82,110,60,110,-22,117,-82,110,-22,109,-42,117,-82,109,-42,108,-85,104,-58,96,-69,96,-87,104,-58,96,-87,108,-85,104,-58,108,-85,109,-42,83,-78,65,-84,83,-89,83,-78,83,-89,96,-87,83,-78,96,-87,96,-69,83,-89,65,-84,65,-89,149,163,138,131,157,125,112,167,110,273,110,189, 233,162,227,151,219,141,211,133,201,128,189,126,179,127,157,135,148,140,141,143,124,150,111,155,100,158,92,160,83,160,69,159,56,154,43,146,31,134,20,117,38,92,44,104,51,114,60,122,70,126,80,128,92,127,103,125,114,122,122,119,128,116,143,107,155,101,166,97,176,95,189,94,202,95,214,100,226,108,238,120,251,137, 92,160,83,160,92,127,92,127,83,160,80,128,70,126,80,128,83,160,70,126,83,160,69,159,141,143,128,116,143,107,141,143,143,107,148,140,148,140,143,107,155,101,148,140,155,101,157,135,157,135,155,101,166,97,157,135,166,97,168,131,168,131,166,97,176,95,168,131,176,95,179,127,179,127,176,95,189,94,179,127,189,94,189,126,189,126,189,94,202,95,189,126,202,95,201,128,92,160,92,127,100,158,100,158,92,127,103,125,100,158,103,125,111,155,111,155,103,125,114,122,111,155,114,122,124,150,124,150,114,122,122,119,124,150,122,119,128,116,201,128,202,95,211,133,211,133,202,95,214,100,211,133,214,100,219,141,219,141,214,100,226,108,219,141,226,108,227,151,227,151,226,108,238,120,227,151,238,120,233,162,233,162,238,120,251,137,44,104,51,114,56,154,56,154,51,114,60,122,56,154,60,122,69,159,69,159,60,122,70,126,43,146,31,134,38,92,43,146,38,92,44,104,43,146,44,104,56,154,38,92,31,134,20,117,128,116,141,143,124,150, 101,209,100,217,96,224,90,229,83,233,75,234,66,233,59,229,53,224,49,217,48,209,49,200,53,192,58,186,66,182,74,181,83,182,90,186,96,192,100,200,101,209,16383,16383,78,141,71,141,49,-49,49,-53,48,-57,48,-69,49,-82,52,-93,58,-101,65,-106,75,-108,84,-106,91,-100,96,-92,100,-81,101,-68,101,-57,100,-53,100,-49, 48,209,49,200,49,217,49,217,49,200,53,192,49,217,53,192,53,224,53,224,53,192,58,186,53,224,58,186,59,229,59,229,58,186,66,182,59,229,66,182,66,233,66,233,66,182,74,181,66,233,74,181,75,234,75,234,74,181,83,182,75,234,83,182,83,233,83,233,83,182,90,186,83,233,90,186,90,229,90,229,90,186,96,192,90,229,96,192,96,224,96,224,96,192,100,200,96,224,100,200,100,217,100,217,100,200,101,209,100,-49,78,141,84,-106,100,-49,84,-106,91,-100,100,-49,91,-100,96,-92,100,-49,96,-92,100,-81,100,-49,100,-81,101,-68,100,-49,101,-68,100,-53,58,-101,65,-106,71,141,71,141,65,-106,75,-108,71,141,75,-108,78,141,78,141,75,-108,84,-106,71,141,49,-49,49,-82,71,141,49,-82,52,-93,71,141,52,-93,58,-101,49,-82,49,-49,49,-53,49,-82,49,-53,48,-57,49,-82,48,-57,48,-61,49,-82,48,-61,48,-65,49,-82,48,-65,48,-69,101,-68,101,-64,101,-61,101,-68,101,-61,101,-57,101,-68,101,-57,100,-53, 218,82,203,62,189,48,175,39,160,33,144,32,138,32,133,33,127,34,121,36,114,38,165,184,170,173,176,166,181,161,187,158,194,157,201,158,207,161,211,166,214,173,215,180,214,190,209,200,202,208,191,216,178,222,201,290,184,290,162,228,155,229,150,229,145,230,137,230,101,224,71,207,47,181,32,148,26,109,27,94,30,79,34,64,40,50,47,38,53,30,59,24,66,18,74,12,84,6,59,-68,76,-68,100,0,107,-1,119,-3,140,-3,151,0,161,3,171,8,180,15,190,24,198,33,206,45,214,59,224,78,16383,16383,99,49,86,63,76,77,70,92,66,110,65,130,68,158,77,182,91,200,110,211,133,215,138,215,142,214,147,213,151,212,156,210, 156,210,99,49,100,0,100,0,99,49,86,63,100,0,86,63,84,6,84,6,86,63,76,77,84,6,76,77,74,12,74,12,76,77,70,92,74,12,70,92,66,110,53,30,59,24,65,130,65,130,66,18,66,110,66,110,66,18,74,12,113,-2,119,-3,114,38,114,38,119,-3,121,36,121,36,119,-3,124,-3,121,36,124,-3,127,34,127,34,124,-3,129,-3,127,34,129,-3,133,33,133,33,129,-3,140,-3,133,33,140,-3,138,32,138,32,140,-3,144,32,160,33,144,32,151,0,160,33,151,0,161,3,114,38,165,184,156,210,156,210,162,228,155,229,156,210,155,229,151,212,151,212,155,229,150,229,151,212,150,229,147,213,147,213,150,229,145,230,147,213,145,230,142,214,142,214,145,230,141,230,142,214,141,230,138,215,138,215,141,230,137,230,138,215,137,230,133,215,184,290,162,228,165,184,184,290,165,184,170,173,184,290,170,173,178,222,184,290,178,222,201,290,170,173,176,166,178,222,178,222,176,166,181,161,178,222,181,161,191,216,191,216,181,161,187,158,191,216,187,158,194,157,114,38,156,210,100,0,114,38,100,0,107,-1,114,38,107,-1,113,-2,76,-68,100,0,84,6,76,-68,84,6,59,-68,194,157,201,158,202,208,202,208,201,158,207,161,202,208,207,161,209,200,209,200,207,161,211,166,209,200,211,166,214,190,214,190,211,166,214,173,214,190,214,173,215,180,77,182,91,200,101,224,101,224,91,200,110,211,101,224,110,211,137,230,137,230,110,211,133,215,71,207,47,181,47,38,71,207,47,38,53,30,71,207,53,30,65,130,71,207,65,130,68,158,71,207,68,158,77,182,71,207,77,182,101,224,27,94,30,79,32,148,32,148,30,79,34,64,32,148,34,64,47,181,47,181,34,64,40,50,47,181,40,50,47,38,190,24,198,33,203,62,203,62,198,33,206,45,203,62,206,45,218,82,218,82,206,45,214,59,218,82,214,59,224,78,161,3,171,8,175,39,175,39,171,8,180,15,175,39,180,15,189,48,189,48,180,15,190,24,189,48,190,24,203,62,144,32,140,-3,151,0,160,33,161,3,175,39,27,94,32,148,26,109,191,216,194,157,202,208,156,210,165,184,162,228,66,18,65,130,59,24, 172,164,172,186,109,186,107,205,106,220,105,233,104,245,104,256,106,280,112,299,122,313,135,322,151,325,161,324,169,321,175,315,178,308,180,299,180,285,182,275,186,269,191,266,199,265,207,266,214,270,219,276,223,283,224,291,221,306,212,319,198,329,180,336,159,338,126,333,99,317,79,293,66,261,61,221,62,214,62,208,64,194,65,186,12,186,12,164,65,164,68,147,71,127,73,109,75,93,76,81,76,69,75,67,75,63,69,64,64,64,60,65,51,65,36,63,24,58,14,50,8,40,6,27,8,16,12,8,19,1,28,-2,40,-3,50,-2,59,0,68,6,78,14,89,27,107,15,123,6,136,1,149,-1,161,-2,175,-1,188,1,201,7,212,15,223,24,229,32,235,42,240,52,244,61,245,68,245,69,244,70,240,70,238,69,236,67,233,65,230,62,230,63,221,54,210,47,199,42,187,39,174,38,160,38,147,40,133,43,117,48,99,55,109,105,111,117,112,125,112,164,16383,16383,71,38,71,35,68,29,66,26,64,22,59,18,55,14,50,12,46,10,40,10,33,11,27,13,23,17,20,22,19,28,20,35,23,40,28,44,35,46,44,47,52,46,59,45,65,43,69,41,71,38, 59,18,55,14,59,0,59,0,55,14,50,12,59,0,50,12,50,-2,50,-2,50,12,46,10,50,-2,46,10,40,-3,40,-3,46,10,40,10,69,64,64,64,65,43,65,43,64,64,60,65,65,43,60,65,59,45,59,45,60,65,56,65,59,45,56,65,52,46,52,46,56,65,51,65,52,46,51,65,44,47,20,35,23,40,24,58,24,58,23,40,28,44,24,58,28,44,36,63,36,63,28,44,35,46,36,63,35,46,44,47,20,22,19,28,19,1,19,1,19,28,14,50,14,50,19,28,24,58,24,58,19,28,20,35,71,35,70,33,78,14,78,14,70,33,68,29,78,14,68,29,68,6,68,6,68,29,66,26,68,6,66,26,64,22,64,22,59,18,68,6,68,6,59,18,59,0,75,67,75,65,78,14,78,14,75,65,75,62,78,14,75,62,71,38,71,38,75,62,75,63,71,38,75,63,69,41,69,41,75,63,69,64,69,41,69,64,65,43,78,14,71,38,71,35,89,27,107,15,99,55,99,55,107,15,117,48,117,48,107,15,123,6,117,48,123,6,133,43,133,43,123,6,136,1,133,43,136,1,147,40,147,40,136,1,149,-1,147,40,149,-1,160,38,160,38,149,-1,161,-2,160,38,161,-2,174,38,174,38,161,-2,175,-1,174,38,175,-1,187,39,99,55,105,85,104,256,104,256,106,280,99,317,99,317,106,280,112,299,99,317,112,299,126,333,126,333,112,299,122,313,126,333,122,313,135,322,180,336,159,338,161,324,161,324,159,338,151,325,135,322,151,325,159,338,135,322,159,338,126,333,221,306,212,319,214,270,221,306,214,270,219,276,221,306,219,276,223,283,221,306,223,283,224,291,186,269,191,266,198,329,198,329,191,266,199,265,198,329,199,265,212,319,212,319,199,265,207,266,212,319,207,266,214,270,178,308,180,299,180,336,180,336,180,299,180,285,180,336,180,285,198,329,198,329,180,285,182,275,198,329,182,275,186,269,180,336,161,324,169,321,180,336,169,321,175,315,180,336,175,315,178,308,76,71,78,14,76,73,76,73,78,14,79,293,79,293,78,14,89,27,79,293,89,27,99,317,99,317,89,27,99,55,99,317,99,55,104,256,109,105,111,117,109,186,109,186,111,117,112,164,109,186,112,164,172,186,172,186,112,164,172,164,109,186,107,205,109,105,109,105,107,205,106,220,109,105,106,220,105,85,105,85,106,220,105,233,105,85,105,233,104,245,112,139,112,146,112,133,112,133,112,146,112,152,112,133,112,152,112,125,112,125,112,152,112,158,112,125,112,158,112,164,229,32,230,62,223,24,223,24,230,62,221,54,223,24,221,54,212,15,212,15,221,54,210,47,212,15,210,47,201,7,201,7,210,47,199,42,201,7,199,42,188,1,188,1,199,42,187,39,188,1,187,39,175,-1,245,69,244,70,245,68,245,68,244,70,244,61,244,61,244,70,243,70,244,61,243,70,242,70,240,52,244,61,242,70,240,52,242,70,240,70,240,52,240,70,238,69,240,52,238,69,236,67,240,52,236,67,235,42,235,42,236,67,233,65,235,42,233,65,230,62,235,42,230,62,229,32,79,293,66,261,68,147,79,293,68,147,71,127,79,293,71,127,73,109,79,293,73,109,75,93,79,293,75,93,76,81,79,293,76,81,76,73,66,261,61,221,62,214,66,261,62,214,62,208,66,261,62,208,63,201,66,261,63,201,64,194,66,261,64,194,65,186,66,261,65,186,65,164,66,261,65,164,68,147,76,69,75,67,78,14,76,69,78,14,76,71,65,164,65,186,12,186,65,164,12,186,12,164,33,11,27,13,28,-2,33,11,28,-2,40,-3,33,11,40,-3,40,10,28,-2,27,13,23,17,28,-2,23,17,20,22,28,-2,20,22,19,1,6,27,8,16,8,40,8,40,8,16,12,8,8,40,12,8,14,50,14,50,12,8,19,1,221,54,230,62,230,63,112,125,112,164,111,117,104,256,105,85,104,245,44,47,51,65,36,63, 261,20,213,68,221,81,226,93,230,105,232,118,233,132,232,146,230,158,226,170,221,182,213,194,261,243,237,267,188,219,176,226,165,232,153,235,140,238,112,238,99,236,87,232,75,226,62,219,14,267,-10,243,38,194,30,182,24,170,20,158,18,145,17,131,18,117,20,105,24,92,30,80,38,68,-10,20,14,-4,62,44,74,36,87,31,99,27,112,24,126,23,139,24,152,27,164,31,176,37,188,44,237,-4,16383,16383,199,132,195,108,185,86,169,70,149,59,126,55,102,59,82,70,66,86,55,107,51,132,55,155,66,176,81,192,101,203,124,206,148,203,168,192,184,176,195,156,199,132, 99,27,112,24,102,59,102,59,112,24,126,55,149,59,126,55,126,23,149,59,126,23,139,24,62,219,14,267,38,194,62,219,38,194,38,68,62,219,38,68,51,132,62,219,51,132,55,155,62,219,55,155,66,176,62,219,66,176,75,226,66,86,55,107,62,44,62,44,55,107,51,132,140,238,126,238,148,203,148,203,126,238,124,206,101,203,124,206,112,238,101,203,112,238,99,236,87,232,75,226,81,192,87,232,81,192,101,203,87,232,101,203,99,236,261,20,213,68,237,-4,237,-4,213,68,195,108,237,-4,195,108,188,44,188,44,195,108,185,86,188,44,185,86,176,37,176,37,185,86,169,70,176,37,169,70,164,31,164,31,169,70,152,27,149,59,139,24,152,27,149,59,152,27,169,70,195,156,199,132,213,194,195,156,213,194,237,267,237,267,213,194,261,243,165,232,168,192,176,226,176,226,168,192,184,176,176,226,184,176,188,219,188,219,184,176,195,156,188,219,195,156,237,267,153,235,140,238,148,203,153,235,148,203,168,192,153,235,168,192,165,232,213,194,213,68,221,182,221,182,213,68,221,81,221,182,221,81,226,170,226,170,221,81,226,93,226,170,226,93,230,158,230,158,226,93,230,105,230,158,230,105,232,146,232,146,230,105,232,118,232,146,232,118,233,132,213,68,213,194,199,132,213,68,199,132,195,108,126,55,112,24,126,23,126,238,112,238,124,206,99,27,102,59,87,31,87,31,102,59,82,70,87,31,82,70,74,36,74,36,82,70,66,86,74,36,66,86,62,44,38,68,14,-4,62,44,38,68,62,44,51,132,38,68,38,194,30,80,30,80,38,194,30,182,30,80,30,182,24,92,24,92,30,182,24,170,24,92,24,170,20,105,20,105,24,170,20,158,20,105,20,158,18,117,18,117,20,158,18,145,18,117,18,145,17,131,14,-4,38,68,-10,20,75,226,66,176,81,192,38,194,14,267,-10,243, 256,331,158,331,158,321,174,321,181,319,186,315,190,311,191,306,191,303,190,299,188,294,187,289,184,284,128,174,69,285,67,289,65,294,64,299,63,303,63,307,64,313,67,317,73,319,83,321,95,321,95,331,-25,331,-25,321,-13,319,-3,314,7,304,18,287,32,262,80,176,8,176,8,156,92,156,95,149,95,111,8,111,8,91,95,91,95,60,94,39,91,25,84,16,72,11,55,9,55,0,177,0,177,9,161,11,150,16,142,24,138,37,137,55,137,91,224,91,224,111,137,111,137,149,141,156,224,156,224,176,151,176,197,268,207,286,218,300,229,310,242,317,256,321, 32,262,80,176,32,262,32,262,80,176,63,303,32,262,63,303,63,307,63,307,64,313,32,262,91,25,84,16,177,0,177,0,84,16,72,11,177,0,72,11,55,9,95,331,-25,331,-13,319,95,331,-13,319,-3,314,95,331,-3,314,7,304,95,331,7,304,67,317,95,331,67,317,73,319,95,331,73,319,83,321,95,331,83,321,95,321,18,287,32,262,64,313,18,287,64,313,67,317,18,287,67,317,7,304,184,284,128,174,137,149,184,284,137,149,141,156,184,284,141,156,151,176,184,284,151,176,197,268,184,284,197,268,187,289,256,331,158,331,166,321,256,331,166,321,174,321,256,331,174,321,181,319,256,331,181,319,186,315,256,331,186,315,190,311,256,331,190,311,191,306,256,331,191,306,229,310,256,331,229,310,242,317,256,331,242,317,256,321,197,268,207,286,191,306,197,268,191,306,191,303,197,268,191,303,190,299,197,268,190,299,188,294,197,268,188,294,187,289,218,300,229,310,191,306,218,300,191,306,207,286,92,156,95,149,128,174,128,174,95,149,138,37,128,174,138,37,137,55,137,111,137,91,224,91,137,111,224,91,224,111,151,176,141,156,224,156,151,176,224,156,224,176,177,0,177,9,161,11,177,0,161,11,150,16,177,0,150,16,94,39,177,0,94,39,91,25,142,24,138,37,95,149,142,24,95,149,95,111,142,24,95,111,95,91,142,24,95,91,95,60,142,24,95,60,150,16,8,111,8,91,95,91,8,111,95,91,95,111,80,176,8,176,92,156,80,176,92,156,128,174,80,176,128,174,69,285,80,176,69,285,67,289,80,176,67,289,65,294,80,176,65,294,64,299,80,176,64,299,63,303,92,156,8,176,8,156,177,0,55,9,55,0,94,39,150,16,95,60,137,149,128,174,137,55,166,321,158,331,158,321,-13,319,-25,331,-25,321, 66,200,66,338,33,338,33,200,16383,16383,66,-6,66,131,33,131,33,-6, 33,338,33,200,66,200,33,338,66,200,66,338,33,131,33,-6,66,-6,33,131,66,-6,66,131, 100,257,94,262,86,276,84,284,83,292,85,304,91,314,100,321,111,326,126,328,135,327,144,324,150,321,155,316,156,311,156,310,155,309,154,307,152,306,144,298,142,293,140,289,140,284,141,277,144,271,149,266,155,263,163,262,172,263,179,267,184,272,188,280,189,289,185,305,177,318,163,329,145,336,124,338,101,335,82,327,68,314,58,297,55,277,57,262,61,248,70,235,84,220,105,202,99,202,97,203,92,203,74,200,58,191,46,179,38,162,35,143,38,121,48,100,64,79,88,57,121,32,137,20,150,8,159,-2,164,-13,165,-24,163,-37,157,-48,148,-56,136,-61,122,-63,111,-62,101,-59,93,-55,88,-50,86,-45,86,-44,87,-42,90,-39,92,-38,96,-33,99,-29,103,-21,103,-17,102,-10,99,-5,93,0,87,2,79,3,70,2,63,-1,57,-7,53,-14,52,-23,55,-39,65,-53,80,-64,99,-71,121,-73,145,-70,165,-62,180,-48,190,-31,193,-10,192,4,187,17,179,30,165,45,146,63,152,63,173,65,190,73,202,86,210,102,213,123,211,139,206,154,197,170,184,185,169,200,16383,16383,187,105,185,96,180,87,172,80,163,75,152,73,141,75,129,79,116,87,101,99,84,114,75,124,69,133,65,141,62,149,61,158,63,169,68,178,75,185,84,190,95,191,106,190,118,184,132,176,146,165,161,152,170,142,177,132,183,123,186,114,187,105, 101,335,82,327,85,304,85,304,82,327,83,292,84,220,83,292,82,327,84,220,82,327,70,235,70,235,82,327,68,314,70,235,68,314,61,248,61,248,68,314,58,297,61,248,58,297,57,262,57,262,58,297,55,277,69,133,88,57,75,124,75,124,88,57,84,114,101,99,84,114,88,57,101,99,88,57,121,32,95,191,94,203,92,203,95,191,92,203,84,190,95,191,97,203,94,203,63,169,68,178,74,200,74,200,68,178,75,185,74,200,75,185,92,203,92,203,75,185,84,190,74,200,58,191,63,169,63,169,58,191,61,158,64,79,61,158,58,191,64,79,58,191,48,100,48,100,58,191,46,179,48,100,46,179,38,121,38,121,46,179,38,162,38,121,38,162,35,143,165,45,146,63,150,8,150,8,146,63,141,75,150,8,141,75,137,20,137,20,141,75,129,79,137,20,129,79,121,32,121,32,129,79,116,87,121,32,116,87,101,99,163,-37,157,-48,165,-62,165,-62,157,-48,148,-56,165,-62,148,-56,145,-70,145,-70,148,-56,136,-61,145,-70,136,-61,122,-63,122,-63,111,-62,121,-73,121,-73,111,-62,101,-59,121,-73,101,-59,99,-71,99,-71,101,-59,93,-55,99,-71,93,-55,88,-50,79,3,80,-64,87,2,87,2,80,-64,86,-45,88,-50,86,-45,80,-64,88,-50,80,-64,99,-71,144,324,145,336,135,327,135,327,145,336,126,328,111,326,126,328,124,338,111,326,124,338,101,335,101,335,85,304,91,314,101,335,91,314,100,321,101,335,100,321,111,326,152,73,146,63,152,63,152,73,152,63,173,65,152,73,141,75,146,63,180,87,172,80,173,65,173,65,172,80,163,75,173,65,163,75,152,73,118,184,132,176,169,200,169,200,132,176,146,165,169,200,146,165,161,152,161,152,170,142,169,200,169,200,170,142,184,185,213,123,211,139,210,102,210,102,211,139,206,154,210,102,206,154,202,86,202,86,206,154,197,170,202,86,197,170,190,73,190,73,197,170,187,105,190,73,187,105,185,96,190,73,185,96,180,87,177,132,183,123,184,185,184,185,183,123,186,114,184,185,186,114,197,170,197,170,186,114,187,105,106,190,118,184,169,200,106,190,169,200,105,202,106,190,105,202,102,202,106,190,102,202,99,202,106,190,99,202,97,203,106,190,97,203,95,191,100,257,94,262,105,202,100,257,105,202,169,200,94,262,90,269,105,202,105,202,90,269,86,276,105,202,86,276,84,220,84,220,86,276,84,284,84,220,84,284,83,292,193,-10,192,4,190,-31,190,-31,192,4,187,17,190,-31,187,17,180,-48,180,-48,187,17,179,30,180,-48,179,30,165,45,165,45,150,8,159,-2,165,45,159,-2,164,-13,165,45,164,-13,165,-24,165,45,165,-24,165,-62,165,45,165,-62,180,-48,163,-37,165,-62,165,-24,122,-63,121,-73,145,-70,156,311,156,310,163,262,163,262,156,310,155,309,163,262,155,309,155,263,155,263,155,309,154,307,155,263,154,307,152,306,163,329,156,311,163,262,155,316,156,311,163,329,155,316,163,329,150,321,150,321,163,329,145,336,150,321,145,336,144,324,145,336,124,338,126,328,185,305,177,318,179,267,185,305,179,267,184,272,185,305,184,272,188,280,185,305,188,280,189,289,177,318,163,329,163,262,177,318,163,262,172,263,177,318,172,263,179,267,149,266,155,263,152,306,149,266,152,306,148,302,149,266,148,302,144,298,149,266,144,298,144,271,142,293,140,289,141,277,142,293,141,277,144,271,142,293,144,271,144,298,102,-10,99,-5,99,-29,102,-10,99,-29,101,-25,102,-10,101,-25,103,-21,102,-10,103,-21,103,-17,99,-29,99,-5,96,-33,96,-33,99,-5,93,0,96,-33,93,0,92,-38,92,-38,93,0,90,-39,86,-45,86,-44,87,2,87,2,86,-44,87,-42,87,2,87,-42,93,0,93,0,87,-42,88,-41,93,0,88,-41,90,-39,70,2,63,-1,65,-53,70,2,65,-53,80,-64,70,2,80,-64,79,3,57,-7,53,-14,55,-39,57,-7,55,-39,65,-53,57,-7,65,-53,63,-1,65,141,62,149,64,79,65,141,64,79,88,57,65,141,88,57,69,133,61,158,64,79,62,149,55,-39,53,-14,52,-23,141,277,140,289,140,284,180,87,173,65,190,73,184,185,170,142,177,132, 158,286,157,294,153,301,148,306,141,310,133,311,125,310,118,306,113,301,110,294,108,286,109,278,113,272,118,266,125,263,132,262,140,263,148,266,153,272,157,278,158,286,16383,16383,59,286,57,294,54,301,48,306,41,310,33,311,26,310,19,306,14,301,10,294,9,286,10,278,14,272,19,266,25,263,33,262,41,263,48,266,54,272,57,278,59,286, 108,286,109,278,110,294,110,294,109,278,113,272,110,294,113,272,113,301,113,301,113,272,118,266,113,301,118,266,118,306,118,306,118,266,125,263,118,306,125,263,125,310,125,310,125,263,132,262,125,310,132,262,133,311,133,311,132,262,140,263,133,311,140,263,141,310,141,310,140,263,148,266,141,310,148,266,148,306,148,306,148,266,153,272,148,306,153,272,153,301,153,301,153,272,157,278,153,301,157,278,157,294,157,294,157,278,158,286,9,286,10,278,10,294,10,294,10,278,14,272,10,294,14,272,14,301,14,301,14,272,19,266,14,301,19,266,19,306,19,306,19,266,25,263,19,306,25,263,26,310,26,310,25,263,33,262,26,310,33,262,33,311,33,311,33,262,41,263,33,311,41,263,41,310,41,310,41,263,48,266,41,310,48,266,48,306,48,306,48,266,54,272,48,306,54,272,54,301,54,301,54,272,57,278,54,301,57,278,57,294,57,294,57,278,59,286, 273,124,266,124,257,108,247,95,236,87,223,82,208,80,183,84,162,95,147,113,137,138,133,169,137,197,146,221,161,240,180,252,205,256,221,254,234,249,245,240,253,227,257,211,266,211,266,247,265,249,264,250,263,252,261,254,259,255,249,259,238,262,216,266,205,266,169,262,138,248,115,227,100,199,95,165,99,133,112,107,132,87,158,75,191,70,210,71,230,74,247,78,260,82,265,86,16383,16383,361,165,352,220,329,267,292,305,246,329,193,338,137,329,89,305,52,268,28,220,19,165,28,110,52,63,89,26,136,1,190,-6,245,1,292,26,329,63,353,110,361,165,16383,16383,334,167,326,119,306,77,275,44,235,22,190,14,145,22,106,43,74,76,54,118,46,166,54,213,74,254,106,287,144,309,189,317,234,309,274,288,305,255,326,214,334,167, 162,95,147,113,158,75,158,75,147,113,137,138,158,75,137,138,132,87,132,87,137,138,133,169,138,248,133,169,137,197,138,248,137,197,146,221,216,266,205,266,221,254,221,254,205,266,205,256,180,252,205,256,205,266,180,252,205,266,169,262,263,252,261,254,266,211,266,211,261,254,259,255,266,211,259,255,257,211,257,211,259,255,253,227,169,262,138,248,146,221,169,262,146,221,161,240,169,262,161,240,180,252,115,227,100,199,112,107,115,227,112,107,132,87,115,227,132,87,133,169,115,227,133,169,138,248,100,199,95,165,99,133,100,199,99,133,112,107,266,124,257,108,260,82,260,82,257,108,247,95,260,82,247,95,247,78,247,78,247,95,236,87,247,78,236,87,230,74,230,74,236,87,223,82,230,74,223,82,210,71,210,71,223,82,208,80,191,70,210,71,208,80,191,70,208,80,183,84,191,70,183,84,162,95,191,70,162,95,158,75,266,211,266,247,265,249,266,211,265,249,264,250,266,211,264,250,263,252,216,266,221,254,227,264,227,264,221,254,234,249,227,264,234,249,238,262,238,262,234,249,245,240,238,262,245,240,249,259,249,259,245,240,253,227,249,259,253,227,259,255,266,124,260,82,265,86,266,124,265,86,273,124,193,338,189,317,234,309,193,338,234,309,246,329,246,329,234,309,274,288,246,329,274,288,292,305,292,305,274,288,305,255,292,305,305,255,329,267,329,267,305,255,326,214,329,267,326,214,334,167,334,167,352,220,329,267,334,167,353,110,352,220,329,63,353,110,334,167,329,63,334,167,326,119,329,63,326,119,306,77,329,63,306,77,292,26,190,14,190,-6,235,22,235,22,190,-6,245,1,235,22,245,1,275,44,275,44,245,1,292,26,275,44,292,26,306,77,54,213,74,254,89,305,89,305,74,254,106,287,89,305,106,287,137,329,137,329,106,287,144,309,137,329,144,309,193,338,193,338,144,309,189,317,28,110,52,63,28,220,28,220,52,63,46,166,52,268,46,166,54,213,52,268,54,213,89,305,145,22,106,43,136,1,145,22,136,1,190,-6,145,22,190,-6,190,14,89,26,136,1,106,43,89,26,106,43,74,76,89,26,74,76,54,118,89,26,54,118,52,63,46,166,52,63,54,118,28,110,28,220,19,165,28,220,46,166,52,268,352,220,353,110,361,165, 135,221,129,217,127,216,124,215,118,215,116,217,115,220,115,225,114,233,114,290,112,307,106,321,96,330,81,336,62,338,44,337,29,332,18,325,10,316,8,305,9,300,11,295,14,292,19,290,24,289,29,290,37,294,39,298,40,301,40,303,39,304,39,307,38,309,38,313,39,316,43,319,48,322,54,324,60,324,67,323,72,321,76,316,78,310,79,303,79,288,56,279,40,273,29,268,20,263,13,257,9,253,6,248,4,243,2,231,4,220,9,210,16,203,26,199,37,197,46,198,55,200,64,205,73,211,83,219,85,210,88,204,93,200,98,198,105,197,112,197,117,199,123,202,128,206,135,212,16383,16383,79,237,79,235,78,233,77,230,76,228,74,226,64,222,60,221,56,221,52,220,46,222,41,225,37,230,34,236,33,243,35,250,39,256,48,262,61,269,79,276, 38,309,38,310,39,298,39,298,38,310,38,311,39,298,38,311,37,294,37,294,38,311,38,313,44,337,38,313,39,316,44,337,39,316,43,319,39,305,39,307,39,298,39,305,39,298,40,301,40,301,40,302,40,303,40,301,40,303,39,304,40,301,39,304,39,305,46,198,55,200,46,222,46,222,55,200,52,220,56,221,52,220,55,200,56,221,55,200,64,205,81,336,62,338,67,323,67,323,62,338,60,324,54,324,60,324,62,338,54,324,62,338,48,322,48,322,62,338,44,337,48,322,44,337,43,319,78,233,77,230,83,219,83,219,77,230,76,228,83,219,76,228,74,226,74,226,69,224,73,211,73,211,69,224,64,222,73,211,64,222,64,205,64,205,64,222,60,221,64,205,60,221,56,221,24,289,29,290,29,332,29,332,29,290,33,292,29,332,33,292,38,313,38,313,33,292,37,294,11,295,14,292,18,325,18,325,14,292,19,290,18,325,19,290,29,332,29,332,19,290,24,289,10,316,8,305,9,300,10,316,9,300,11,295,10,316,11,295,18,325,81,336,79,276,83,219,81,336,83,219,96,330,96,330,83,219,85,210,96,330,85,210,88,204,81,336,67,323,72,321,81,336,72,321,76,316,81,336,76,316,78,310,81,336,78,310,79,303,81,336,79,303,79,276,98,198,105,197,106,321,106,321,105,197,112,197,106,321,112,197,112,307,112,307,112,197,115,225,112,307,115,225,114,233,117,199,123,202,118,215,118,215,123,202,121,215,124,215,121,215,123,202,124,215,123,202,128,206,135,221,132,219,135,212,135,212,132,219,129,217,135,212,129,217,128,206,128,206,129,217,127,216,128,206,127,216,124,215,117,199,118,215,116,217,117,199,116,217,115,220,117,199,115,220,115,225,117,199,115,225,112,197,96,330,88,204,93,200,96,330,93,200,98,198,96,330,98,198,106,321,83,219,79,276,79,237,83,219,79,237,79,235,83,219,79,235,78,233,74,226,73,211,83,219,35,250,39,256,40,273,40,273,39,256,48,262,40,273,48,262,56,279,56,279,48,262,61,269,56,279,61,269,79,288,79,288,61,269,79,276,79,288,79,276,79,303,40,273,29,268,35,250,35,250,29,268,33,243,37,197,33,243,29,268,37,197,29,268,26,199,26,199,29,268,20,263,26,199,20,263,16,203,16,203,20,263,13,257,16,203,13,257,9,253,41,225,37,230,37,197,41,225,37,197,46,198,41,225,46,198,46,222,34,236,33,243,37,197,34,236,37,197,37,230,9,210,16,203,9,253,9,210,9,253,6,248,9,210,6,248,4,243,9,210,4,243,4,220,3,237,2,231,4,220,3,237,4,220,4,243,114,233,114,290,112,307,29,332,38,313,44,337,38,309,39,298,39,307, 117,113,157,77,172,64,203,33,216,21,222,17,224,17,225,18,227,19,228,20,228,22,227,26,224,31,219,39,212,49,203,60,196,70,188,80,180,91,171,102,161,113,203,166,212,178,219,187,224,194,227,199,228,203,228,205,227,207,225,208,223,208,216,204,204,193,172,163,157,150,16383,16383,21,113,61,77,76,64,107,33,120,21,126,17,128,17,129,18,131,19,132,20,132,22,131,26,128,31,123,39,116,49,107,60,100,70,92,80,65,113,107,166,116,178,123,187,128,194,131,199,132,203,132,205,131,207,129,208,127,208,120,204,108,193,76,163,61,150, 203,60,196,70,203,60,203,60,196,70,203,33,203,60,203,33,212,49,212,49,203,33,216,21,212,49,216,21,219,39,219,39,216,21,222,17,219,39,222,17,224,31,224,31,222,17,224,17,224,31,224,17,225,18,227,26,224,31,225,18,227,26,225,18,227,19,227,26,227,19,228,20,227,26,228,20,228,22,171,102,172,64,180,91,180,91,172,64,188,48,180,91,188,48,188,80,188,80,188,48,203,33,188,80,203,33,196,70,161,113,172,163,157,150,161,113,157,150,157,77,161,113,157,77,172,64,161,113,172,64,171,102,228,205,227,207,227,199,228,205,227,199,228,203,228,205,228,203,228,204,188,178,203,166,204,193,204,193,203,166,212,178,204,193,212,178,216,204,216,204,212,178,219,187,216,204,219,187,223,208,223,208,219,187,224,194,223,208,224,194,225,208,225,208,224,194,227,199,225,208,227,199,227,207,172,163,161,113,203,166,172,163,203,166,188,178,107,60,100,70,107,33,107,60,107,33,116,49,116,49,107,33,120,21,116,49,120,21,123,39,123,39,120,21,126,17,123,39,126,17,128,31,128,31,126,17,128,17,128,31,128,17,129,18,131,26,128,31,129,18,131,26,129,18,131,19,131,26,131,19,132,20,131,26,132,20,132,22,74,102,76,64,83,91,83,91,76,64,92,48,83,91,92,48,92,80,92,80,92,48,107,33,92,80,107,33,100,70,65,113,76,163,61,150,65,113,61,150,61,77,65,113,61,77,76,64,65,113,76,64,74,102,132,205,131,207,131,199,132,205,131,199,132,203,132,205,132,203,132,204,92,178,107,166,108,193,108,193,107,166,116,178,108,193,116,178,120,204,120,204,116,178,123,187,120,204,123,187,127,208,127,208,123,187,128,194,127,208,128,194,129,208,129,208,128,194,131,199,129,208,131,199,131,207,76,163,65,113,107,166,76,163,107,166,92,178,61,77,61,150,21,113,157,77,157,150,117,113, 276,57,276,196,24,196,24,164,243,164,243,57, 243,164,243,57,276,57,243,164,276,57,276,196,243,164,276,196,24,196,243,164,24,196,24,164, 142,97,142,128,20,128,20,97, 142,97,142,128,20,128,142,97,20,128,20,97, 283,76,283,80,276,86,268,94,252,112,244,123,216,162,230,168,241,177,249,188,254,199,256,211,253,228,246,241,233,251,217,258,196,260,110,260,110,252,122,251,128,248,132,244,134,237,134,98,132,91,129,87,121,85,110,84,109,76,190,76,190,84,178,85,171,87,168,92,166,100,166,157,190,157,199,143,206,133,210,127,213,121,216,116,224,101,232,90,239,82,246,77,252,76,16383,16383,166,166,166,251,185,251,199,248,210,243,217,234,221,222,222,209,221,196,216,184,209,175,199,168,187,166,188,166,16383,16383,361,165,352,220,329,267,292,305,246,329,193,338,137,330,89,305,52,268,28,221,19,166,28,111,51,63,88,26,135,1,190,-6,245,1,292,26,329,63,353,110,361,165,16383,16383,334,165,326,118,306,77,275,44,235,22,190,14,145,22,106,43,74,76,54,118,46,166,54,213,74,254,106,287,145,309,189,317,235,309,275,288,306,255,326,213,334,165, 222,209,222,209,222,209,222,209,230,168,233,251,233,251,230,168,241,177,233,251,241,177,246,241,246,241,241,177,249,188,246,241,249,188,253,228,253,228,249,188,254,199,253,228,254,199,256,211,221,222,222,209,233,251,221,222,233,251,217,258,221,222,217,258,217,234,166,251,185,251,196,260,196,260,185,251,199,248,196,260,199,248,217,258,217,258,199,248,210,243,217,258,210,243,217,234,134,226,168,92,166,100,134,226,166,100,166,111,166,166,166,157,190,157,166,166,190,157,187,166,187,166,190,157,188,166,187,166,188,166,199,168,199,168,188,166,190,157,199,168,190,157,199,143,166,251,196,260,132,244,166,251,132,244,134,237,166,251,134,237,134,226,166,251,134,226,166,111,196,260,110,260,122,251,196,260,122,251,128,248,196,260,128,248,132,244,213,121,216,162,216,184,216,184,216,162,230,168,216,184,230,168,221,196,221,196,230,168,222,209,213,121,216,184,210,127,210,127,216,184,209,175,210,127,209,175,206,133,206,133,209,175,199,168,206,133,199,168,199,143,232,90,239,82,244,123,244,123,239,82,246,77,244,123,246,77,252,112,252,112,246,77,252,76,252,112,252,76,260,103,260,103,252,76,283,76,260,103,283,76,268,94,268,94,283,76,276,86,244,123,216,162,216,116,244,123,216,116,224,101,244,123,224,101,232,90,190,76,190,84,178,85,190,76,178,85,171,87,190,76,171,87,134,108,190,76,134,108,134,98,190,76,134,98,132,91,190,76,132,91,129,87,190,76,129,87,121,85,190,76,121,85,110,84,190,76,110,84,109,76,134,111,134,108,171,87,134,111,171,87,168,92,134,111,168,92,134,226,193,338,189,317,235,309,193,338,235,309,246,329,246,329,235,309,275,288,246,329,275,288,292,305,292,305,275,288,306,255,292,305,306,255,329,267,329,267,306,255,326,213,329,267,326,213,334,165,334,165,352,220,329,267,334,165,353,110,352,220,329,63,353,110,334,165,329,63,334,165,326,118,329,63,326,118,306,77,329,63,306,77,292,26,190,14,190,-6,235,22,235,22,190,-6,245,1,235,22,245,1,275,44,275,44,245,1,292,26,275,44,292,26,306,77,54,213,74,254,89,305,89,305,74,254,106,287,89,305,106,287,137,330,137,330,106,287,145,309,137,330,145,309,193,338,193,338,145,309,189,317,28,111,51,63,28,221,28,221,51,63,46,166,52,268,46,166,54,213,52,268,54,213,89,305,145,22,106,43,135,1,145,22,135,1,190,-6,145,22,190,-6,190,14,88,26,135,1,106,43,88,26,106,43,74,76,88,26,74,76,54,118,88,26,54,118,51,63,46,166,51,63,54,118,28,111,28,221,19,166,28,221,46,166,52,268,352,220,353,110,361,165,216,116,216,162,213,121,276,86,283,76,283,80,122,251,110,260,110,252, 161,273,161,300,6,300,6,273, 161,273,161,300,6,300,161,273,6,300,6,273, 171,267,168,289,158,309,143,324,123,334,101,338,78,335,58,325,42,309,32,290,28,267,32,244,42,224,57,209,77,198,100,195,123,198,142,209,158,224,168,244,171,267,16383,16383,152,267,149,250,142,235,130,223,116,215,100,212,84,215,69,223,58,234,51,249,48,267,51,284,58,298,69,310,83,318,99,321,115,318,130,310,141,299,149,284,152,267, 83,318,99,321,99,321,101,338,99,321,115,318,101,338,115,318,123,334,123,334,115,318,130,310,123,334,130,310,143,324,143,324,130,310,141,299,143,324,141,299,149,284,171,267,168,289,168,244,168,244,168,289,158,309,168,244,158,309,158,224,158,224,158,309,152,267,158,224,152,267,149,250,158,224,149,250,142,209,142,209,149,250,142,235,142,209,142,235,130,223,158,309,143,324,149,284,158,309,149,284,152,267,142,209,130,223,123,198,123,198,130,223,116,215,123,198,116,215,100,195,100,195,116,215,100,212,58,298,69,310,78,335,78,335,69,310,83,318,78,335,83,318,101,338,101,338,83,318,99,321,42,309,48,267,51,284,42,309,51,284,58,325,58,325,51,284,58,298,58,325,58,298,78,335,84,215,69,223,77,198,84,215,77,198,100,195,84,215,100,195,100,212,48,267,42,224,51,249,51,249,42,224,57,209,51,249,57,209,58,234,58,234,57,209,77,198,58,234,77,198,69,223,28,267,32,244,32,290,32,290,32,244,42,224,32,290,42,224,42,309,42,309,42,224,48,267, 319,121,319,154,188,154,188,251,155,251,155,154,24,154,24,121,155,121,155,17,188,17,188,121,16383,16383,319,-43,319,-10,24,-10,24,-43, 188,251,155,251,188,17,188,17,155,251,155,154,188,17,155,154,155,121,155,121,155,154,24,154,155,121,24,154,24,121,188,121,319,121,188,154,24,-10,24,-43,319,-43,24,-10,319,-43,319,-10,188,154,319,121,319,154,188,17,155,121,155,17, 148,177,139,181,134,175,124,169,110,167,54,167,95,208,112,226,125,241,133,255,137,269,138,283,136,301,127,316,114,328,97,335,75,338,53,336,35,329,21,317,10,301,1,278,13,271,20,284,28,295,37,302,46,307,57,308,68,306,78,301,86,292,91,282,93,270,91,260,86,247,78,233,67,217,54,201,3,147,3,135,128,135, 54,201,3,147,54,167,54,201,54,167,95,208,54,201,95,208,67,217,13,271,20,284,21,317,21,317,20,284,28,295,21,317,28,295,35,329,35,329,28,295,37,302,35,329,37,302,53,336,53,336,37,302,46,307,53,336,46,307,57,308,57,308,68,306,75,338,75,338,68,306,78,301,75,338,78,301,97,335,97,335,78,301,86,292,97,335,86,292,91,282,10,301,1,278,13,271,10,301,13,271,21,317,91,260,95,208,93,270,93,270,95,208,97,335,97,335,95,208,112,226,97,335,112,226,114,328,114,328,112,226,125,241,114,328,125,241,127,316,127,316,125,241,133,255,127,316,133,255,136,301,136,301,133,255,137,269,136,301,137,269,138,283,97,335,91,282,93,270,75,338,53,336,57,308,95,208,91,260,86,247,95,208,86,247,78,233,95,208,78,233,67,217,129,172,124,169,128,135,128,135,124,169,117,168,128,135,117,168,110,167,128,135,110,167,54,167,128,135,54,167,3,147,148,177,139,181,134,175,148,177,134,175,129,172,148,177,129,172,128,135,128,135,3,147,3,135, 102,256,114,263,123,271,129,279,131,288,132,296,130,310,122,321,110,330,95,336,78,338,61,336,46,331,33,322,22,309,11,291,23,281,31,293,39,301,47,306,56,309,66,310,76,309,83,306,89,301,93,295,94,286,92,276,87,267,78,259,65,252,46,244,46,230,52,231,59,231,60,232,76,230,88,225,97,216,103,205,105,190,103,179,99,169,92,162,82,157,71,155,66,155,61,156,57,158,52,161,40,169,32,173,28,174,25,175,19,174,14,172,10,169,8,165,7,159,9,150,15,142,25,136,37,132,52,131,83,134,109,144,129,159,141,177,146,200,144,214,139,227,130,239,118,248,102,254, 66,155,61,156,83,134,83,134,61,156,57,158,83,134,57,158,52,131,52,131,57,158,52,161,52,131,52,161,46,165,56,231,59,231,65,252,65,252,59,231,60,232,60,232,76,230,65,252,65,252,76,230,78,259,65,252,46,244,52,231,65,252,52,231,56,231,23,281,31,293,33,322,33,322,31,293,39,301,33,322,39,301,46,331,46,331,39,301,47,306,46,331,47,306,61,336,61,336,47,306,56,309,61,336,56,309,66,310,66,310,76,309,78,338,78,338,76,309,83,306,78,338,83,306,95,336,95,336,83,306,89,301,95,336,89,301,93,295,22,309,11,291,23,281,22,309,23,281,33,322,103,179,99,169,109,144,109,144,99,169,92,162,109,144,92,162,83,134,83,134,92,162,82,157,83,134,82,157,71,155,71,155,66,155,83,134,95,336,94,286,97,216,95,336,97,216,110,330,110,330,97,216,102,256,110,330,102,256,114,263,78,338,61,336,66,310,130,310,122,321,123,271,130,310,123,271,129,279,130,310,129,279,131,288,130,310,131,288,132,296,122,321,110,330,114,263,122,321,114,263,123,271,102,254,102,256,97,216,102,254,97,216,103,205,102,254,103,205,118,248,92,276,87,267,88,225,92,276,88,225,97,216,92,276,97,216,94,286,78,259,76,230,88,225,78,259,88,225,87,267,141,177,146,200,144,214,141,177,144,214,139,227,141,177,139,227,130,239,141,177,130,239,129,159,103,179,109,144,105,190,105,190,109,144,118,248,118,248,109,144,129,159,118,248,129,159,130,239,105,190,118,248,103,205,40,169,36,171,37,132,40,169,37,132,52,131,40,169,52,131,46,165,37,132,36,171,32,173,37,132,32,173,28,174,37,132,28,174,25,175,37,132,25,175,25,136,19,174,14,172,15,142,19,174,15,142,25,136,19,174,25,136,25,175,10,169,8,165,9,150,10,169,9,150,15,142,10,169,15,142,14,172,52,231,46,244,46,230,9,150,8,165,7,159,95,336,93,295,94,286, 46,253,66,253,143,302,149,306,153,310,156,314,158,318,158,329,155,333,152,336,147,338,141,339,133,337,129,335,125,332,120,328, 141,339,143,302,147,338,147,338,143,302,149,306,147,338,149,306,152,336,152,336,149,306,153,310,152,336,153,310,155,333,155,333,153,310,156,314,155,333,156,314,158,329,158,329,156,314,158,318,158,329,158,318,158,323,143,302,141,339,137,338,143,302,137,338,133,337,143,302,133,337,129,335,143,302,129,335,125,332,143,302,125,332,120,328,143,302,120,328,66,253,66,253,120,328,46,253, 215,225,171,225,171,57,164,46,155,38,144,31,131,27,116,26,102,28,90,34,81,45,76,59,74,78,74,225,30,225,30,27,29,14,26,-5,22,-28,19,-51,18,-69,19,-82,22,-93,26,-101,32,-106,40,-108,48,-106,55,-102,60,-94,63,-83,64,-69,62,-51,58,-29,52,-6,48,14,46,32,55,18,66,8,77,1,91,-3,107,-4,123,-2,137,2,150,11,162,24,172,40,174,40,176,24,182,11,191,2,201,-2,211,-4,222,-3,231,0,239,4,247,12,256,23,256,28,249,22,244,18,239,15,235,14,230,13,224,15,220,19,217,26,215,36,215,48, 46,32,46,32,46,32,46,32,74,225,30,225,46,32,30,225,32,-106,46,32,32,-106,40,-108,46,32,40,-108,48,-106,76,59,74,78,77,1,77,1,74,78,66,8,66,8,74,78,74,225,66,8,74,225,55,18,55,18,74,225,46,32,30,225,30,27,32,-106,32,-106,30,27,29,14,32,-106,29,14,26,-101,26,-101,29,14,26,-5,26,-101,26,-5,22,-28,18,-69,19,-82,19,-51,19,-51,19,-82,22,-93,19,-51,22,-93,22,-28,22,-28,22,-93,26,-101,171,225,171,57,172,40,172,40,171,57,164,46,172,40,164,46,162,24,162,24,164,46,155,38,162,24,155,38,150,11,150,11,155,38,144,31,150,11,144,31,137,2,137,2,144,31,131,27,137,2,131,27,123,-2,123,-2,131,27,116,26,123,-2,116,26,107,-4,107,-4,116,26,102,28,107,-4,102,28,91,-3,91,-3,102,28,90,34,91,-3,90,34,81,45,81,45,76,59,77,1,81,45,77,1,91,-3,215,225,171,225,172,40,215,225,172,40,174,40,215,225,174,40,176,24,215,225,176,24,182,11,215,225,182,11,191,2,215,225,191,2,201,-2,215,225,201,-2,211,-4,215,225,211,-4,215,48,249,22,244,18,247,12,247,12,244,18,239,15,247,12,239,15,239,4,239,4,239,15,235,14,239,4,235,14,231,0,231,0,235,14,230,13,249,22,247,12,256,23,249,22,256,23,256,28,224,15,220,19,222,-3,224,15,222,-3,231,0,224,15,231,0,230,13,215,48,211,-4,215,36,215,36,211,-4,222,-3,215,36,222,-3,217,26,217,26,222,-3,220,19,48,14,48,-106,52,-6,52,-6,48,-106,55,-102,52,-6,55,-102,58,-29,58,-29,55,-102,60,-94,58,-29,60,-94,62,-51,62,-51,60,-94,63,-83,62,-51,63,-83,64,-69,46,32,48,-106,48,14, 266,-76,266,-65,247,-62,234,-58,227,-50,223,-38,222,-20,222,271,223,290,227,304,234,313,247,318,266,321,266,331,134,331,95,327,66,316,46,297,34,270,30,235,34,199,46,172,66,154,93,142,127,137,127,-14,126,-35,123,-49,115,-58,102,-63,83,-65,83,-76,160,-76,160,320,189,320,189,-76,16383,16383,127,147,105,153,88,164,77,182,70,206,68,237,70,266,75,289,86,305,103,315,127,320, 123,-49,115,-58,160,-76,160,-76,115,-58,102,-63,160,-76,102,-63,83,-65,134,331,95,327,103,315,134,331,103,315,127,320,134,331,127,320,127,137,134,331,127,137,160,-76,134,331,160,-76,160,320,134,331,160,320,266,331,127,320,127,147,127,137,105,153,88,164,93,142,93,142,88,164,77,182,93,142,77,182,66,154,66,154,77,182,70,206,66,154,70,206,68,237,68,237,70,266,66,316,66,316,70,266,75,289,66,316,75,289,95,327,95,327,75,289,86,305,95,327,86,305,103,315,66,316,46,297,46,172,66,316,46,172,66,154,66,316,66,154,68,237,247,318,266,321,266,331,247,318,266,331,234,313,234,313,266,331,189,320,234,313,189,320,227,304,227,304,189,320,223,290,234,-58,227,-50,189,-76,189,-76,227,-50,223,-38,189,-76,223,-38,189,320,189,320,223,-38,222,-20,189,320,222,-20,222,271,160,-76,127,137,127,-14,160,-76,127,-14,126,-35,160,-76,126,-35,123,-49,266,-76,266,-65,247,-62,266,-76,247,-62,234,-58,266,-76,234,-58,189,-76,105,153,93,142,127,137,105,153,127,137,127,147,34,199,46,172,46,297,34,199,46,297,34,270,34,199,34,270,30,235,160,-76,83,-65,83,-76,266,331,160,320,189,320,223,290,189,320,222,271, 90,127,89,135,85,143,79,149,71,154,63,155,54,154,46,150,40,144,37,136,35,127,37,118,40,111,46,105,54,101,63,99,71,101,79,105,85,111,89,118,90,127, 35,127,37,118,37,136,37,136,37,118,40,111,37,136,40,111,40,144,40,144,40,111,46,105,40,144,46,105,46,150,46,150,46,105,54,101,46,150,54,101,54,154,54,154,54,101,62,99,54,154,62,99,63,155,63,155,62,99,71,101,63,155,71,101,71,154,71,154,71,101,79,105,71,154,79,105,79,149,79,149,79,105,85,111,79,149,85,111,85,143,85,143,85,111,89,118,85,143,89,118,89,135,89,135,89,118,90,127, 87,0,70,0,49,-49,52,-51,55,-50,57,-50,60,-49,66,-49,76,-50,84,-52,89,-55,92,-60,93,-67,92,-74,88,-81,83,-85,75,-88,65,-89,59,-89,47,-87,40,-86,33,-83,26,-98,35,-102,51,-106,59,-106,68,-107,89,-105,107,-99,120,-91,128,-79,131,-64,129,-52,123,-43,114,-36,102,-32,88,-30,80,-30,77,-31,75,-31, 59,-106,68,-107,59,-89,59,-89,68,-107,65,-89,75,-88,65,-89,68,-107,75,-88,68,-107,89,-105,57,-50,60,-49,70,0,70,0,60,-49,63,-49,70,0,63,-49,66,-49,66,-49,76,-50,70,0,70,0,76,-50,75,-31,70,0,75,-31,87,0,70,0,49,-49,52,-51,70,0,52,-51,55,-50,70,0,55,-50,57,-50,131,-64,129,-52,128,-79,128,-79,129,-52,123,-43,128,-79,123,-43,120,-91,120,-91,123,-43,114,-36,120,-91,114,-36,107,-99,107,-99,114,-36,102,-32,107,-99,102,-32,93,-67,93,-67,102,-32,92,-60,89,-55,92,-60,102,-32,89,-55,102,-32,88,-30,89,-55,88,-30,85,-30,89,-55,85,-30,84,-52,84,-52,85,-30,82,-30,84,-52,82,-30,80,-30,84,-52,80,-30,77,-31,84,-52,77,-31,76,-50,107,-99,93,-67,92,-74,107,-99,92,-74,89,-105,89,-105,92,-74,88,-81,89,-105,88,-81,83,-85,33,-83,35,-102,40,-86,40,-86,35,-102,43,-104,40,-86,43,-104,47,-87,47,-87,43,-104,51,-106,47,-87,51,-106,53,-88,53,-88,51,-106,59,-106,53,-88,59,-106,59,-89,35,-102,33,-83,26,-98,75,-88,89,-105,83,-85,75,-31,76,-50,77,-31, 124,135,124,147,113,148,105,150,99,154,96,159,95,166,95,336,89,338,30,310,30,299,36,302,41,304,45,305,52,305,54,301,55,297,55,157,52,153,47,150,40,148,28,147,28,135, 52,153,47,150,124,135,124,135,47,150,40,148,124,135,40,148,28,147,41,304,45,305,89,338,89,338,45,305,48,305,89,338,48,305,50,305,50,305,52,305,89,338,89,338,52,305,53,303,89,338,53,303,54,301,113,148,105,150,124,135,124,135,105,150,99,154,124,135,99,154,55,164,55,164,99,154,96,159,55,164,96,159,55,291,55,297,55,291,89,338,55,297,89,338,54,301,36,302,41,304,89,338,36,302,89,338,30,310,36,302,30,310,30,299,95,166,95,336,89,338,95,166,89,338,55,291,95,166,55,291,96,159,55,157,52,153,124,135,55,157,124,135,55,164,124,135,28,147,28,135,113,148,124,135,124,147, 152,271,148,293,139,312,123,326,103,335,79,338,54,335,33,325,17,310,6,291,3,267,6,244,16,225,32,210,52,200,75,197,100,201,121,211,138,227,148,247,152,271,16383,16383,116,258,114,242,110,230,102,221,93,216,80,214,73,214,66,216,56,224,52,230,44,250,42,261,40,273,40,285,41,297,46,307,53,315,63,320,74,321,88,318,99,310,108,297,114,279,116,258, 44,250,52,200,48,240,48,240,52,200,52,230,56,224,52,230,52,200,56,224,52,200,75,197,42,261,40,273,33,325,42,261,33,325,32,210,42,261,32,210,52,200,42,261,52,200,44,250,33,325,40,285,41,297,33,325,41,297,54,335,54,335,41,297,46,307,54,335,46,307,53,315,3,267,6,244,6,291,6,291,6,244,16,225,6,291,16,225,17,310,17,310,16,225,32,210,17,310,32,210,33,325,103,335,79,338,88,318,88,318,79,338,74,321,63,320,74,321,79,338,63,320,79,338,54,335,114,242,110,230,121,211,121,211,110,230,102,221,121,211,102,221,100,201,100,201,102,221,93,216,100,201,93,216,80,214,80,214,73,214,75,197,75,197,73,214,66,216,75,197,66,216,61,220,152,271,148,293,148,247,148,247,148,293,139,312,148,247,139,312,138,227,138,227,139,312,123,326,138,227,123,326,121,211,121,211,123,326,116,258,88,318,99,310,103,335,103,335,99,310,108,297,103,335,108,297,123,326,123,326,108,297,114,279,123,326,114,279,116,258,80,214,75,197,100,201,54,335,53,315,63,320,114,242,121,211,116,258,56,224,75,197,61,220,33,325,40,273,40,285, 229,111,189,147,174,161,143,192,130,204,124,208,122,208,121,207,119,206,118,204,118,203,119,199,122,193,127,185,134,176,143,165,150,155,158,145,167,134,176,122,185,111,143,58,134,47,127,38,122,31,119,25,118,22,118,19,119,18,121,17,123,17,130,21,142,32,158,46,174,61,189,75,16383,16383,132,111,92,147,62,177,46,192,34,204,27,208,26,208,24,207,23,206,22,204,22,203,23,199,26,193,31,185,38,176,46,165,53,155,61,145,70,134,79,122,89,111,46,58,38,47,31,38,26,31,23,25,22,22,22,19,23,18,25,17,27,17,33,21,45,32,61,46,77,61,92,75, 92,75,132,111,92,147,92,75,92,147,89,111,92,75,89,111,77,61,53,155,61,145,62,177,62,177,61,145,70,134,62,177,70,134,78,161,78,161,70,134,79,122,78,161,79,122,92,147,92,147,79,122,89,111,53,155,62,177,46,165,46,165,62,177,46,192,46,165,46,192,38,176,38,176,46,192,34,204,38,176,34,204,31,185,31,185,34,204,27,208,31,185,27,208,26,193,26,193,27,208,26,208,26,193,26,208,24,207,23,206,22,204,23,199,23,206,23,199,26,193,23,206,26,193,24,207,189,75,229,111,189,147,189,75,189,147,185,111,189,75,185,111,174,61,150,155,158,145,158,177,158,177,158,145,167,134,158,177,167,134,174,161,174,161,167,134,176,122,174,161,176,122,189,147,189,147,176,122,185,111,150,155,158,177,143,165,143,165,158,177,143,192,143,165,143,192,134,176,134,176,143,192,130,204,134,176,130,204,127,185,127,185,130,204,124,208,127,185,124,208,122,208,122,193,127,185,122,208,122,193,122,208,121,207,122,193,121,207,119,206,122,193,119,206,119,199,118,204,118,203,119,199,118,204,119,199,119,206,119,18,121,17,122,31,122,31,121,17,123,17,122,31,123,17,127,38,127,38,123,17,130,21,127,38,130,21,134,47,134,47,130,21,142,32,134,47,142,32,143,58,143,58,142,32,158,46,143,58,158,46,185,111,185,111,158,46,174,61,119,25,118,22,118,20,119,25,118,20,118,19,119,25,118,19,119,18,119,25,119,18,122,31,23,18,25,17,26,31,26,31,25,17,27,17,26,31,27,17,31,38,31,38,27,17,33,21,31,38,33,21,38,47,38,47,33,21,45,32,38,47,45,32,46,58,46,58,45,32,61,46,46,58,61,46,89,111,89,111,61,46,77,61,23,25,22,22,22,20,23,25,22,20,22,19,23,25,22,19,23,18,23,25,23,18,26,31,23,199,22,204,22,203, 357,45,357,74,329,74,329,203,305,203,204,70,204,45,294,45,294,0,329,0,329,45,16383,16383,294,74,227,74,294,163,16383,16383,316,338,293,338,66,-6,91,-6,16383,16383,112,135,112,147,100,148,92,150,87,154,84,159,83,166,83,336,76,338,22,310,22,299,29,302,34,304,38,305,45,305,47,301,47,157,44,153,40,150,32,148,21,147,21,135, 204,45,294,45,204,70,204,70,294,45,227,74,204,70,227,74,305,203,305,203,227,74,294,163,305,203,294,163,329,0,329,0,294,163,294,74,329,0,294,74,294,45,294,45,294,74,227,74,305,203,329,0,329,203,329,74,329,45,357,45,329,74,357,45,357,74,293,338,66,-6,91,-6,293,338,91,-6,316,338,44,153,40,150,112,135,112,135,40,150,32,148,112,135,32,148,21,147,34,304,38,305,76,338,76,338,38,305,41,305,76,338,41,305,43,305,43,305,45,305,76,338,76,338,45,305,46,303,76,338,46,303,47,301,100,148,92,150,112,135,112,135,92,150,87,154,112,135,87,154,47,164,47,164,87,154,84,159,47,164,84,159,47,291,47,297,47,291,76,338,47,297,76,338,47,301,29,302,34,304,76,338,29,302,76,338,22,310,29,302,22,310,22,299,83,166,83,336,76,338,83,166,76,338,47,291,83,166,47,291,84,159,47,157,44,153,112,135,47,157,112,135,47,164,112,135,21,147,21,135,100,148,112,135,112,147,329,0,294,45,294,0, 371,42,362,46,357,40,352,36,346,34,340,33,333,32,276,32,318,73,335,91,347,106,355,120,360,134,361,148,358,166,350,181,337,193,320,200,298,203,275,201,257,194,243,182,232,165,223,143,235,136,243,149,251,159,259,167,269,171,280,173,291,171,301,166,308,158,313,147,315,135,313,125,308,112,301,98,290,82,276,66,225,12,225,0,351,0,16383,16383,297,338,275,338,48,-6,73,-6,16383,16383,108,135,108,147,97,148,89,150,84,154,81,159,80,166,80,336,73,338,19,310,19,299,26,302,31,304,35,305,42,305,44,301,44,297,45,291,45,164,44,157,41,153,37,150,29,148,18,147,18,135, 308,112,301,98,318,73,318,73,301,98,290,82,318,73,290,82,276,66,276,66,225,12,276,32,276,32,225,12,351,0,276,32,351,0,333,32,340,33,333,32,351,0,340,33,351,0,346,34,346,34,351,0,352,36,235,136,243,149,243,182,243,182,243,149,251,159,243,182,251,159,257,194,257,194,251,159,259,167,257,194,259,167,275,201,275,201,259,167,269,171,275,201,269,171,280,173,280,173,291,171,298,203,298,203,291,171,301,166,298,203,301,166,320,200,320,200,301,166,308,158,320,200,308,158,313,147,232,165,223,143,235,136,232,165,235,136,243,182,371,42,362,46,357,40,371,42,357,40,352,36,371,42,352,36,351,0,275,338,48,-6,73,-6,275,338,73,-6,297,338,41,153,37,150,108,135,108,135,37,150,29,148,108,135,29,148,18,147,31,304,35,305,73,338,73,338,35,305,38,305,73,338,38,305,40,305,40,305,42,305,73,338,73,338,42,305,43,303,73,338,43,303,44,301,97,148,89,150,108,135,108,135,89,150,84,154,108,135,84,154,45,164,45,164,84,154,81,159,45,164,81,159,45,291,44,297,45,291,73,338,44,297,73,338,44,301,26,302,31,304,73,338,26,302,73,338,19,310,26,302,19,310,19,299,80,166,80,336,73,338,80,166,73,338,45,291,80,166,45,291,81,159,313,125,318,73,315,135,315,135,318,73,320,200,320,200,318,73,335,91,320,200,335,91,337,193,337,193,335,91,347,106,337,193,347,106,350,181,350,181,347,106,355,120,350,181,355,120,358,166,358,166,355,120,360,134,358,166,360,134,361,148,320,200,313,147,315,135,298,203,275,201,280,173,276,66,276,32,318,73,44,157,41,153,108,135,44,157,108,135,45,164,108,135,18,147,18,135,97,148,108,135,108,147,308,112,318,73,313,125,351,0,225,12,225,0, 359,45,359,74,331,74,331,203,308,203,206,70,206,45,296,45,296,0,331,0,331,45,16383,16383,296,74,229,74,296,163,16383,16383,319,338,296,338,69,-6,94,-6,16383,16383,102,256,114,263,123,271,129,279,131,288,132,296,130,310,122,321,110,330,95,336,78,338,61,336,46,331,33,322,22,309,11,291,23,281,31,293,39,301,47,306,56,309,66,310,76,309,83,306,89,301,93,295,94,286,92,276,87,267,78,259,65,252,46,244,46,230,52,231,59,231,60,232,76,230,88,225,97,216,103,205,105,190,103,179,99,169,92,162,82,157,71,155,66,155,61,156,57,158,52,161,40,169,32,173,28,174,25,175,19,174,14,172,10,169,8,165,7,159,9,150,15,142,25,136,37,132,52,131,83,134,109,144,129,159,141,177,146,200,144,214,139,227,130,239,118,248,102,254, 206,45,296,45,206,70,206,70,296,45,229,74,206,70,229,74,308,203,308,203,229,74,296,163,308,203,296,163,331,0,331,0,296,163,296,74,331,0,296,74,296,45,296,45,296,74,229,74,308,203,331,0,331,203,331,74,331,45,359,45,331,74,359,45,359,74,296,338,69,-6,94,-6,296,338,94,-6,319,338,66,155,61,156,83,134,83,134,61,156,57,158,83,134,57,158,52,131,52,131,57,158,52,161,52,131,52,161,46,165,56,231,59,231,65,252,65,252,59,231,60,232,60,232,76,230,65,252,65,252,76,230,78,259,65,252,46,244,52,231,65,252,52,231,56,231,23,281,31,293,33,322,33,322,31,293,39,301,33,322,39,301,46,331,46,331,39,301,47,306,46,331,47,306,61,336,61,336,47,306,56,309,61,336,56,309,66,310,66,310,76,309,78,338,78,338,76,309,83,306,78,338,83,306,95,336,95,336,83,306,89,301,95,336,89,301,93,295,22,309,11,291,23,281,22,309,23,281,33,322,103,179,99,169,109,144,109,144,99,169,92,162,109,144,92,162,83,134,83,134,92,162,82,157,83,134,82,157,71,155,71,155,66,155,83,134,95,336,94,286,97,216,95,336,97,216,110,330,110,330,97,216,102,256,110,330,102,256,114,263,78,338,61,336,66,310,130,310,122,321,123,271,130,310,123,271,129,279,130,310,129,279,131,288,130,310,131,288,132,296,122,321,110,330,114,263,122,321,114,263,123,271,102,254,102,256,97,216,102,254,97,216,103,205,102,254,103,205,118,248,92,276,87,267,88,225,92,276,88,225,97,216,92,276,97,216,94,286,78,259,76,230,88,225,78,259,88,225,87,267,141,177,146,200,144,214,141,177,144,214,139,227,141,177,139,227,130,239,141,177,130,239,129,159,103,179,109,144,105,190,105,190,109,144,118,248,118,248,109,144,129,159,118,248,129,159,130,239,105,190,118,248,103,205,40,169,36,171,37,132,40,169,37,132,52,131,40,169,52,131,46,165,37,132,36,171,32,173,37,132,32,173,28,174,37,132,28,174,25,175,37,132,25,175,25,136,19,174,14,172,15,142,19,174,15,142,25,136,19,174,25,136,25,175,10,169,8,165,9,150,10,169,9,150,15,142,10,169,15,142,14,172,52,231,46,244,46,230,9,150,8,165,7,159,95,336,93,295,94,286,331,0,296,45,296,0, 130,208,129,216,125,223,119,229,112,232,103,233,95,232,87,229,82,223,78,217,77,208,78,199,82,192,87,186,95,182,103,180,112,182,119,186,125,192,129,199,130,208,16383,16383,100,147,96,128,91,112,85,97,77,84,68,70,46,42,31,20,22,2,17,-13,15,-30,16,-42,18,-52,22,-62,27,-71,33,-79,45,-89,58,-97,74,-103,90,-107,107,-108,133,-104,155,-94,173,-79,184,-59,188,-35,187,-24,184,-16,179,-10,173,-6,164,-5,157,-5,151,-8,147,-12,144,-18,143,-25,145,-33,147,-37,150,-42,154,-46,160,-54,161,-57,162,-59,162,-62,160,-71,153,-80,142,-87,130,-91,116,-93,98,-90,83,-81,71,-69,64,-52,61,-34,62,-19,64,-4,67,11,72,27,79,44,93,75,101,99,106,118,108,133,108,147, 103,180,112,182,112,232,112,232,112,182,119,186,112,232,119,186,119,229,119,229,119,186,125,192,119,229,125,192,125,223,125,223,125,192,129,199,125,223,129,199,129,216,129,216,129,199,130,208,78,217,78,199,82,223,82,223,78,199,82,192,82,223,82,192,87,229,87,229,82,192,87,186,87,229,87,186,95,232,95,232,87,186,95,182,95,232,95,182,103,233,103,233,95,182,103,180,103,233,103,180,112,232,72,27,79,44,77,84,72,27,77,84,68,70,68,70,46,42,62,-19,62,-19,46,42,61,-34,64,-52,61,-34,58,-97,64,-52,58,-97,74,-103,68,70,62,-19,64,-4,68,70,64,-4,67,11,68,70,67,11,72,27,33,-79,45,-89,46,42,46,42,45,-89,58,-97,46,42,58,-97,61,-34,31,20,22,2,22,-62,31,20,22,-62,27,-71,31,20,27,-71,33,-79,31,20,33,-79,46,42,15,-30,16,-42,17,-13,17,-13,16,-42,18,-52,17,-13,18,-52,22,2,22,2,18,-52,22,-62,108,147,100,147,101,99,108,147,101,99,106,118,108,147,106,118,108,133,96,128,91,112,93,75,96,128,93,75,101,99,96,128,101,99,100,147,85,97,77,84,79,44,85,97,79,44,93,75,85,97,93,75,91,112,160,-71,153,-80,155,-94,155,-94,153,-80,142,-87,155,-94,142,-87,133,-104,133,-104,142,-87,130,-91,133,-104,130,-91,116,-93,116,-93,98,-90,107,-108,107,-108,98,-90,90,-107,83,-81,71,-69,74,-103,83,-81,74,-103,90,-107,83,-81,90,-107,98,-90,147,-37,150,-42,151,-8,151,-8,150,-42,154,-46,151,-8,154,-46,157,-5,157,-5,154,-46,157,-50,157,-5,157,-50,164,-5,164,-5,157,-50,160,-54,164,-5,160,-54,161,-57,143,-25,144,-29,144,-18,144,-18,144,-29,145,-33,144,-18,145,-33,147,-12,147,-12,145,-33,147,-37,147,-12,147,-37,151,-8,173,-6,173,-79,179,-10,179,-10,173,-79,184,-59,179,-10,184,-59,184,-16,184,-16,184,-59,188,-35,184,-16,188,-35,187,-24,155,-94,173,-79,160,-71,160,-71,173,-79,162,-62,164,-5,162,-62,173,-79,164,-5,173,-79,173,-6,116,-93,107,-108,133,-104,164,-5,161,-57,162,-59,164,-5,162,-59,162,-62,64,-52,74,-103,71,-69,78,199,78,217,77,208, 225,378,153,453,148,457,144,460,140,462,132,464,125,463,120,461,117,458,114,454,113,448,114,443,116,439,119,434,123,430,128,426,205,378,16383,16383,353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 205,378,225,378,153,453,205,378,153,453,148,457,205,378,148,457,144,460,205,378,144,460,140,462,205,378,140,462,136,463,205,378,136,463,132,464,205,378,132,464,128,426,113,448,114,443,114,454,114,454,114,443,116,439,114,454,116,439,117,458,117,458,116,439,119,434,117,458,119,434,120,461,120,461,119,434,123,430,120,461,123,430,125,463,125,463,123,430,128,426,125,463,128,426,132,464,55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0, 138,378,158,378,235,427,245,435,248,439,249,443,250,448,249,454,247,458,243,461,239,463,233,464,228,463,224,462,221,460,216,457,211,453,16383,16383,353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 233,464,235,427,239,463,239,463,235,427,240,431,239,463,240,431,243,461,243,461,240,431,245,435,243,461,245,435,247,458,247,458,245,435,248,439,247,458,248,439,249,454,249,454,248,439,249,443,249,454,249,443,250,448,235,427,233,464,228,463,235,427,228,463,224,462,235,427,224,462,221,460,235,427,221,460,216,457,235,427,216,457,211,453,235,427,211,453,158,378,55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0,158,378,211,453,138,378, 257,378,194,462,163,462,101,378,118,378,179,430,239,378,16383,16383,353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 101,378,118,378,163,462,163,462,118,378,179,430,163,462,179,430,194,462,194,462,179,430,239,378,194,462,239,378,257,378,55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0, 248,444,243,434,238,427,233,422,227,420,221,419,216,419,211,420,206,422,200,424,195,426,182,432,175,436,161,440,154,441,147,441,133,439,121,433,111,423,103,409,97,391,112,391,115,399,120,406,125,410,131,413,137,414,141,414,149,412,157,408,169,403,180,398,189,394,196,392,202,391,209,391,224,393,237,399,247,409,255,424,262,444,16383,16383,353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 115,399,120,406,121,433,121,433,120,406,125,410,121,433,125,410,133,439,133,439,125,410,131,413,133,439,131,413,137,414,137,414,141,414,147,441,147,441,141,414,145,413,147,441,145,413,149,412,112,391,115,399,121,433,112,391,121,433,111,423,112,391,111,423,103,409,112,391,103,409,97,391,147,441,149,412,154,441,154,441,149,412,153,410,154,441,153,410,157,408,157,408,169,403,161,440,161,440,169,403,168,438,147,441,133,439,137,414,161,440,154,441,157,408,168,438,169,403,175,436,175,436,169,403,180,398,175,436,180,398,182,432,182,432,180,398,189,394,182,432,189,394,195,426,195,426,189,394,196,392,195,426,196,392,200,424,200,424,196,392,202,391,200,424,202,391,206,422,206,422,202,391,209,391,206,422,209,391,211,420,211,420,209,391,224,393,211,420,224,393,216,419,216,419,224,393,221,419,227,420,221,419,224,393,227,420,224,393,237,399,248,444,243,434,247,409,248,444,247,409,255,424,248,444,255,424,262,444,238,427,233,422,237,399,238,427,237,399,247,409,238,427,247,409,243,434,55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0,227,420,237,399,233,422, 254,411,253,419,249,426,244,431,237,435,229,436,221,435,214,431,209,426,206,419,204,411,205,403,209,397,214,391,221,388,228,387,236,388,244,391,249,397,253,403,254,411,16383,16383,155,411,153,419,150,426,144,431,137,435,129,436,122,435,115,431,110,426,106,419,105,411,106,403,110,397,115,391,121,388,129,387,137,388,144,391,150,397,153,403,155,411,16383,16383,353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 204,411,205,403,206,419,206,419,205,403,209,397,206,419,209,397,209,426,209,426,209,397,214,391,209,426,214,391,214,431,214,431,214,391,221,388,214,431,221,388,221,435,221,435,221,388,228,387,221,435,228,387,229,436,229,436,228,387,236,388,229,436,236,388,237,435,237,435,236,388,244,391,237,435,244,391,244,431,244,431,244,391,249,397,244,431,249,397,249,426,249,426,249,397,253,403,249,426,253,403,253,419,253,419,253,403,254,411,105,411,106,403,106,419,106,419,106,403,110,397,106,419,110,397,110,426,110,426,110,397,115,391,110,426,115,391,115,431,115,431,115,391,121,388,115,431,121,388,122,435,122,435,121,388,129,387,122,435,129,387,129,436,129,436,129,387,137,388,129,436,137,388,137,435,137,435,137,388,144,391,137,435,144,391,144,431,144,431,144,391,150,397,144,431,150,397,150,426,150,426,150,397,153,403,150,426,153,403,153,419,153,419,153,403,155,411,55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0, 229,430,227,446,220,460,209,471,196,478,180,480,164,478,151,471,140,460,133,447,130,431,132,415,139,401,150,391,163,384,179,381,195,384,209,391,220,401,227,415,229,430,16383,16383,213,431,211,420,206,411,199,404,190,400,179,398,169,400,160,404,153,411,148,420,147,431,148,441,153,450,160,457,169,462,179,464,190,462,199,457,206,450,211,441,213,431,16383,16383,353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,23,259,21,258,18,256,16,250,12,242,10,235,10,226,9,226,0,16383,16383,224,128,108,128,166,266, 211,420,206,411,209,391,209,391,206,411,199,404,209,391,199,404,195,384,195,384,199,404,190,400,195,384,190,400,179,381,179,381,190,400,179,398,180,480,179,464,190,462,180,480,190,462,196,478,196,478,190,462,199,457,196,478,199,457,209,471,209,471,199,457,206,450,209,471,206,450,211,441,229,430,227,446,227,415,227,415,227,446,220,460,227,415,220,460,220,401,220,401,220,460,213,431,211,441,213,431,220,460,211,441,220,460,209,471,211,420,209,391,220,401,211,420,220,401,213,431,153,450,160,457,164,478,164,478,160,457,169,462,164,478,169,462,180,480,180,480,169,462,179,464,151,471,140,460,147,431,151,471,147,431,148,441,151,471,148,441,153,450,151,471,153,450,164,478,153,411,148,420,150,391,150,391,148,420,147,431,169,400,160,404,163,384,169,400,163,384,179,381,169,400,179,381,179,398,153,411,150,391,163,384,153,411,163,384,160,404,130,431,132,415,133,447,133,447,132,415,139,401,133,447,139,401,140,460,140,460,139,401,150,391,140,460,150,391,147,431,55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,246,11,242,10,353,0,353,0,242,10,235,10,353,0,235,10,226,9,259,21,258,18,353,0,353,0,258,18,256,16,353,0,256,16,253,14,253,14,250,12,353,0,353,0,250,12,246,11,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,23,259,21,353,0,260,23,353,0,261,26,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58,353,0,226,9,226,0, 431,84,420,84,404,56,389,37,372,26,349,20,320,19,268,19,257,22,252,26,249,34,248,47,248,165,319,165,337,163,350,158,360,149,366,135,370,114,381,114,381,232,370,232,367,211,359,197,346,189,326,184,300,183,248,183,248,295,249,301,251,306,253,310,257,312,262,313,305,313,341,312,367,308,382,299,392,283,397,261,408,261,408,331,126,331,126,321,143,320,155,318,164,315,169,310,171,305,171,302,170,300,168,294,166,291,44,49,36,33,28,23,21,16,11,12,0,9,0,0,99,0,99,9,87,11,77,13,70,16,66,20,65,24,66,33,71,48,80,68,93,95,111,130,199,130,199,56,198,39,195,27,189,18,179,13,164,11,155,9,155,0,410,0,16383,16383,199,150,120,150,199,309, 87,11,77,13,99,0,99,0,77,13,70,16,99,0,70,16,36,33,36,33,70,16,66,20,36,33,66,20,44,49,44,49,66,20,65,24,71,48,80,68,166,291,166,291,80,68,93,95,166,291,93,95,111,130,111,130,199,130,120,150,120,150,199,130,199,150,195,27,189,18,410,0,410,0,189,18,179,13,410,0,179,13,164,11,166,291,111,130,120,150,166,291,120,150,199,309,166,291,199,309,168,294,262,313,408,331,199,309,199,309,408,331,169,310,199,309,169,310,171,305,171,305,171,302,199,309,199,309,171,302,170,300,199,309,170,300,169,297,360,149,366,135,367,211,367,211,366,135,370,114,367,211,370,114,370,232,370,232,370,114,381,114,370,232,381,114,381,232,300,183,319,165,326,184,326,184,319,165,337,163,326,184,337,163,346,189,346,189,337,163,350,158,346,189,350,158,359,197,359,197,350,158,360,149,359,197,360,149,367,211,199,309,249,34,248,47,248,183,248,165,319,165,248,183,319,165,300,183,408,331,262,313,305,313,408,331,305,313,341,312,408,331,341,312,367,308,408,331,367,308,382,299,408,331,382,299,392,283,408,331,392,283,397,261,408,331,397,261,408,261,199,309,248,47,248,295,199,309,248,295,249,301,199,309,249,301,251,306,199,309,251,306,253,310,199,309,253,310,257,312,199,309,257,312,262,313,408,331,126,331,143,320,408,331,143,320,155,318,408,331,155,318,164,315,408,331,164,315,169,310,389,37,372,26,410,0,410,0,372,26,349,20,410,0,349,20,320,19,410,0,431,84,420,84,410,0,420,84,404,56,410,0,404,56,389,37,199,56,198,39,257,22,257,22,198,39,195,27,257,22,195,27,268,19,268,19,195,27,410,0,268,19,410,0,283,19,283,19,410,0,320,19,199,150,199,130,252,26,199,150,252,26,249,34,199,150,249,34,199,309,199,56,257,22,252,26,199,56,252,26,199,130,155,9,155,0,410,0,155,9,410,0,164,11,44,49,65,24,66,33,44,49,66,33,71,48,44,49,71,48,166,291,99,0,36,33,28,23,99,0,28,23,21,16,99,0,21,16,11,12,99,0,11,12,0,9,99,0,0,9,0,0,87,11,99,0,99,9,168,294,199,309,169,297,143,320,126,331,126,321, 307,65,285,47,264,32,242,23,220,17,196,15,175,17,155,21,137,29,120,40,105,54,93,72,84,94,77,118,73,145,72,173,77,222,93,262,118,292,151,311,191,318,221,313,249,300,272,280,289,255,299,225,310,225,305,338,295,338,293,332,285,324,280,322,275,321,271,322,268,322,263,323,259,325,254,326,240,330,225,334,210,336,196,338,181,338,160,337,140,333,120,327,101,319,84,308,59,287,40,262,25,233,17,200,14,165,16,135,21,107,30,82,43,60,58,41,73,27,90,15,109,6,129,0,151,-4,132,-49,136,-51,139,-50,141,-50,144,-49,150,-49,160,-50,168,-52,173,-55,175,-60,176,-67,175,-74,172,-81,166,-85,158,-88,149,-89,143,-89,131,-87,124,-86,117,-83,109,-98,118,-102,134,-106,142,-106,151,-107,173,-105,190,-99,203,-91,211,-79,214,-64,212,-52,206,-43,198,-36,186,-32,171,-30,163,-30,161,-31,158,-31,168,-6,180,-6,213,-4,244,3,272,16,297,34,316,56, 84,94,77,118,90,15,90,15,77,118,73,145,90,15,73,145,73,27,73,27,73,145,72,173,59,287,72,173,84,308,158,-31,175,17,155,21,158,-31,155,21,151,-4,151,-4,155,21,137,29,151,-4,137,29,129,0,129,0,137,29,120,40,129,0,120,40,109,6,109,6,120,40,105,54,142,-106,151,-107,143,-89,143,-89,151,-107,149,-89,158,-88,149,-89,151,-107,158,-88,151,-107,173,-105,141,-50,144,-49,151,-4,151,-4,144,-49,147,-49,151,-4,147,-49,150,-49,150,-49,160,-50,151,-4,151,-4,132,-49,136,-51,151,-4,136,-51,139,-50,151,-4,139,-50,141,-50,196,15,178,-6,180,-6,196,15,180,-6,213,-4,196,15,175,17,175,-6,196,15,175,-6,178,-6,175,17,158,-31,168,-6,175,17,168,-6,171,-6,175,17,171,-6,173,-6,175,17,173,-6,175,-6,316,56,307,65,297,34,297,34,307,65,285,47,297,34,285,47,272,16,272,16,285,47,264,32,272,16,264,32,244,3,244,3,264,32,242,23,244,3,242,23,220,17,220,17,196,15,213,-4,220,17,213,-4,244,3,191,318,181,338,160,337,191,318,160,337,151,311,191,318,196,338,181,338,72,173,77,222,84,308,84,308,77,222,93,262,84,308,93,262,101,319,101,319,93,262,118,292,101,319,118,292,120,327,120,327,118,292,151,311,120,327,151,311,140,333,140,333,151,311,160,337,210,336,221,313,225,334,225,334,221,313,249,300,225,334,249,300,240,330,240,330,249,300,254,326,221,313,210,336,196,338,221,313,196,338,191,318,289,328,285,324,289,255,289,255,285,324,280,322,289,255,280,322,275,321,275,321,271,322,272,280,272,280,271,322,268,322,272,280,268,322,263,323,272,280,263,323,259,325,272,280,259,325,254,326,272,280,254,326,249,300,299,225,310,225,305,338,299,225,305,338,295,338,299,225,295,338,293,332,299,225,293,332,289,255,275,321,272,280,289,255,214,-64,212,-52,211,-79,211,-79,212,-52,206,-43,211,-79,206,-43,203,-91,203,-91,206,-43,198,-36,203,-91,198,-36,190,-99,190,-99,198,-36,186,-32,190,-99,186,-32,176,-67,176,-67,186,-32,175,-60,173,-55,175,-60,186,-32,173,-55,186,-32,171,-30,173,-55,171,-30,168,-30,173,-55,168,-30,168,-52,168,-52,168,-30,166,-30,168,-52,166,-30,163,-30,168,-52,163,-30,161,-31,168,-52,161,-31,160,-50,158,-31,151,-4,160,-50,158,-31,160,-50,161,-31,190,-99,176,-67,175,-74,190,-99,175,-74,173,-105,173,-105,175,-74,172,-81,173,-105,172,-81,166,-85,117,-83,118,-102,124,-86,124,-86,118,-102,126,-104,124,-86,126,-104,131,-87,131,-87,126,-104,134,-106,131,-87,134,-106,137,-88,137,-88,134,-106,142,-106,137,-88,142,-106,143,-89,93,72,84,94,90,15,93,72,90,15,109,6,93,72,109,6,105,54,59,287,40,262,43,60,59,287,43,60,58,41,59,287,58,41,73,27,59,287,73,27,72,173,14,165,16,135,17,200,17,200,16,135,21,107,17,200,21,107,25,233,25,233,21,107,30,82,25,233,30,82,40,262,40,262,30,82,43,60,118,-102,117,-83,109,-98,158,-88,173,-105,166,-85,289,328,289,255,293,332, 201,378,128,453,124,457,119,460,115,462,107,464,101,463,96,461,92,458,90,454,89,448,89,443,91,439,94,434,104,426,181,378,16383,16383,299,84,285,84,271,57,255,38,234,26,206,20,169,18,151,18,132,19,117,21,108,25,102,31,100,42,100,164,176,164,198,162,213,158,222,150,229,136,233,115,244,115,244,232,233,232,229,212,222,198,213,190,198,185,176,184,100,184,100,294,101,302,103,307,106,310,111,312,184,312,213,311,234,306,247,297,255,282,261,259,273,259,271,331,6,331,6,321,25,320,38,315,45,307,49,294,50,275,50,57,49,37,45,24,38,16,25,12,6,9,6,0,276,0, 181,378,201,378,128,453,181,378,128,453,124,457,181,378,124,457,119,460,181,378,119,460,115,462,181,378,115,462,111,463,181,378,111,463,107,464,181,378,107,464,104,426,89,448,89,443,90,454,90,454,89,443,91,439,90,454,91,439,92,458,92,458,91,439,94,434,92,458,94,434,96,461,96,461,94,434,99,430,96,461,99,430,101,463,101,463,99,430,104,426,101,463,104,426,107,464,45,24,38,16,276,0,276,0,38,16,25,12,276,0,25,12,6,9,49,294,50,275,106,310,49,294,106,310,45,307,45,307,106,310,111,312,45,307,111,312,271,331,271,331,111,312,118,312,45,24,117,21,49,37,49,37,117,21,108,25,49,37,108,25,50,57,50,57,108,25,102,31,50,57,102,31,50,275,50,275,102,31,100,42,50,275,100,42,100,294,100,184,100,164,176,164,100,184,176,164,176,184,198,185,176,184,198,162,198,185,198,162,213,190,213,190,198,162,213,158,213,190,213,158,222,198,222,198,213,158,222,150,222,198,222,150,229,212,229,212,222,150,229,136,229,212,229,136,233,232,233,232,229,136,233,115,233,232,233,115,244,115,271,331,118,312,184,312,271,331,184,312,213,311,271,331,213,311,234,306,271,331,234,306,247,297,271,331,247,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,50,275,100,294,101,302,50,275,101,302,103,307,50,275,103,307,106,310,271,331,6,331,25,320,271,331,25,320,38,315,271,331,38,315,45,307,255,38,234,26,276,0,276,0,234,26,206,20,276,0,206,20,169,18,276,0,299,84,285,84,276,0,285,84,271,57,276,0,271,57,255,38,276,0,169,18,151,18,276,0,151,18,132,19,276,0,132,19,117,21,276,0,117,21,45,24,276,0,6,9,6,0,25,320,6,331,6,321,176,184,176,164,198,162,233,232,244,115,244,232, 123,378,142,378,219,427,225,431,229,435,232,439,234,443,234,454,231,458,228,461,223,463,217,464,209,462,205,460,201,457,196,453,16383,16383,299,84,285,84,271,57,255,38,234,26,206,20,169,18,151,18,132,19,117,21,108,25,102,31,100,42,100,164,176,164,198,162,213,158,222,150,229,136,233,115,244,115,244,232,233,232,229,212,222,198,213,190,198,185,176,184,100,184,100,294,101,302,103,307,106,310,111,312,184,312,213,311,234,306,247,297,255,282,261,259,273,259,271,331,6,331,6,321,25,320,38,315,45,307,49,294,50,275,50,57,49,37,45,24,38,16,25,12,6,9,6,0,276,0, 217,464,219,427,223,463,223,463,219,427,225,431,223,463,225,431,228,461,228,461,225,431,229,435,228,461,229,435,231,458,231,458,229,435,232,439,231,458,232,439,234,454,234,454,232,439,234,443,234,454,234,443,234,448,219,427,217,464,213,463,219,427,213,463,209,462,219,427,209,462,205,460,219,427,205,460,201,457,219,427,201,457,196,453,219,427,196,453,142,378,45,24,38,16,276,0,276,0,38,16,25,12,276,0,25,12,6,9,49,294,50,275,106,310,49,294,106,310,45,307,45,307,106,310,111,312,45,307,111,312,271,331,271,331,111,312,118,312,45,24,117,21,49,37,49,37,117,21,108,25,49,37,108,25,50,57,50,57,108,25,102,31,50,57,102,31,50,275,50,275,102,31,100,42,50,275,100,42,100,294,100,184,100,164,176,164,100,184,176,164,176,184,198,185,176,184,198,162,198,185,198,162,213,190,213,190,198,162,213,158,213,190,213,158,222,198,222,198,213,158,222,150,222,198,222,150,229,212,229,212,222,150,229,136,229,212,229,136,233,232,233,232,229,136,233,115,233,232,233,115,244,115,271,331,118,312,184,312,271,331,184,312,213,311,271,331,213,311,234,306,271,331,234,306,247,297,271,331,247,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,50,275,100,294,101,302,50,275,101,302,103,307,50,275,103,307,106,310,271,331,6,331,25,320,271,331,25,320,38,315,271,331,38,315,45,307,255,38,234,26,276,0,276,0,234,26,206,20,276,0,206,20,169,18,276,0,299,84,285,84,276,0,285,84,271,57,276,0,271,57,255,38,276,0,169,18,151,18,276,0,151,18,132,19,276,0,132,19,117,21,276,0,117,21,45,24,276,0,6,9,6,0,25,320,6,331,6,321,176,184,176,164,198,162,233,232,244,115,244,232,142,378,196,453,123,378, 242,378,179,462,148,462,86,378,103,378,164,430,224,378,16383,16383,299,84,285,84,271,57,255,38,234,26,206,20,169,18,151,18,132,19,117,21,108,25,102,31,100,42,100,164,176,164,198,162,213,158,222,150,229,136,233,115,244,115,244,232,233,232,229,212,222,198,213,190,198,185,176,184,100,184,100,294,101,302,103,307,106,310,111,312,184,312,213,311,234,306,247,297,255,282,261,259,273,259,271,331,6,331,6,321,25,320,38,315,45,307,49,294,50,275,50,57,49,37,45,24,38,16,25,12,6,9,6,0,276,0, 86,378,103,378,148,462,148,462,103,378,164,430,148,462,164,430,179,462,179,462,164,430,224,378,179,462,224,378,242,378,45,24,38,16,276,0,276,0,38,16,25,12,276,0,25,12,6,9,49,294,50,275,106,310,49,294,106,310,45,307,45,307,106,310,111,312,45,307,111,312,271,331,271,331,111,312,118,312,45,24,117,21,49,37,49,37,117,21,108,25,49,37,108,25,50,57,50,57,108,25,102,31,50,57,102,31,50,275,50,275,102,31,100,42,50,275,100,42,100,294,100,184,100,164,176,164,100,184,176,164,176,184,198,185,176,184,198,162,198,185,198,162,213,190,213,190,198,162,213,158,213,190,213,158,222,198,222,198,213,158,222,150,222,198,222,150,229,212,229,212,222,150,229,136,229,212,229,136,233,232,233,232,229,136,233,115,233,232,233,115,244,115,271,331,118,312,184,312,271,331,184,312,213,311,271,331,213,311,234,306,271,331,234,306,247,297,271,331,247,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,50,275,100,294,101,302,50,275,101,302,103,307,50,275,103,307,106,310,271,331,6,331,25,320,271,331,25,320,38,315,271,331,38,315,45,307,255,38,234,26,276,0,276,0,234,26,206,20,276,0,206,20,169,18,276,0,299,84,285,84,276,0,285,84,271,57,276,0,271,57,255,38,276,0,169,18,151,18,276,0,151,18,132,19,276,0,132,19,117,21,276,0,117,21,45,24,276,0,6,9,6,0,25,320,6,331,6,321,176,184,176,164,198,162,233,232,244,115,244,232, 238,411,236,419,233,426,227,431,220,435,213,436,205,435,198,431,193,426,189,419,188,411,189,403,193,397,198,391,204,388,212,387,220,388,227,391,233,397,236,403,238,411,16383,16383,138,411,137,419,133,426,128,431,121,435,113,436,105,435,98,431,93,426,90,419,89,411,90,403,93,397,98,391,105,388,113,387,121,388,128,391,133,397,137,403,138,411,16383,16383,299,84,285,84,271,57,255,38,234,26,206,20,169,18,151,18,132,19,117,21,108,25,102,31,100,42,100,164,176,164,198,162,213,158,222,150,229,136,233,115,244,115,244,232,233,232,229,212,222,198,213,190,198,185,176,184,100,184,100,294,101,302,103,307,106,310,111,312,184,312,213,311,234,306,247,297,255,282,261,259,273,259,271,331,6,331,6,321,25,320,38,315,45,307,49,294,50,275,50,57,49,37,45,24,38,16,25,12,6,9,6,0,276,0, 113,436,113,387,121,435,121,435,113,387,121,388,121,435,121,388,128,431,128,431,121,388,128,391,128,431,128,391,133,426,133,426,128,391,133,397,133,426,133,397,137,419,137,419,133,397,137,403,137,419,137,403,138,411,89,411,90,403,90,419,90,419,90,403,93,397,90,419,93,397,93,426,93,426,93,397,98,391,93,426,98,391,98,431,98,431,98,391,105,388,98,431,105,388,105,435,105,435,105,388,113,387,105,435,113,387,113,436,45,24,38,16,276,0,276,0,38,16,25,12,276,0,25,12,6,9,49,294,50,275,106,310,49,294,106,310,45,307,45,307,106,310,111,312,45,307,111,312,271,331,271,331,111,312,118,312,188,411,189,403,189,419,189,419,189,403,193,397,189,419,193,397,193,426,193,426,193,397,198,391,193,426,198,391,198,431,198,431,198,391,204,388,198,431,204,388,205,435,205,435,204,388,212,387,205,435,212,387,213,436,213,436,212,387,220,388,213,436,220,388,220,435,220,435,220,388,227,391,220,435,227,391,227,431,227,431,227,391,233,397,227,431,233,397,233,426,233,426,233,397,236,403,233,426,236,403,236,419,236,419,236,403,238,411,45,24,117,21,49,37,49,37,117,21,108,25,49,37,108,25,50,57,50,57,108,25,102,31,50,57,102,31,50,275,50,275,102,31,100,42,50,275,100,42,100,294,100,184,100,164,176,164,100,184,176,164,176,184,198,185,176,184,198,162,198,185,198,162,213,190,213,190,198,162,213,158,213,190,213,158,222,198,222,198,213,158,222,150,222,198,222,150,229,212,229,212,222,150,229,136,229,212,229,136,233,232,233,232,229,136,233,115,233,232,233,115,244,115,271,331,118,312,184,312,271,331,184,312,213,311,271,331,213,311,234,306,271,331,234,306,247,297,271,331,247,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,50,275,100,294,101,302,50,275,101,302,103,307,50,275,103,307,106,310,271,331,6,331,25,320,271,331,25,320,38,315,271,331,38,315,45,307,255,38,234,26,276,0,276,0,234,26,206,20,276,0,206,20,169,18,276,0,299,84,285,84,276,0,285,84,271,57,276,0,271,57,255,38,276,0,169,18,151,18,276,0,151,18,132,19,276,0,132,19,117,21,276,0,117,21,45,24,276,0,6,9,6,0,25,320,6,331,6,321,176,184,176,164,198,162,233,232,244,115,244,232, 134,378,62,453,57,457,53,460,49,462,41,464,35,463,29,461,26,458,23,454,22,448,23,443,25,439,28,434,32,430,37,426,114,378,16383,16383,157,0,157,9,137,11,122,16,114,24,109,37,108,56,108,276,109,295,113,308,122,316,136,320,157,321,157,331,9,331,9,321,30,320,44,316,53,308,57,295,57,56,56,36,52,23,44,15,30,11,9,9,9,0, 114,378,134,378,62,453,114,378,62,453,57,457,114,378,57,457,53,460,114,378,53,460,49,462,114,378,49,462,45,463,114,378,45,463,41,464,114,378,41,464,37,426,22,448,23,443,23,454,23,454,23,443,25,439,23,454,25,439,26,458,26,458,25,439,28,434,26,458,28,434,29,461,29,461,28,434,32,430,29,461,32,430,35,463,35,463,32,430,37,426,35,463,37,426,41,464,52,23,44,15,157,0,157,0,44,15,30,11,157,0,30,11,9,9,157,331,9,331,30,320,157,331,30,320,44,316,157,331,44,316,53,308,157,331,53,308,57,295,157,331,57,295,122,316,157,331,122,316,136,320,157,331,136,320,157,321,122,16,114,24,57,56,57,56,114,24,109,37,57,56,109,37,57,276,57,276,109,37,108,56,57,276,108,56,108,276,57,276,108,276,109,295,57,276,109,295,113,308,57,276,113,308,122,316,57,276,122,316,57,295,157,0,157,9,137,11,157,0,137,11,122,16,157,0,122,16,56,36,157,0,56,36,52,23,157,0,9,9,9,0,56,36,122,16,57,56,30,320,9,331,9,321, 32,378,52,378,129,427,139,435,142,439,143,443,144,448,143,454,141,458,137,461,133,463,127,464,122,463,118,462,115,460,110,457,105,453,16383,16383,157,0,157,9,137,11,122,16,114,24,109,37,108,56,108,276,109,295,113,308,122,316,136,320,157,321,157,331,9,331,9,321,30,320,44,316,53,308,57,295,57,56,56,36,52,23,44,15,30,11,9,9,9,0, 127,464,129,427,133,463,133,463,129,427,134,431,133,463,134,431,137,461,137,461,134,431,139,435,137,461,139,435,141,458,141,458,139,435,142,439,141,458,142,439,143,454,143,454,142,439,143,443,143,454,143,443,144,448,129,427,127,464,122,463,129,427,122,463,118,462,129,427,118,462,115,460,129,427,115,460,110,457,129,427,110,457,105,453,129,427,105,453,52,378,52,23,44,15,157,0,157,0,44,15,30,11,157,0,30,11,9,9,157,331,9,331,30,320,157,331,30,320,44,316,157,331,44,316,53,308,157,331,53,308,57,295,157,331,57,295,122,316,157,331,122,316,136,320,157,331,136,320,157,321,122,16,114,24,57,56,57,56,114,24,109,37,57,56,109,37,57,276,57,276,109,37,108,56,57,276,108,56,108,276,57,276,108,276,109,295,57,276,109,295,113,308,57,276,113,308,122,316,57,276,122,316,57,295,157,0,157,9,137,11,157,0,137,11,122,16,157,0,122,16,56,36,157,0,56,36,52,23,157,0,9,9,9,0,56,36,122,16,57,56,30,320,9,331,9,321,52,378,105,453,32,378, 161,378,98,462,67,462,5,378,22,378,83,430,143,378,16383,16383,153,0,153,9,133,11,119,16,110,24,106,37,104,56,104,276,105,295,110,308,118,316,132,320,153,321,153,331,5,331,5,321,26,320,40,316,49,308,53,295,54,276,54,56,53,36,49,23,40,15,26,11,5,9,5,0, 5,378,22,378,67,462,67,462,22,378,83,430,67,462,83,430,98,462,98,462,83,430,143,378,98,462,143,378,161,378,49,23,40,15,153,0,153,0,40,15,26,11,153,0,26,11,5,9,153,331,5,331,26,320,153,331,26,320,40,316,153,331,40,316,49,308,153,331,49,308,53,295,153,331,53,295,118,316,153,331,118,316,132,320,153,331,132,320,153,321,119,16,110,24,54,56,54,56,110,24,106,37,54,56,106,37,54,276,54,276,106,37,104,56,54,276,104,56,104,276,54,276,104,276,105,295,54,276,105,295,110,308,54,276,110,308,118,316,54,276,118,316,53,295,153,0,153,9,133,11,153,0,133,11,119,16,153,0,119,16,53,36,153,0,53,36,49,23,153,0,5,9,5,0,53,36,119,16,54,56,26,320,5,331,5,321, 157,411,156,419,153,426,147,431,140,435,132,436,125,435,118,431,113,426,109,419,108,411,109,403,113,397,118,391,124,388,132,387,140,388,147,391,153,397,156,403,157,411,16383,16383,58,411,57,419,53,426,48,431,41,435,33,436,25,435,18,431,13,426,10,419,8,411,10,403,13,397,18,391,25,388,32,387,40,388,47,391,53,397,57,403,58,411,16383,16383,157,0,157,9,136,11,122,16,114,24,109,37,108,56,108,276,109,295,113,308,122,316,136,320,157,321,157,331,8,331,8,321,30,320,44,316,52,308,56,295,57,276,57,56,56,36,52,23,44,15,29,11,8,9,8,0, 8,411,10,403,10,419,10,419,10,403,13,397,10,419,13,397,13,426,13,426,13,397,18,391,13,426,18,391,18,431,18,431,18,391,25,388,18,431,25,388,25,435,25,435,25,388,32,387,25,435,32,387,33,436,33,436,32,387,40,388,33,436,40,388,41,435,41,435,40,388,47,391,41,435,47,391,48,431,48,431,47,391,53,397,48,431,53,397,53,426,53,426,53,397,57,403,53,426,57,403,57,419,57,419,57,403,58,411,52,23,44,15,157,0,157,0,44,15,29,11,157,0,29,11,8,9,157,331,8,331,30,320,157,331,30,320,44,316,157,331,44,316,52,308,157,331,52,308,56,295,157,331,56,295,122,316,157,331,122,316,136,320,157,331,136,320,157,321,122,16,114,24,57,56,57,56,114,24,109,37,57,56,109,37,57,276,57,276,109,37,108,56,57,276,108,56,108,276,57,276,108,276,109,295,57,276,109,295,113,308,57,276,113,308,122,316,57,276,122,316,56,295,132,436,132,387,140,435,140,435,132,387,140,388,140,435,140,388,147,431,147,431,140,388,147,391,147,431,147,391,153,426,153,426,147,391,153,397,153,426,153,397,156,419,156,419,153,397,156,403,156,419,156,403,157,411,108,411,109,403,109,419,109,419,109,403,113,397,109,419,113,397,113,426,113,426,113,397,118,391,113,426,118,391,118,431,118,431,118,391,124,388,118,431,124,388,125,435,125,435,124,388,132,387,125,435,132,387,132,436,157,0,157,9,136,11,157,0,136,11,122,16,157,0,122,16,56,36,157,0,56,36,52,23,157,0,8,9,8,0,56,36,122,16,57,56,30,320,8,331,8,321, 8,331,8,321,28,319,40,315,48,307,51,295,52,276,52,180,11,180,11,157,52,157,52,55,51,36,47,24,40,16,27,12,8,9,8,0,150,0,183,2,213,7,242,16,267,27,287,41,307,60,322,83,333,109,340,137,343,167,334,224,308,269,267,303,212,324,143,331,16383,16383,103,157,176,157,176,180,103,180,103,293,104,301,106,307,111,310,117,312,127,313,152,312,175,309,194,304,212,297,227,289,249,271,266,249,278,224,285,195,288,164,285,130,278,101,266,76,249,55,227,39,211,31,194,26,175,22,153,19,128,18,118,19,111,21,106,25,104,31,103,39, 47,24,40,16,150,0,150,0,40,16,27,12,150,0,27,12,8,9,40,315,48,307,143,331,143,331,48,307,51,295,143,331,51,295,52,276,104,31,52,276,52,180,104,31,52,180,52,157,52,157,52,180,11,180,52,157,11,180,11,157,104,301,106,307,52,276,52,276,106,307,111,310,52,276,111,310,143,331,143,331,111,310,117,312,143,331,117,312,127,313,127,313,117,312,127,312,127,313,127,312,152,312,127,313,152,312,143,331,143,331,152,312,212,324,175,22,183,2,194,26,194,26,183,2,213,7,194,26,213,7,211,31,211,31,213,7,227,39,249,55,227,39,242,16,249,55,242,16,267,27,128,18,150,0,153,19,153,19,150,0,183,2,153,19,183,2,175,22,175,309,194,304,212,324,212,324,194,304,212,297,212,324,212,297,227,289,227,289,249,271,267,303,267,303,249,271,266,249,267,303,266,249,278,224,334,224,308,269,322,83,334,224,322,83,333,109,334,224,333,109,340,137,334,224,340,137,343,167,322,83,308,269,307,60,307,60,308,269,288,164,287,41,288,164,285,130,287,41,285,130,278,101,267,303,278,224,308,269,308,269,278,224,285,195,308,269,285,195,288,164,267,303,212,324,227,289,267,27,287,41,278,101,267,27,278,101,266,76,267,27,266,76,249,55,227,39,213,7,242,16,52,276,104,31,103,39,103,180,103,157,176,157,103,180,176,157,176,180,103,293,104,301,52,276,103,293,52,276,103,39,143,331,8,331,28,319,143,331,28,319,40,315,52,55,51,36,111,21,111,21,51,36,150,0,111,21,150,0,118,19,118,19,150,0,128,18,52,55,111,21,106,25,52,55,106,25,104,31,52,55,104,31,52,157,150,0,8,9,8,0,47,24,150,0,51,36,28,319,8,331,8,321,288,164,287,41,307,60,212,324,152,312,175,309, 244,444,240,434,235,427,230,422,224,420,218,419,213,419,208,420,203,422,191,426,180,432,172,436,158,440,151,441,145,441,130,439,118,433,108,423,100,409,94,391,108,391,112,399,116,406,122,410,128,413,134,414,138,414,146,412,150,410,155,408,177,398,185,394,193,392,200,391,206,391,221,393,234,399,244,409,252,424,259,444,16383,16383,353,331,235,331,235,321,247,320,256,319,263,317,275,309,278,303,281,295,283,285,284,274,284,89,91,331,6,331,6,321,19,321,29,318,37,313,46,306,55,295,55,75,54,48,49,30,41,19,27,13,6,9,6,0,123,0,123,9,103,13,90,20,82,31,78,49,76,75,76,269,297,-5,306,-5,306,274,308,289,311,299,315,307,320,313,324,315,329,318,335,319,343,320,353,321, 112,399,116,406,118,433,118,433,116,406,122,410,118,433,122,410,130,439,130,439,122,410,128,413,130,439,128,413,134,414,134,414,138,414,145,441,145,441,138,414,142,413,145,441,142,413,146,412,108,391,112,399,118,433,108,391,118,433,108,423,108,391,108,423,100,409,108,391,100,409,94,391,145,441,146,412,151,441,151,441,146,412,150,410,151,441,150,410,155,408,155,408,166,403,158,440,158,440,166,403,165,438,145,441,130,439,134,414,158,440,151,441,155,408,165,438,166,403,172,436,172,436,166,403,177,398,172,436,177,398,180,432,180,432,177,398,185,394,180,432,185,394,191,426,191,426,185,394,193,392,191,426,193,392,197,424,197,424,193,392,200,391,197,424,200,391,203,422,203,422,200,391,206,391,203,422,206,391,208,420,208,420,206,391,221,393,208,420,221,393,213,419,213,419,221,393,218,419,224,420,218,419,221,393,224,420,221,393,234,399,244,444,240,434,244,409,244,444,244,409,252,424,244,444,252,424,259,444,235,427,230,422,234,399,235,427,234,399,244,409,235,427,244,409,240,434,49,30,41,19,123,0,123,0,41,19,27,13,123,0,27,13,6,9,256,319,263,317,353,331,353,331,263,317,269,313,353,331,269,313,275,309,275,309,278,303,353,331,353,331,278,303,281,295,353,331,281,295,324,315,324,315,281,295,320,313,324,315,320,313,320,312,320,312,320,313,315,307,315,307,320,313,284,274,315,307,284,274,284,259,297,-5,284,259,284,89,297,-5,284,89,91,331,353,331,324,315,329,318,353,331,329,318,335,319,353,331,335,319,343,320,353,331,343,320,353,321,306,-5,306,253,297,-5,297,-5,306,253,306,274,297,-5,306,274,284,259,284,259,306,274,308,289,284,259,308,289,311,299,283,285,284,274,320,313,283,285,320,313,281,295,247,320,256,319,353,331,247,320,353,331,235,331,247,320,235,331,235,321,91,331,6,331,19,321,91,331,19,321,29,318,91,331,29,318,37,313,91,331,37,313,46,306,91,331,46,306,55,295,91,331,55,295,76,269,91,331,76,269,297,-5,55,295,78,49,76,75,54,48,49,30,90,20,90,20,49,30,123,0,90,20,123,0,103,13,103,13,123,0,123,9,55,75,54,48,82,31,55,75,82,31,78,49,55,75,78,49,55,295,123,0,6,9,6,0,54,48,90,20,82,31,19,321,6,331,6,321,76,269,55,295,76,75,315,307,284,259,311,299,224,420,234,399,230,422, 225,378,152,453,148,457,143,460,139,462,131,464,125,463,120,461,116,458,114,454,113,448,113,443,115,439,118,434,128,426,205,378,16383,16383,344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 205,378,225,378,152,453,205,378,152,453,148,457,205,378,148,457,143,460,205,378,143,460,139,462,205,378,139,462,135,463,205,378,135,463,131,464,205,378,131,464,128,426,113,448,113,443,114,454,114,454,113,443,115,439,114,454,115,439,116,458,116,458,115,439,118,434,116,458,118,434,120,461,120,461,118,434,123,430,120,461,123,430,125,463,125,463,123,430,128,426,125,463,128,426,131,464,149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,81,24,74,166,46,61,223,19,234,1,235,26,130,25,180,-6,142,19, 129,378,150,378,227,427,232,431,236,435,239,439,241,443,242,448,241,454,239,458,235,461,230,463,224,464,216,462,212,460,208,457,203,453,16383,16383,344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,224,464,227,427,230,463,230,463,227,427,232,431,230,463,232,431,235,461,235,461,232,431,236,435,235,461,236,435,239,458,239,458,236,435,239,439,239,458,239,439,241,454,241,454,239,439,241,443,241,454,241,443,242,448,227,427,224,464,220,463,227,427,220,463,216,462,227,427,216,462,212,460,227,427,212,460,208,457,227,427,208,457,203,453,227,427,203,453,150,378,81,24,74,166,46,61,150,378,203,453,129,378,223,19,234,1,235,26,130,25,180,-6,142,19, 255,378,193,462,161,462,99,378,117,378,177,430,238,378,16383,16383,344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 99,378,117,378,161,462,161,462,117,378,177,430,161,462,177,430,193,462,193,462,177,430,238,378,193,462,238,378,255,378,149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,81,24,74,166,46,61,223,19,234,1,235,26,130,25,180,-6,142,19, 244,444,240,434,235,427,230,422,224,420,218,419,213,419,208,420,203,422,191,426,180,432,172,436,158,440,151,441,145,441,130,439,118,433,108,423,100,409,94,391,108,391,112,399,116,406,122,410,128,413,134,414,138,414,146,412,150,410,155,408,177,398,185,394,193,392,200,391,206,391,221,393,234,399,244,409,252,424,259,444,16383,16383,344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 112,399,116,406,118,433,118,433,116,406,122,410,118,433,122,410,130,439,130,439,122,410,128,413,130,439,128,413,134,414,134,414,138,414,145,441,145,441,138,414,142,413,145,441,142,413,146,412,108,391,112,399,118,433,108,391,118,433,108,423,108,391,108,423,100,409,108,391,100,409,94,391,145,441,146,412,151,441,151,441,146,412,150,410,151,441,150,410,155,408,155,408,166,403,158,440,158,440,166,403,165,438,145,441,130,439,134,414,158,440,151,441,155,408,165,438,166,403,172,436,172,436,166,403,177,398,172,436,177,398,180,432,180,432,177,398,185,394,180,432,185,394,191,426,191,426,185,394,193,392,191,426,193,392,197,424,197,424,193,392,200,391,197,424,200,391,203,422,203,422,200,391,206,391,203,422,206,391,208,420,208,420,206,391,221,393,208,420,221,393,213,419,213,419,221,393,218,419,224,420,218,419,221,393,224,420,221,393,234,399,244,444,240,434,244,409,244,444,244,409,252,424,244,444,252,424,259,444,235,427,230,422,234,399,235,427,234,399,244,409,235,427,244,409,240,434,149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,81,24,74,166,46,61,223,19,234,1,235,26,130,25,180,-6,142,19,224,420,234,399,230,422, 252,411,250,419,247,426,241,431,234,435,227,436,219,435,212,431,207,426,203,419,202,411,203,403,207,397,212,391,218,388,226,387,234,388,241,391,247,397,250,403,252,411,16383,16383,152,411,151,419,147,426,142,431,135,435,127,436,119,435,113,431,107,426,104,419,103,411,104,403,107,397,112,391,119,388,127,387,135,388,142,391,147,397,151,403,152,411,16383,16383,344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 103,411,104,403,104,419,104,419,104,403,107,397,104,419,107,397,107,426,107,426,107,397,112,391,107,426,112,391,113,431,113,431,112,391,119,388,113,431,119,388,119,435,119,435,119,388,127,387,119,435,127,387,127,436,127,436,127,387,135,388,127,436,135,388,135,435,135,435,135,388,142,391,135,435,142,391,142,431,142,431,142,391,147,397,142,431,147,397,147,426,147,426,147,397,151,403,147,426,151,403,151,419,151,419,151,403,152,411,149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,202,411,203,403,203,419,203,419,203,403,207,397,203,419,207,397,207,426,207,426,207,397,212,391,207,426,212,391,212,431,212,431,212,391,218,388,212,431,218,388,219,435,219,435,218,388,226,387,219,435,226,387,227,436,227,436,226,387,234,388,227,436,234,388,234,435,234,435,234,388,241,391,234,435,241,391,241,431,241,431,241,391,247,397,241,431,247,397,247,426,247,426,247,397,250,403,247,426,250,403,250,419,250,419,250,403,252,411,81,24,74,166,46,61,223,19,234,1,235,26,130,25,180,-6,142,19, 299,11,184,126,299,242,276,265,160,150,45,265,22,242,137,126,22,11,45,-11,160,103,276,-11, 184,126,299,242,276,265,184,126,276,265,160,150,184,126,160,150,276,-11,184,126,276,-11,299,11,22,11,45,-11,137,126,137,126,45,-11,160,103,137,126,160,103,160,150,160,150,160,103,276,-11,45,265,22,242,137,126,45,265,137,126,160,150, 329,367,305,367,268,314,250,323,233,330,217,335,200,337,181,338,127,330,81,307,47,270,25,222,17,165,18,147,20,129,24,111,30,94,36,79,48,59,55,50,75,30,28,-39,52,-39,92,18,110,8,127,1,143,-3,161,-5,180,-6,234,1,279,24,314,61,336,109,344,166,343,184,340,203,336,220,331,237,325,252,319,263,313,272,305,281,296,291,285,302,16383,16383,97,61,88,80,82,99,77,119,75,141,74,165,79,218,93,261,115,293,144,313,180,320,196,319,211,315,225,309,238,300,251,287,16383,16383,263,270,272,251,279,232,284,212,286,190,287,165,282,113,268,70,246,38,217,18,180,11,164,12,149,16,135,22,122,32,109,44, 48,59,55,50,81,307,81,307,55,50,64,41,81,307,64,41,74,165,74,165,75,30,75,141,75,141,75,30,77,119,282,113,268,70,279,24,279,24,268,70,246,38,279,24,246,38,234,1,234,1,246,38,217,18,234,1,217,18,180,11,180,11,164,12,180,-6,180,-6,164,12,161,-5,88,80,92,18,97,61,97,61,92,18,110,8,97,61,110,8,109,44,109,44,110,8,122,32,122,32,110,8,127,1,122,32,127,1,135,22,135,22,127,1,143,-3,135,22,143,-3,149,16,149,16,143,-3,161,-5,149,16,161,-5,164,12,92,18,88,80,82,99,92,18,82,99,77,119,92,18,77,119,75,30,92,18,75,30,52,-39,75,30,28,-39,52,-39,109,44,263,270,251,287,251,287,268,314,250,323,251,287,250,323,238,300,238,300,250,323,233,330,238,300,233,330,225,309,225,309,233,330,217,335,225,309,217,335,211,315,211,315,217,335,200,337,211,315,200,337,196,319,196,319,200,337,181,338,196,319,181,338,180,320,343,184,340,203,344,166,344,166,340,203,336,220,344,166,336,220,336,109,336,109,336,220,331,237,336,109,331,237,325,252,319,263,313,272,314,61,319,263,314,61,336,109,319,263,336,109,325,252,279,24,314,61,282,113,282,113,314,61,287,165,296,291,287,165,314,61,296,291,314,61,305,281,305,281,314,61,313,272,180,11,180,-6,234,1,263,270,272,251,268,314,268,314,272,251,285,302,268,314,285,302,305,367,305,367,285,302,329,367,285,302,272,251,279,232,285,302,279,232,284,212,285,302,284,212,286,190,285,302,286,190,296,291,251,287,97,61,109,44,93,261,115,293,127,330,127,330,115,293,144,313,127,330,144,313,181,338,181,338,144,313,180,320,81,307,74,165,79,218,81,307,79,218,93,261,81,307,93,261,127,330,47,270,25,222,30,94,47,270,30,94,36,79,47,270,36,79,42,69,47,270,42,69,48,59,47,270,48,59,81,307,25,222,17,165,18,147,25,222,18,147,20,129,25,222,20,129,24,111,25,222,24,111,30,94,296,291,286,190,287,165,268,314,251,287,263,270,75,30,74,165,64,41, 227,378,154,453,149,457,145,460,141,462,137,463,132,464,126,463,121,461,118,458,115,454,114,448,115,443,117,439,120,434,124,430,129,426,206,378,16383,16383,353,331,237,331,237,321,257,319,270,312,279,301,282,283,283,257,283,103,282,85,279,70,273,57,265,45,254,34,241,26,225,20,208,16,189,15,173,16,158,19,146,24,135,30,125,37,115,50,109,63,105,79,104,97,103,118,103,275,104,293,108,306,115,314,128,319,148,321,148,331,7,331,7,321,27,319,40,315,47,308,51,297,52,280,52,124,53,95,58,69,66,48,78,30,93,16,106,8,121,1,138,-3,157,-5,177,-6,204,-5,227,0,247,6,264,17,278,30,290,45,297,62,302,81,305,104,305,258,306,282,310,300,318,311,331,318,353,321, 206,378,227,378,154,453,206,378,154,453,149,457,206,378,149,457,145,460,206,378,145,460,141,462,206,378,141,462,137,463,206,378,137,463,132,464,206,378,132,464,129,426,114,448,115,443,115,454,115,454,115,443,117,439,115,454,117,439,118,458,118,458,117,439,120,434,118,458,120,434,121,461,121,461,120,434,124,430,121,461,124,430,126,463,126,463,124,430,129,426,126,463,129,426,132,464,105,79,106,8,109,63,109,63,106,8,121,1,109,63,121,1,115,50,115,50,121,1,125,37,135,30,125,37,138,-3,135,30,138,-3,146,24,146,24,138,-3,157,-5,146,24,157,-5,158,19,158,19,157,-5,177,-6,158,19,177,-6,173,16,173,16,177,-6,189,15,208,16,189,15,204,-5,208,16,204,-5,227,0,103,118,103,275,93,16,103,118,93,16,104,97,104,97,93,16,106,8,104,97,106,8,105,79,125,37,121,1,138,-3,283,103,282,85,290,45,290,45,282,85,279,70,290,45,279,70,278,30,278,30,279,70,273,57,278,30,273,57,265,45,265,45,254,34,264,17,264,17,254,34,247,6,241,26,225,20,227,0,241,26,227,0,247,6,241,26,247,6,254,34,353,331,237,331,257,319,353,331,257,319,270,312,353,331,270,312,279,301,353,331,279,301,318,311,353,331,318,311,331,318,353,331,331,318,353,321,305,258,306,282,297,62,305,258,297,62,302,81,305,258,302,81,305,104,305,258,305,104,305,131,290,45,297,62,306,282,290,45,306,282,283,257,290,45,283,257,283,125,290,45,283,125,283,103,310,300,318,311,282,283,310,300,282,283,283,257,310,300,283,257,306,282,265,45,264,17,278,30,189,15,177,-6,204,-5,128,319,148,321,148,331,128,319,148,331,115,314,115,314,148,331,51,297,115,314,51,297,52,280,53,95,52,280,52,124,58,69,66,48,104,293,104,293,66,48,78,30,104,293,78,30,103,275,103,275,78,30,93,16,104,293,108,306,52,280,104,293,52,280,53,95,104,293,53,95,58,69,148,331,7,331,27,319,148,331,27,319,40,315,148,331,40,315,47,308,148,331,47,308,51,297,27,319,7,331,7,321,115,314,52,280,108,306,257,319,237,331,237,321,318,311,279,301,282,283,208,16,227,0,225,20, 132,378,152,378,229,427,234,431,238,435,241,439,243,443,244,448,243,454,241,458,237,461,233,463,227,464,222,463,218,462,214,460,210,457,205,453,16383,16383,353,331,237,331,237,321,257,319,270,312,279,301,282,283,283,257,283,103,282,85,279,70,273,57,265,45,254,34,241,26,225,20,208,16,189,15,173,16,158,19,146,24,135,30,125,37,115,50,109,63,105,79,104,97,103,118,103,275,104,293,108,306,115,314,128,319,148,321,148,331,7,331,7,321,27,319,40,315,47,308,51,297,52,280,52,124,53,95,58,69,66,48,78,30,93,16,106,8,121,1,138,-3,157,-5,177,-6,204,-5,227,0,247,6,264,17,278,30,290,45,297,62,302,81,305,104,305,258,306,282,310,300,318,311,331,318,353,321, 105,79,106,8,109,63,109,63,106,8,121,1,109,63,121,1,115,50,115,50,121,1,125,37,135,30,125,37,138,-3,135,30,138,-3,146,24,146,24,138,-3,157,-5,146,24,157,-5,158,19,158,19,157,-5,177,-6,158,19,177,-6,173,16,173,16,177,-6,189,15,208,16,189,15,204,-5,208,16,204,-5,227,0,103,118,103,275,93,16,103,118,93,16,104,97,104,97,93,16,106,8,104,97,106,8,105,79,125,37,121,1,138,-3,227,464,229,427,233,463,233,463,229,427,234,431,233,463,234,431,237,461,237,461,234,431,238,435,237,461,238,435,241,458,241,458,238,435,241,439,241,458,241,439,243,454,243,454,241,439,243,443,243,454,243,443,244,448,229,427,227,464,222,463,229,427,222,463,218,462,229,427,218,462,214,460,229,427,214,460,210,457,229,427,210,457,205,453,229,427,205,453,152,378,283,103,282,85,290,45,290,45,282,85,279,70,290,45,279,70,278,30,278,30,279,70,273,57,278,30,273,57,265,45,265,45,254,34,264,17,264,17,254,34,247,6,241,26,225,20,227,0,241,26,227,0,247,6,241,26,247,6,254,34,353,331,237,331,257,319,353,331,257,319,270,312,353,331,270,312,279,301,353,331,279,301,318,311,353,331,318,311,331,318,353,331,331,318,353,321,305,258,306,282,297,62,305,258,297,62,302,81,305,258,302,81,305,104,305,258,305,104,305,131,290,45,297,62,306,282,290,45,306,282,283,257,290,45,283,257,283,125,290,45,283,125,283,103,310,300,318,311,282,283,310,300,282,283,283,257,310,300,283,257,306,282,265,45,264,17,278,30,189,15,177,-6,204,-5,128,319,148,321,148,331,128,319,148,331,115,314,115,314,148,331,51,297,115,314,51,297,52,280,53,95,52,280,52,124,58,69,66,48,104,293,104,293,66,48,78,30,104,293,78,30,103,275,103,275,78,30,93,16,104,293,108,306,52,280,104,293,52,280,53,95,104,293,53,95,58,69,148,331,7,331,27,319,148,331,27,319,40,315,148,331,40,315,47,308,148,331,47,308,51,297,27,319,7,331,7,321,115,314,52,280,108,306,257,319,237,331,237,321,318,311,279,301,282,283,208,16,227,0,225,20,152,378,205,453,132,378, 256,378,193,462,162,462,100,378,117,378,177,430,238,378,16383,16383,353,331,237,331,237,321,257,319,270,312,279,301,282,283,283,257,283,103,282,85,279,70,273,57,265,45,254,34,241,26,225,20,208,16,189,15,173,16,158,19,146,24,135,30,125,37,115,50,109,63,105,79,104,97,103,118,103,275,104,293,108,306,115,314,128,319,148,321,148,331,7,331,7,321,27,319,40,315,47,308,51,297,52,280,52,124,53,95,58,69,66,48,78,30,93,16,106,8,121,1,138,-3,157,-5,177,-6,204,-5,227,0,247,6,264,17,278,30,290,45,297,62,302,81,305,104,305,258,306,282,310,300,318,311,331,318,353,321, 100,378,117,378,162,462,162,462,117,378,177,430,162,462,177,430,193,462,193,462,177,430,238,378,193,462,238,378,256,378,105,79,106,8,109,63,109,63,106,8,121,1,109,63,121,1,115,50,115,50,121,1,125,37,135,30,125,37,138,-3,135,30,138,-3,146,24,146,24,138,-3,157,-5,146,24,157,-5,158,19,158,19,157,-5,177,-6,158,19,177,-6,173,16,173,16,177,-6,189,15,208,16,189,15,204,-5,208,16,204,-5,227,0,103,118,103,275,93,16,103,118,93,16,104,97,104,97,93,16,106,8,104,97,106,8,105,79,125,37,121,1,138,-3,283,103,282,85,290,45,290,45,282,85,279,70,290,45,279,70,278,30,278,30,279,70,273,57,278,30,273,57,265,45,265,45,254,34,264,17,264,17,254,34,247,6,241,26,225,20,227,0,241,26,227,0,247,6,241,26,247,6,254,34,353,331,237,331,257,319,353,331,257,319,270,312,353,331,270,312,279,301,353,331,279,301,318,311,353,331,318,311,331,318,353,331,331,318,353,321,305,258,306,282,297,62,305,258,297,62,302,81,305,258,302,81,305,104,305,258,305,104,305,131,290,45,297,62,306,282,290,45,306,282,283,257,290,45,283,257,283,125,290,45,283,125,283,103,310,300,318,311,282,283,310,300,282,283,283,257,310,300,283,257,306,282,265,45,264,17,278,30,189,15,177,-6,204,-5,128,319,148,321,148,331,128,319,148,331,115,314,115,314,148,331,51,297,115,314,51,297,52,280,53,95,52,280,52,124,58,69,66,48,104,293,104,293,66,48,78,30,104,293,78,30,103,275,103,275,78,30,93,16,104,293,108,306,52,280,104,293,52,280,53,95,104,293,53,95,58,69,148,331,7,331,27,319,148,331,27,319,40,315,148,331,40,315,47,308,148,331,47,308,51,297,27,319,7,331,7,321,115,314,52,280,108,306,257,319,237,331,237,321,318,311,279,301,282,283,208,16,227,0,225,20, 252,411,250,419,247,426,241,431,234,435,227,436,219,435,212,431,207,426,203,419,202,411,203,403,207,397,212,391,218,388,226,387,234,388,241,391,247,397,250,403,252,411,16383,16383,152,411,151,419,147,426,142,431,135,435,127,436,119,435,113,431,107,426,104,419,103,411,104,403,107,397,112,391,119,388,127,387,135,388,142,391,147,397,151,403,152,411,16383,16383,353,331,237,331,237,321,257,319,270,312,279,301,282,283,283,257,283,103,282,85,279,70,273,57,265,45,254,34,241,26,225,20,208,16,189,15,173,16,158,19,146,24,135,30,125,37,115,50,109,63,105,79,104,97,103,118,103,275,104,293,108,306,115,314,128,319,148,321,148,331,7,331,7,321,27,319,40,315,47,308,51,297,52,280,52,124,53,95,58,69,66,48,78,30,93,16,106,8,121,1,138,-3,157,-5,177,-6,204,-5,227,0,247,6,264,17,278,30,290,45,297,62,302,81,305,104,305,258,306,282,310,300,318,311,331,318,353,321, 202,411,203,403,203,419,203,419,203,403,207,397,203,419,207,397,207,426,207,426,207,397,212,391,207,426,212,391,212,431,212,431,212,391,218,388,212,431,218,388,219,435,219,435,218,388,226,387,219,435,226,387,227,436,227,436,226,387,234,388,227,436,234,388,234,435,234,435,234,388,241,391,234,435,241,391,241,431,241,431,241,391,247,397,241,431,247,397,247,426,247,426,247,397,250,403,247,426,250,403,250,419,250,419,250,403,252,411,103,411,104,403,104,419,104,419,104,403,107,397,104,419,107,397,107,426,107,426,107,397,112,391,107,426,112,391,113,431,113,431,112,391,119,388,113,431,119,388,119,435,119,435,119,388,127,387,119,435,127,387,127,436,127,436,127,387,135,388,127,436,135,388,135,435,135,435,135,388,142,391,135,435,142,391,142,431,142,431,142,391,147,397,142,431,147,397,147,426,147,426,147,397,151,403,147,426,151,403,151,419,151,419,151,403,152,411,105,79,106,8,109,63,109,63,106,8,121,1,109,63,121,1,115,50,115,50,121,1,125,37,135,30,125,37,138,-3,135,30,138,-3,146,24,146,24,138,-3,157,-5,146,24,157,-5,158,19,158,19,157,-5,177,-6,158,19,177,-6,173,16,173,16,177,-6,189,15,208,16,189,15,204,-5,208,16,204,-5,227,0,103,118,103,275,93,16,103,118,93,16,104,97,104,97,93,16,106,8,104,97,106,8,105,79,125,37,121,1,138,-3,283,103,282,85,290,45,290,45,282,85,279,70,290,45,279,70,278,30,278,30,279,70,273,57,278,30,273,57,265,45,265,45,254,34,264,17,264,17,254,34,247,6,241,26,225,20,227,0,241,26,227,0,247,6,241,26,247,6,254,34,353,331,237,331,257,319,353,331,257,319,270,312,353,331,270,312,279,301,353,331,279,301,318,311,353,331,318,311,331,318,353,331,331,318,353,321,305,258,306,282,297,62,305,258,297,62,302,81,305,258,302,81,305,104,305,258,305,104,305,131,290,45,297,62,306,282,290,45,306,282,283,257,290,45,283,257,283,125,290,45,283,125,283,103,310,300,318,311,282,283,310,300,282,283,283,257,310,300,283,257,306,282,265,45,264,17,278,30,189,15,177,-6,204,-5,128,319,148,321,148,331,128,319,148,331,115,314,115,314,148,331,51,297,115,314,51,297,52,280,53,95,52,280,52,124,58,69,66,48,104,293,104,293,66,48,78,30,104,293,78,30,103,275,103,275,78,30,93,16,104,293,108,306,52,280,104,293,52,280,53,95,104,293,53,95,58,69,148,331,7,331,27,319,148,331,27,319,40,315,148,331,40,315,47,308,148,331,47,308,51,297,27,319,7,331,7,321,115,314,52,280,108,306,257,319,237,331,237,321,318,311,279,301,282,283,208,16,227,0,225,20, 133,378,153,378,230,427,240,435,243,439,244,443,245,448,244,454,242,458,238,461,234,463,228,464,223,463,219,462,216,460,211,457,206,453,16383,16383,352,331,243,331,243,321,256,321,266,319,272,316,275,312,276,306,276,302,274,294,272,290,270,285,197,174,124,285,121,289,118,294,116,299,115,304,115,308,116,312,119,316,123,318,130,320,138,321,151,321,151,331,11,331,11,321,24,319,37,313,50,299,68,277,92,243,157,147,157,61,156,39,152,25,144,16,129,12,107,9,107,0,260,0,260,9,239,11,224,15,215,23,210,36,209,55,209,151,282,266,297,288,310,303,322,313,336,319,352,321, 121,289,118,294,157,147,157,147,118,294,116,299,157,147,116,299,92,243,92,243,116,299,115,304,92,243,115,304,115,308,115,308,116,312,92,243,151,331,11,331,24,319,151,331,24,319,37,313,151,331,37,313,50,299,151,331,50,299,123,318,151,331,123,318,130,320,151,331,130,320,138,321,151,331,138,321,151,321,123,318,50,299,119,316,119,316,50,299,68,277,119,316,68,277,116,312,116,312,68,277,92,243,209,55,209,151,197,174,209,55,197,174,210,36,210,36,197,174,157,147,210,36,157,147,215,23,215,23,157,147,157,61,215,23,157,61,224,15,224,15,157,61,156,39,224,15,156,39,260,0,260,0,156,39,152,25,260,0,152,25,144,16,275,298,274,294,282,266,282,266,274,294,272,290,282,266,272,290,270,285,270,285,197,174,209,151,352,331,243,331,256,321,352,331,256,321,266,319,352,331,266,319,272,316,352,331,272,316,275,312,352,331,275,312,276,306,352,331,276,306,322,313,352,331,322,313,336,319,352,331,336,319,352,321,276,306,282,266,297,288,276,306,297,288,310,303,276,306,310,303,322,313,282,266,276,306,276,302,282,266,276,302,275,298,270,285,209,151,282,266,228,464,230,427,234,463,234,463,230,427,235,431,234,463,235,431,238,461,238,461,235,431,240,435,238,461,240,435,242,458,242,458,240,435,243,439,242,458,243,439,244,454,244,454,243,439,244,443,244,454,244,443,245,448,230,427,228,464,223,463,230,427,223,463,219,462,230,427,219,462,216,460,230,427,216,460,211,457,230,427,211,457,206,453,230,427,206,453,153,378,239,11,224,15,260,0,239,11,260,0,260,9,129,12,107,9,260,0,129,12,260,0,144,16,124,285,121,289,157,147,124,285,157,147,197,174,260,0,107,9,107,0,153,378,206,453,133,378,256,321,243,331,243,321,24,319,11,331,11,321, 101,266,101,268,100,269,100,271,101,292,105,306,113,314,127,319,147,321,147,331,8,331,8,321,27,319,39,314,46,307,49,294,50,276,50,60,49,39,46,25,39,17,27,12,8,9,8,0,148,0,148,9,128,11,114,16,106,23,102,36,101,55,101,80,109,80,115,79,136,79,158,80,177,82,194,85,210,90,223,96,239,107,253,121,263,138,269,156,271,175,265,206,248,231,221,250,185,262,141,266,16383,16383,101,230,101,237,103,242,106,245,110,247,117,247,154,244,182,236,201,221,213,200,217,172,213,146,202,126,185,111,161,102,129,99,113,99,107,100,101,100, 50,276,102,36,50,276,50,276,102,36,101,55,50,276,101,55,100,271,100,271,101,292,50,276,50,276,101,292,105,306,50,276,105,306,113,314,147,331,8,331,27,319,147,331,27,319,39,314,147,331,39,314,46,307,147,331,46,307,49,294,147,331,49,294,113,314,147,331,113,314,127,319,147,331,127,319,147,321,50,276,113,314,49,294,101,237,103,242,101,266,101,266,103,242,106,245,101,266,106,245,141,266,141,266,106,245,110,247,141,266,110,247,117,247,117,247,154,244,141,266,141,266,154,244,185,262,201,221,213,200,221,250,221,250,213,200,217,172,223,96,217,172,213,146,185,262,154,244,182,236,185,262,182,236,201,221,185,262,201,221,221,250,265,206,248,231,253,121,265,206,253,121,263,138,265,206,263,138,269,156,265,206,269,156,271,175,248,231,221,250,223,96,248,231,223,96,239,107,248,231,239,107,253,121,136,79,158,80,161,102,161,102,158,80,177,82,161,102,177,82,185,111,185,111,177,82,194,85,185,111,194,85,202,126,202,126,194,85,210,90,202,126,210,90,213,146,213,146,210,90,223,96,161,102,129,99,136,79,136,79,129,99,128,79,128,79,129,99,124,99,128,79,124,99,122,79,122,79,124,99,118,99,122,79,118,99,115,79,115,79,118,99,113,99,115,79,113,99,109,80,109,80,113,99,107,100,109,80,107,100,101,100,101,266,101,100,101,230,101,266,101,230,101,237,101,267,101,268,101,55,101,267,101,55,101,100,101,267,101,100,101,266,101,100,101,80,109,80,148,0,148,9,128,11,148,0,128,11,114,16,148,0,114,16,49,39,148,0,49,39,46,25,148,0,46,25,39,17,148,0,39,17,27,12,148,0,27,12,8,9,148,0,8,9,8,0,101,55,101,268,100,269,101,55,100,269,100,270,101,55,100,270,100,271,50,60,49,39,114,16,50,60,114,16,106,23,50,60,106,23,102,36,50,60,102,36,50,276,217,172,223,96,221,250,27,319,8,331,8,321, 36,42,36,28,33,19,28,13,19,9,6,7,6,0,79,0,79,275,81,293,86,308,95,319,107,326,122,328,137,325,150,316,159,302,165,282,167,258,165,237,159,220,150,207,137,199,119,195,114,194,110,193,107,191,105,189,105,184,107,182,110,180,115,179,121,179,145,173,163,161,176,140,184,111,187,75,186,61,185,48,182,36,179,26,175,19,172,15,164,11,160,10,155,10,150,11,146,12,143,15,142,19,141,25,140,36,138,42,135,48,130,52,125,55,118,56,111,55,105,51,100,46,97,40,96,32,98,20,105,10,115,2,129,-2,145,-3,173,0,198,14,217,35,229,62,234,93,233,110,229,125,223,139,214,152,203,163,193,170,183,176,172,181,158,185,142,189,169,203,189,216,202,230,208,246,210,266,207,291,195,312,178,328,154,338,126,342,93,337,68,324,50,301,40,269,36,227, 33,19,28,13,79,0,79,0,28,13,19,9,79,0,19,9,6,7,158,185,142,189,145,173,145,173,142,189,137,199,145,173,137,199,121,179,121,179,137,199,119,195,121,179,119,195,115,179,115,179,119,195,114,194,115,179,114,194,110,180,110,180,114,194,110,193,110,180,110,193,107,182,107,182,110,193,107,191,107,182,107,191,105,184,105,184,107,191,105,189,105,184,105,189,105,187,81,293,86,308,93,337,93,337,86,308,95,319,93,337,95,319,126,342,126,342,95,319,107,326,126,342,107,326,122,328,122,328,137,325,126,342,126,342,137,325,154,338,165,237,169,203,167,258,167,258,169,203,178,328,178,328,169,203,189,216,178,328,189,216,195,312,195,312,189,216,202,230,195,312,202,230,207,291,207,291,202,230,208,246,207,291,208,246,210,266,137,325,150,316,154,338,154,338,150,316,159,302,154,338,159,302,178,328,178,328,159,302,165,282,178,328,165,282,167,258,150,207,142,189,169,203,150,207,169,203,159,220,159,220,169,203,165,237,229,62,234,93,233,110,229,62,233,110,229,125,229,62,229,125,223,139,229,62,223,139,217,35,223,139,214,152,217,35,217,35,214,152,203,163,217,35,203,163,198,14,198,14,203,163,193,170,198,14,193,170,187,75,187,75,193,170,184,111,198,14,187,75,186,61,198,14,186,61,185,48,198,14,185,48,182,36,198,14,182,36,179,26,198,14,179,26,175,19,198,14,175,19,173,0,141,25,140,36,138,42,141,25,138,42,145,-3,141,25,145,-3,142,19,68,324,50,301,79,0,68,324,79,0,79,275,68,324,79,275,81,293,68,324,81,293,93,337,79,0,50,301,40,269,79,0,40,269,36,227,79,0,36,227,36,42,79,0,36,42,36,28,79,0,36,28,33,19,168,13,164,11,173,0,173,0,164,11,160,10,173,0,160,10,155,10,155,10,150,11,173,0,173,0,150,11,146,12,173,0,146,12,145,-3,145,-3,146,12,143,15,145,-3,143,15,142,19,168,13,173,0,172,15,172,15,173,0,175,19,138,42,135,48,145,-3,145,-3,135,48,130,52,145,-3,130,52,129,-2,129,-2,130,52,125,55,129,-2,125,55,118,56,115,2,129,-2,118,56,115,2,118,56,111,55,115,2,111,55,105,51,115,2,105,51,105,10,100,46,97,40,98,20,100,46,98,20,105,10,100,46,105,10,105,51,158,185,163,161,172,181,172,181,163,161,176,140,172,181,176,140,183,176,183,176,176,140,184,111,183,176,184,111,193,170,158,185,145,173,163,161,98,20,97,40,96,32,79,0,6,7,6,0,142,189,150,207,137,199, 158,253,86,328,81,332,77,335,73,337,65,339,59,338,53,336,50,333,47,329,46,323,47,318,49,314,52,309,56,305,61,301,138,253,16383,16383,221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 138,253,158,253,86,328,138,253,86,328,81,332,138,253,81,332,77,335,138,253,77,335,73,337,138,253,73,337,69,338,138,253,69,338,65,339,138,253,65,339,61,301,46,323,47,318,47,329,47,329,47,318,49,314,47,329,49,314,50,333,50,333,49,314,52,309,50,333,52,309,53,336,53,336,52,309,56,305,53,336,56,305,59,338,59,338,56,305,61,301,59,338,61,301,65,339,37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,184,56,186,-3,185,44,29,167,29,183,28,175, 60,253,79,253,156,302,162,306,166,310,169,314,171,318,171,329,168,333,165,336,160,338,154,339,146,337,142,335,138,332,133,328,16383,16383,221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,154,339,156,302,160,338,160,338,156,302,162,306,160,338,162,306,165,336,165,336,162,306,166,310,165,336,166,310,168,333,168,333,166,310,169,314,168,333,169,314,171,329,171,329,169,314,171,318,171,329,171,318,171,323,156,302,154,339,150,338,156,302,150,338,146,337,156,302,146,337,142,335,156,302,142,335,138,332,156,302,138,332,133,328,156,302,133,328,79,253,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,79,253,133,328,60,253,184,56,186,-3,185,44,29,167,29,183,28,175, 190,253,128,337,97,337,35,253,52,253,113,305,174,253,16383,16383,221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 35,253,52,253,97,337,97,337,52,253,113,305,97,337,113,305,128,337,128,337,113,305,174,253,128,337,174,253,190,253,37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,184,56,186,-3,185,44,29,167,29,183,28,175, 180,319,175,309,170,302,165,297,160,295,153,294,149,294,144,295,138,297,133,299,127,301,115,307,108,311,94,315,87,316,80,316,66,314,54,308,43,298,35,284,30,266,44,266,48,274,52,281,57,285,63,288,70,289,73,289,81,287,86,285,90,283,102,278,112,273,121,269,128,267,135,266,142,266,157,268,169,274,180,284,188,299,195,319,16383,16383,221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 48,274,52,281,54,308,54,308,52,281,57,285,54,308,57,285,66,314,66,314,57,285,63,288,66,314,63,288,70,289,70,289,73,289,80,316,80,316,73,289,77,288,80,316,77,288,81,287,44,266,48,274,54,308,44,266,54,308,43,298,44,266,43,298,35,284,44,266,35,284,30,266,37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,80,316,81,287,87,316,87,316,81,287,86,285,87,316,86,285,90,283,90,283,102,278,94,315,94,315,102,278,101,313,80,316,66,314,70,289,94,315,87,316,90,283,101,313,102,278,108,311,108,311,102,278,112,273,108,311,112,273,115,307,115,307,112,273,121,269,115,307,121,269,127,301,127,301,121,269,128,267,127,301,128,267,133,299,133,299,128,267,135,266,133,299,135,266,138,297,138,297,135,266,142,266,138,297,142,266,144,295,144,295,142,266,157,268,144,295,157,268,149,294,149,294,157,268,153,294,160,295,153,294,157,268,160,295,157,268,169,274,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,180,319,175,309,180,284,180,319,180,284,188,299,180,319,188,299,195,319,170,302,165,297,169,274,170,302,169,274,180,284,170,302,180,284,175,309,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,29,167,29,183,28,175,160,295,169,274,165,297,184,56,186,-3,185,44, 186,286,185,294,182,301,176,306,169,310,161,311,154,310,147,306,142,301,138,294,137,286,138,278,142,272,147,266,153,263,161,262,169,263,176,266,182,272,185,278,186,286,16383,16383,87,286,86,294,82,301,77,306,70,310,62,311,54,310,48,306,42,301,39,294,37,286,39,278,42,272,47,266,54,263,61,262,69,263,76,266,82,272,86,278,87,286,16383,16383,221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 161,311,161,262,169,310,169,310,161,262,169,263,169,310,169,263,176,306,176,306,169,263,176,266,176,306,176,266,182,301,182,301,176,266,182,272,182,301,182,272,185,294,185,294,182,272,185,278,185,294,185,278,186,286,137,286,138,278,138,294,138,294,138,278,142,272,138,294,142,272,142,301,142,301,142,272,147,266,142,301,147,266,147,306,147,306,147,266,153,263,147,306,153,263,154,310,154,310,153,263,161,262,154,310,161,262,161,311,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,37,286,39,278,39,294,39,294,39,278,42,272,39,294,42,272,42,301,42,301,42,272,47,266,42,301,47,266,48,306,48,306,47,266,54,263,48,306,54,263,54,310,54,310,54,263,61,262,54,310,61,262,62,311,62,311,61,262,69,263,62,311,69,263,70,310,70,310,69,263,76,266,70,310,76,266,77,306,77,306,76,266,82,272,77,306,82,272,82,301,82,301,82,272,86,278,82,301,86,278,86,294,86,294,86,278,87,286,37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,29,167,29,183,28,175,184,56,186,-3,185,44, 162,306,159,322,152,336,142,347,128,354,113,357,97,354,83,347,72,336,65,323,63,307,65,291,72,277,83,267,96,260,112,257,128,260,141,267,152,277,159,291,162,306,16383,16383,145,307,143,296,139,287,132,280,122,276,112,274,101,276,92,280,85,287,81,296,79,307,81,317,86,326,93,333,102,338,112,339,122,338,131,333,139,326,143,317,145,307,16383,16383,221,33,216,29,208,25,200,23,195,25,190,28,187,35,185,44,184,56,184,168,183,181,180,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,208,83,213,93,217,104,218,117,216,128,211,136,202,142,190,143,173,143,146,114,135,92,126,75,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,98,0,113,6,128,16,143,31,144,31,147,17,151,7,157,0,166,-3,176,-4,186,-3,195,-1,204,2,212,9,221,19,16383,16383,143,64,143,56,142,49,138,43,133,38,126,32,121,29,109,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,79,68,87,73,94,79,101,88,108,99,114,111,121,126,127,143,134, 143,296,139,287,141,267,141,267,139,287,132,280,141,267,132,280,128,260,128,260,132,280,122,276,128,260,122,276,112,257,112,257,122,276,112,274,63,307,65,291,65,323,65,323,65,291,72,277,65,323,72,277,72,336,72,336,72,277,83,267,72,336,83,267,79,307,79,307,83,347,72,336,37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,111,230,104,218,117,216,111,230,117,216,127,229,127,229,117,216,128,211,127,229,128,211,140,226,140,226,128,211,136,202,140,226,136,202,142,190,76,208,83,213,85,227,85,227,83,213,93,217,85,227,93,217,98,229,98,229,93,217,104,218,98,229,104,218,111,230,73,224,70,194,71,201,73,224,71,201,76,208,73,224,76,208,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,113,357,112,339,122,338,113,357,122,338,128,354,128,354,122,338,131,333,128,354,131,333,142,347,142,347,131,333,139,326,142,347,139,326,143,317,184,56,184,152,184,168,184,56,184,168,183,181,184,56,183,181,180,191,184,56,180,191,186,-3,190,28,195,-1,195,25,195,25,195,-1,200,23,204,24,200,23,204,2,204,24,204,2,212,9,187,35,185,44,186,-3,187,35,186,-3,195,-1,187,35,195,-1,190,28,147,17,151,7,152,222,152,222,151,7,157,0,152,222,157,0,162,215,162,215,157,0,166,-3,162,215,166,-3,170,208,170,208,166,-3,176,-4,170,208,176,-4,176,199,176,199,176,-4,186,-3,176,199,186,-3,180,191,152,222,140,226,142,190,152,222,142,190,143,173,152,222,143,173,143,134,152,222,143,134,144,31,152,222,144,31,147,17,143,31,144,31,143,134,143,146,143,134,143,173,216,29,212,27,212,9,216,29,212,9,221,19,216,29,221,19,221,33,208,25,204,24,212,9,208,25,212,9,212,27,200,23,195,-1,204,2,162,306,159,322,159,291,159,291,159,322,152,336,159,291,152,336,152,277,152,277,152,336,145,307,143,317,145,307,152,336,143,317,152,336,142,347,143,296,141,267,152,277,143,296,152,277,145,307,86,326,93,333,97,354,97,354,93,333,102,338,97,354,102,338,113,357,113,357,102,338,112,339,83,347,79,307,81,317,83,347,81,317,86,326,83,347,86,326,97,354,101,276,92,280,96,260,101,276,96,260,112,257,101,276,112,257,112,274,85,287,81,296,83,267,85,287,83,267,96,260,85,287,96,260,92,280,143,31,143,134,143,64,143,31,143,64,143,56,143,31,143,56,142,49,143,31,142,49,138,43,143,31,138,43,133,38,143,31,133,38,128,16,128,16,133,38,126,32,126,32,121,29,128,16,128,16,121,29,115,27,128,16,115,27,113,6,113,6,115,27,109,25,113,6,109,25,103,24,99,114,111,121,114,135,114,135,111,121,126,127,114,135,126,127,143,146,143,146,126,127,143,134,65,79,68,87,75,118,75,118,68,87,73,94,75,118,73,94,79,101,79,101,88,108,92,126,92,126,88,108,99,114,92,126,99,114,114,135,92,126,75,118,79,101,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,79,63,112,65,79,75,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,98,0,86,25,86,25,98,0,97,24,103,24,97,24,98,0,103,24,98,0,113,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,79,307,83,267,81,296,184,56,186,-3,185,44,29,167,29,183,28,175, 310,77,296,58,283,44,269,35,254,30,238,28,226,30,215,33,205,38,197,45,190,54,185,65,181,78,179,93,178,112,177,138,308,138,302,173,292,199,277,216,255,227,228,230,215,229,203,227,192,222,181,216,169,206,157,216,147,222,136,227,123,229,109,230,84,227,62,220,45,208,34,193,30,176,31,168,34,161,38,156,44,153,52,152,59,153,66,156,70,161,73,167,74,175,74,185,73,188,73,196,74,203,79,208,86,213,96,216,107,217,119,215,127,210,133,202,136,189,137,172,137,141,73,123,48,112,32,99,24,84,20,68,19,50,22,32,30,17,42,6,58,0,77,-2,91,-1,105,1,119,7,134,17,153,31,164,18,175,8,188,1,202,-1,218,-2,230,-2,243,0,254,3,266,9,276,17,285,24,293,33,300,44,308,58,316,75,16383,16383,177,153,180,177,186,194,194,206,206,212,221,214,235,212,246,206,254,194,259,177,261,153,16383,16383,137,100,138,90,140,68,146,46,146,45,147,45,147,44,143,38,134,31,121,25,108,21,95,19,83,21,74,28,67,37,64,49,63,63,64,79,71,92,85,103,106,114,137,127, 73,196,73,196,73,196,73,196,74,203,62,220,73,196,62,220,66,156,73,196,66,156,70,161,143,38,134,31,134,17,134,17,134,31,121,25,134,17,121,25,119,7,119,7,121,25,108,21,119,7,108,21,105,1,105,1,108,21,95,19,105,1,95,19,91,-1,91,-1,95,19,83,21,91,-1,83,21,77,-2,77,-2,83,21,74,28,77,-2,74,28,67,37,63,63,58,0,64,49,64,49,58,0,77,-2,64,49,77,-2,67,37,74,203,79,208,84,227,84,227,79,208,86,213,84,227,86,213,109,230,109,230,86,213,96,216,109,230,96,216,107,217,107,217,119,215,109,230,109,230,119,215,123,229,175,8,177,138,169,206,175,8,169,206,164,18,164,18,169,206,157,216,164,18,157,216,153,31,153,31,157,216,147,44,147,45,147,44,147,222,147,222,147,44,157,216,147,222,136,227,136,189,147,222,136,189,137,172,147,222,137,172,137,127,147,222,137,127,138,90,147,222,138,90,139,79,147,222,139,79,140,68,147,222,140,68,143,57,147,222,143,57,146,46,147,222,146,46,146,45,147,222,146,45,147,45,137,141,137,127,137,172,136,227,123,229,127,210,136,227,127,210,133,202,136,227,133,202,136,189,228,230,221,214,235,212,228,230,235,212,255,227,255,227,235,212,246,206,255,227,246,206,254,194,177,153,180,177,181,216,181,216,180,177,186,194,181,216,186,194,192,222,192,222,186,194,194,206,192,222,194,206,203,227,203,227,194,206,206,212,203,227,206,212,215,229,215,229,206,212,221,214,215,229,221,214,228,230,277,216,261,153,308,138,308,138,261,153,177,153,308,138,177,153,177,138,169,206,177,138,177,153,169,206,177,153,181,216,259,177,261,153,277,216,259,177,277,216,255,227,259,177,255,227,254,194,292,199,277,216,308,138,292,199,308,138,302,173,226,30,215,33,218,-2,218,-2,215,33,205,38,218,-2,205,38,202,-1,202,-1,205,38,197,45,202,-1,197,45,190,54,190,54,185,65,188,1,188,1,185,65,181,78,188,1,181,78,179,93,175,8,188,1,179,93,175,8,179,93,178,112,175,8,178,112,177,138,218,-2,230,-2,226,30,226,30,230,-2,238,28,254,30,238,28,243,0,254,30,243,0,254,3,190,54,188,1,202,-1,285,24,293,33,296,58,296,58,293,33,300,44,296,58,300,44,310,77,310,77,300,44,308,58,310,77,308,58,316,75,254,3,266,9,269,35,269,35,266,9,276,17,269,35,276,17,283,44,283,44,276,17,285,24,283,44,285,24,296,58,238,28,230,-2,243,0,143,38,134,17,153,31,143,38,153,31,147,44,64,79,71,92,73,123,73,123,71,92,85,103,73,123,85,103,137,141,137,141,85,103,106,114,137,141,106,114,137,127,42,6,58,0,48,112,48,112,58,0,63,63,48,112,63,63,64,79,20,68,22,32,24,84,24,84,22,32,30,17,24,84,30,17,32,99,32,99,30,17,42,6,32,99,42,6,48,112,38,156,44,153,45,208,45,208,44,153,52,152,45,208,52,152,62,220,62,220,52,152,59,153,62,220,59,153,66,156,34,193,30,176,31,168,34,193,31,168,34,161,34,193,34,161,38,156,34,193,38,156,45,208,74,185,73,188,73,167,74,185,73,167,74,175,74,185,74,175,74,180,73,167,73,188,73,192,73,167,73,192,73,196,73,167,73,196,70,161,62,220,74,203,84,227,22,32,20,68,19,50,48,112,64,79,73,123,138,90,137,127,137,100,254,30,254,3,269,35,123,229,119,215,127,210, 199,78,185,60,172,46,159,38,144,33,128,31,103,36,81,49,65,69,54,96,51,128,54,157,63,181,78,200,96,211,119,215,128,215,136,212,141,208,145,201,148,191,151,180,154,172,159,166,163,161,169,158,175,157,183,158,189,161,195,166,198,172,199,179,195,195,184,209,167,220,146,227,122,230,108,229,94,226,80,220,67,213,55,204,40,189,28,172,19,152,14,130,12,106,16,72,27,43,45,20,68,4,96,-3,77,-49,80,-51,83,-50,85,-50,88,-49,94,-49,104,-50,112,-52,117,-55,120,-60,121,-67,120,-74,116,-81,111,-85,103,-88,94,-89,88,-89,82,-88,75,-87,69,-86,61,-83,54,-98,63,-102,79,-106,87,-106,96,-107,117,-105,135,-99,148,-91,156,-79,158,-64,157,-52,151,-43,142,-36,130,-32,116,-30,108,-30,105,-31,103,-31,113,-4,136,0,156,9,174,24,190,46,206,74, 81,49,65,69,68,4,68,4,65,69,54,96,68,4,54,96,45,20,45,20,54,96,51,128,55,204,51,128,54,157,55,204,54,157,63,181,87,-106,96,-107,88,-89,88,-89,96,-107,94,-89,103,-88,94,-89,96,-107,103,-88,96,-107,117,-105,96,-3,94,-49,104,-50,96,-3,104,-50,103,-31,96,-3,103,-31,103,36,103,36,103,-31,113,-4,96,-3,77,-49,80,-51,96,-3,80,-51,83,-50,96,-3,83,-50,85,-50,96,-3,85,-50,88,-49,96,-3,88,-49,91,-49,96,-3,91,-49,94,-49,185,60,172,46,174,24,174,24,172,46,159,38,174,24,159,38,156,9,156,9,159,38,144,33,156,9,144,33,136,0,136,0,144,33,128,31,113,-4,136,0,128,31,113,-4,128,31,103,36,81,49,68,4,96,-3,81,49,96,-3,103,36,136,212,141,208,146,227,146,227,141,208,145,201,146,227,145,201,148,191,148,191,151,180,167,220,167,220,151,180,154,172,167,220,154,172,159,166,122,230,119,215,128,215,122,230,128,215,146,227,146,227,128,215,136,212,195,195,184,209,189,161,195,195,189,161,195,166,195,195,195,166,198,172,195,195,198,172,199,179,184,209,167,220,169,158,184,209,169,158,175,157,184,209,175,157,183,158,184,209,183,158,189,161,167,220,159,166,163,161,167,220,163,161,169,158,167,220,146,227,148,191,190,46,206,74,199,78,190,46,199,78,185,60,190,46,185,60,174,24,96,211,119,215,108,229,96,211,108,229,94,226,96,211,94,226,80,220,96,211,80,220,78,200,67,213,55,204,63,181,67,213,63,181,78,200,67,213,78,200,80,220,45,20,51,128,55,204,45,20,55,204,40,189,45,20,40,189,28,172,45,20,28,172,27,43,19,152,14,130,16,72,19,152,16,72,27,43,19,152,27,43,28,172,158,-64,157,-52,156,-79,156,-79,157,-52,151,-43,156,-79,151,-43,148,-91,148,-91,151,-43,142,-36,148,-91,142,-36,135,-99,135,-99,142,-36,130,-32,135,-99,130,-32,121,-67,121,-67,130,-32,120,-60,117,-55,120,-60,130,-32,117,-55,130,-32,116,-30,117,-55,116,-30,113,-30,117,-55,113,-30,112,-52,112,-52,113,-30,110,-30,112,-52,110,-30,108,-30,112,-52,108,-30,105,-31,112,-52,105,-31,104,-50,135,-99,121,-67,120,-74,135,-99,120,-74,117,-105,117,-105,120,-74,116,-81,117,-105,116,-81,111,-85,61,-83,63,-102,69,-86,69,-86,63,-102,71,-104,69,-86,71,-104,75,-87,75,-87,71,-104,79,-106,75,-87,79,-106,82,-88,82,-88,79,-106,87,-106,82,-88,87,-106,88,-89,63,-102,61,-83,54,-98,103,-88,117,-105,111,-85,103,-31,104,-50,105,-31,119,215,122,230,108,229,16,72,14,130,12,106, 155,253,83,328,78,332,74,335,69,337,61,339,55,338,50,336,46,333,44,329,43,323,44,318,46,314,49,309,53,305,58,301,135,253,16383,16383,204,82,190,62,176,48,162,37,146,31,127,30,114,31,101,34,90,39,80,47,71,57,62,71,56,85,52,100,50,118,49,138,203,138,201,153,198,166,195,177,185,195,175,207,163,217,149,224,133,228,116,230,81,224,52,207,31,182,17,148,12,108,17,70,29,39,49,15,75,0,108,-4,136,-1,160,9,181,26,198,49,212,79,16383,16383,50,155,55,175,63,191,74,203,87,210,103,212,120,210,133,203,141,192,147,176,151,155, 56,85,75,0,62,71,62,71,75,0,71,57,80,47,71,57,75,0,80,47,75,0,108,-4,52,100,50,118,49,15,52,100,49,15,75,0,52,100,75,0,56,85,12,108,17,70,17,148,17,148,17,70,29,39,17,148,29,39,31,182,31,182,29,39,49,15,31,182,49,15,49,138,49,138,49,15,50,118,135,253,155,253,83,328,135,253,83,328,78,332,135,253,78,332,74,335,135,253,74,335,69,337,135,253,69,337,65,338,135,253,65,338,61,339,135,253,61,339,58,301,43,323,44,318,44,329,44,329,44,318,46,314,44,329,46,314,46,333,46,333,46,314,49,309,46,333,49,309,50,336,50,336,49,309,53,305,50,336,53,305,55,338,55,338,53,305,58,301,55,338,58,301,61,339,133,228,116,230,120,210,120,210,116,230,103,212,87,210,103,212,116,230,87,210,116,230,81,224,190,62,176,48,181,26,181,26,176,48,162,37,181,26,162,37,160,9,160,9,162,37,146,31,160,9,146,31,136,-1,136,-1,146,31,127,30,203,138,201,153,198,166,203,138,198,166,195,177,203,138,195,177,190,186,203,138,190,186,185,195,203,138,185,195,175,207,203,138,175,207,163,217,203,138,163,217,151,155,203,138,151,155,50,155,203,138,50,155,49,138,141,192,147,176,149,224,149,224,147,176,151,155,149,224,151,155,163,217,198,49,212,79,204,82,198,49,204,82,190,62,198,49,190,62,181,26,114,31,101,34,108,-4,114,31,108,-4,136,-1,114,31,136,-1,127,30,90,39,80,47,108,-4,90,39,108,-4,101,34,133,228,120,210,133,203,133,228,133,203,141,192,133,228,141,192,149,224,50,155,55,175,52,207,52,207,55,175,63,191,52,207,63,191,81,224,81,224,63,191,74,203,81,224,74,203,87,210,52,207,31,182,49,138,52,207,49,138,50,155, 58,253,78,253,155,302,161,306,165,310,168,314,170,318,170,323,169,329,167,333,163,336,158,338,152,339,148,338,145,337,141,335,137,332,132,328,16383,16383,204,82,190,62,176,48,162,37,146,31,127,30,114,31,101,34,90,39,80,47,71,57,62,71,56,85,52,100,50,118,49,138,203,138,201,153,198,166,195,177,185,195,175,207,163,217,149,224,133,228,116,230,81,224,52,207,31,182,17,148,12,108,17,70,29,39,49,15,75,0,108,-4,136,-1,160,9,181,26,198,49,212,79,16383,16383,50,155,55,175,63,191,74,203,87,210,103,212,120,210,133,203,141,192,147,176,151,155, 203,138,201,153,198,166,203,138,198,166,195,177,203,138,195,177,190,186,203,138,190,186,185,195,203,138,185,195,175,207,203,138,175,207,163,217,203,138,163,217,151,155,203,138,151,155,50,155,203,138,50,155,49,138,141,192,147,176,149,224,149,224,147,176,151,155,149,224,151,155,163,217,152,339,155,302,158,338,158,338,155,302,161,306,158,338,161,306,163,336,163,336,161,306,165,310,163,336,165,310,167,333,167,333,165,310,168,314,167,333,168,314,169,329,169,329,168,314,170,318,169,329,170,318,170,323,155,302,152,339,148,338,155,302,148,338,145,337,155,302,145,337,141,335,155,302,141,335,137,332,155,302,137,332,132,328,155,302,132,328,78,253,52,100,50,118,49,15,49,15,50,118,49,138,49,15,49,138,31,182,49,15,31,182,29,39,29,39,31,182,17,148,29,39,17,148,17,70,17,70,17,148,12,108,133,228,116,230,120,210,120,210,116,230,103,212,87,210,103,212,116,230,87,210,116,230,81,224,190,62,176,48,181,26,181,26,176,48,162,37,181,26,162,37,160,9,160,9,162,37,146,31,160,9,146,31,136,-1,136,-1,146,31,127,30,198,49,212,79,204,82,198,49,204,82,190,62,198,49,190,62,181,26,114,31,101,34,108,-4,114,31,108,-4,136,-1,114,31,136,-1,127,30,101,34,90,39,108,-4,108,-4,90,39,80,47,108,-4,80,47,75,0,75,0,80,47,71,57,133,228,120,210,133,203,133,228,133,203,141,192,133,228,141,192,149,224,50,155,55,175,52,207,52,207,55,175,63,191,52,207,63,191,81,224,81,224,63,191,74,203,81,224,74,203,87,210,52,207,31,182,49,138,52,207,49,138,50,155,75,0,71,57,62,71,75,0,62,71,56,85,75,0,56,85,52,100,75,0,52,100,49,15,78,253,132,328,58,253, 190,253,127,337,97,337,35,253,51,253,112,305,173,253,16383,16383,204,82,190,62,176,48,162,37,146,31,127,30,114,31,101,34,90,39,80,47,71,57,62,71,56,85,52,100,50,118,49,138,203,138,201,153,198,166,195,177,185,195,175,207,163,217,149,224,133,228,116,230,81,224,52,207,31,182,17,148,12,108,17,70,29,39,49,15,75,0,108,-4,136,-1,160,9,181,26,198,49,212,79,16383,16383,50,155,55,175,63,191,74,203,87,210,103,212,120,210,133,203,141,192,147,176,151,155, 35,253,51,253,97,337,97,337,51,253,112,305,97,337,112,305,127,337,127,337,112,305,173,253,127,337,173,253,190,253,52,100,50,118,49,15,49,15,50,118,49,138,49,15,49,138,31,182,49,15,31,182,29,39,29,39,31,182,17,148,29,39,17,148,17,70,17,70,17,148,12,108,133,228,116,230,120,210,120,210,116,230,103,212,87,210,103,212,116,230,87,210,116,230,81,224,190,62,176,48,181,26,181,26,176,48,162,37,181,26,162,37,160,9,160,9,162,37,146,31,160,9,146,31,136,-1,136,-1,146,31,127,30,203,138,201,153,198,166,203,138,198,166,195,177,203,138,195,177,190,186,203,138,190,186,185,195,203,138,185,195,175,207,203,138,175,207,163,217,203,138,163,217,151,155,203,138,151,155,50,155,203,138,50,155,49,138,141,192,147,176,149,224,149,224,147,176,151,155,149,224,151,155,163,217,198,49,212,79,204,82,198,49,204,82,190,62,198,49,190,62,181,26,114,31,101,34,108,-4,114,31,108,-4,136,-1,114,31,136,-1,127,30,101,34,90,39,108,-4,108,-4,90,39,80,47,108,-4,80,47,75,0,75,0,80,47,71,57,133,228,120,210,133,203,133,228,133,203,141,192,133,228,141,192,149,224,50,155,55,175,52,207,52,207,55,175,63,191,52,207,63,191,81,224,81,224,63,191,74,203,81,224,74,203,87,210,52,207,31,182,49,138,52,207,49,138,50,155,75,0,71,57,62,71,75,0,62,71,56,85,75,0,56,85,52,100,75,0,52,100,49,15, 186,286,185,294,181,301,176,306,169,310,161,311,153,310,147,306,141,301,138,294,137,286,138,278,141,272,146,266,153,263,161,262,169,263,176,266,181,272,185,278,186,286,16383,16383,86,286,85,294,82,301,76,306,69,310,61,311,54,310,47,306,42,301,38,294,37,286,38,278,41,272,47,266,53,263,61,262,69,263,76,266,81,272,85,278,86,286,16383,16383,204,82,190,62,176,48,162,37,146,31,127,30,114,31,101,34,90,39,80,47,71,57,62,71,56,85,52,100,50,118,49,138,203,138,201,153,198,166,195,177,185,195,175,207,163,217,149,224,133,228,116,230,81,224,52,207,31,182,17,148,12,108,17,70,29,39,49,15,75,0,108,-4,136,-1,160,9,181,26,198,49,212,79,16383,16383,50,155,55,175,63,191,74,203,87,210,103,212,120,210,133,203,141,192,147,176,151,155, 203,138,201,153,198,166,203,138,198,166,195,177,203,138,195,177,190,186,203,138,190,186,185,195,203,138,185,195,175,207,203,138,175,207,163,217,203,138,163,217,151,155,203,138,151,155,50,155,203,138,50,155,49,138,141,192,147,176,149,224,149,224,147,176,151,155,149,224,151,155,163,217,137,286,138,278,138,294,138,294,138,278,141,272,138,294,141,272,141,301,141,301,141,272,146,266,141,301,146,266,147,306,147,306,146,266,153,263,147,306,153,263,153,310,153,310,153,263,161,262,153,310,161,262,161,311,161,311,161,262,169,263,161,311,169,263,169,310,169,310,169,263,176,266,169,310,176,266,176,306,176,306,176,266,181,272,176,306,181,272,181,301,181,301,181,272,185,278,181,301,185,278,185,294,185,294,185,278,186,286,37,286,38,278,38,294,38,294,38,278,41,272,38,294,41,272,42,301,42,301,41,272,47,266,42,301,47,266,47,306,47,306,47,266,53,263,47,306,53,263,54,310,54,310,53,263,61,262,54,310,61,262,61,311,61,311,61,262,69,263,61,311,69,263,69,310,69,310,69,263,76,266,69,310,76,266,76,306,76,306,76,266,81,272,76,306,81,272,82,301,82,301,81,272,85,278,82,301,85,278,85,294,85,294,85,278,86,286,52,100,50,118,49,15,49,15,50,118,49,138,49,15,49,138,31,182,49,15,31,182,29,39,29,39,31,182,17,148,29,39,17,148,17,70,17,70,17,148,12,108,133,228,116,230,120,210,120,210,116,230,103,212,87,210,103,212,116,230,87,210,116,230,81,224,190,62,176,48,181,26,181,26,176,48,162,37,181,26,162,37,160,9,160,9,162,37,146,31,160,9,146,31,136,-1,136,-1,146,31,127,30,198,49,212,79,204,82,198,49,204,82,190,62,198,49,190,62,181,26,114,31,101,34,108,-4,114,31,108,-4,136,-1,114,31,136,-1,127,30,101,34,90,39,108,-4,108,-4,90,39,80,47,108,-4,80,47,75,0,75,0,80,47,71,57,133,228,120,210,133,203,133,228,133,203,141,192,133,228,141,192,149,224,50,155,55,175,52,207,52,207,55,175,63,191,52,207,63,191,81,224,81,224,63,191,74,203,81,224,74,203,87,210,52,207,31,182,49,138,52,207,49,138,50,155,75,0,71,57,62,71,75,0,62,71,56,85,75,0,56,85,52,100,75,0,52,100,49,15, 115,253,42,328,38,332,33,335,29,337,21,339,15,338,10,336,6,333,4,329,3,323,3,318,5,314,8,309,18,301,95,253,16383,16383,122,0,122,7,105,9,94,14,88,21,85,34,84,52,84,228,82,230,5,203,5,195,15,197,26,197,33,196,37,193,40,187,42,178,42,33,38,20,32,13,20,9,3,7,3,0, 95,253,115,253,42,328,95,253,42,328,38,332,95,253,38,332,33,335,95,253,33,335,29,337,95,253,29,337,25,338,95,253,25,338,21,339,95,253,21,339,18,301,3,323,3,318,4,329,4,329,3,318,5,314,4,329,5,314,6,333,6,333,5,314,8,309,6,333,8,309,10,336,10,336,8,309,13,305,10,336,13,305,15,338,15,338,13,305,18,301,15,338,18,301,21,339,38,20,32,13,122,0,122,0,32,13,20,9,122,0,20,9,3,7,15,197,19,197,82,230,82,230,19,197,23,197,82,230,23,197,26,197,26,197,33,196,82,230,82,230,33,196,37,193,82,230,37,193,40,187,38,20,122,0,42,33,42,33,122,0,94,14,42,33,94,14,42,52,42,52,94,14,88,21,42,52,88,21,42,166,42,178,42,166,82,230,42,178,82,230,40,187,10,196,15,197,82,230,10,196,82,230,5,203,10,196,5,203,5,195,84,52,84,228,82,230,84,52,82,230,42,166,84,52,42,166,85,34,105,9,94,14,122,0,105,9,122,0,122,7,122,0,3,7,3,0,42,166,88,21,85,34, 25,253,45,253,122,302,127,306,131,310,134,314,136,318,137,323,136,329,134,333,130,336,125,338,119,339,111,337,107,335,103,332,98,328,16383,16383,127,0,127,7,110,9,99,14,93,21,90,34,89,52,89,228,87,230,10,203,10,195,20,197,31,197,38,196,42,193,45,187,47,178,47,33,43,20,37,13,25,9,8,7,8,0, 119,339,122,302,125,338,125,338,122,302,127,306,125,338,127,306,130,336,130,336,127,306,131,310,130,336,131,310,134,333,134,333,131,310,134,314,134,333,134,314,136,329,136,329,134,314,136,318,136,329,136,318,137,323,122,302,119,339,115,338,122,302,115,338,111,337,122,302,111,337,107,335,122,302,107,335,103,332,122,302,103,332,98,328,122,302,98,328,45,253,43,20,37,13,127,0,127,0,37,13,25,9,127,0,25,9,8,7,20,197,24,197,87,230,87,230,24,197,28,197,87,230,28,197,31,197,31,197,38,196,87,230,87,230,38,196,42,193,87,230,42,193,45,187,43,20,127,0,47,33,47,33,127,0,99,14,47,33,99,14,47,52,47,52,99,14,93,21,47,52,93,21,47,166,47,178,47,166,87,230,47,178,87,230,45,187,15,196,20,197,87,230,15,196,87,230,10,203,15,196,10,203,10,195,89,52,89,228,87,230,89,52,87,230,47,166,89,52,47,166,90,34,110,9,99,14,127,0,110,9,127,0,127,7,127,0,8,7,8,0,47,166,93,21,90,34,45,253,98,328,25,253, 147,253,84,337,54,337,-7,253,8,253,69,305,130,253,16383,16383,110,0,110,7,93,9,83,14,77,21,74,34,73,52,73,228,70,230,-6,203,-6,195,0,196,3,197,15,197,21,196,26,193,29,187,31,178,31,52,30,33,27,20,21,13,9,9,-7,7,-7,0, -7,253,8,253,54,337,54,337,8,253,69,305,54,337,69,305,84,337,84,337,69,305,130,253,84,337,130,253,147,253,27,20,21,13,110,0,110,0,21,13,9,9,110,0,9,9,-7,7,3,197,8,197,70,230,70,230,8,197,11,197,70,230,11,197,15,197,15,197,21,196,70,230,70,230,21,196,26,193,70,230,26,193,29,187,31,166,31,52,77,21,31,166,77,21,74,34,31,166,74,34,73,52,31,166,73,52,70,230,31,166,70,230,31,178,0,196,3,197,70,230,0,196,70,230,-6,203,0,196,-6,203,-6,195,73,52,73,228,70,230,110,0,110,7,93,9,110,0,93,9,83,14,110,0,83,14,30,33,110,0,30,33,27,20,31,52,30,33,83,14,31,52,83,14,77,21,110,0,-7,7,-7,0,70,230,29,187,31,178, 144,286,143,294,139,301,133,306,127,310,119,311,111,310,104,306,99,301,96,294,94,286,96,278,99,272,104,266,111,263,118,262,126,263,133,266,139,272,143,278,144,286,16383,16383,45,286,43,294,40,301,34,306,27,310,20,311,12,310,5,306,0,301,-3,294,-4,286,-3,278,0,272,5,266,11,263,19,262,27,263,34,266,40,272,43,278,45,286,16383,16383,113,0,113,7,97,9,86,14,80,21,77,34,76,52,76,228,74,230,-2,203,-2,195,2,196,7,197,18,197,25,196,29,193,32,187,34,178,35,166,35,52,34,33,31,20,24,13,12,9,-4,7,-4,0, 31,20,113,0,34,33,34,33,113,0,86,14,34,33,86,14,35,52,35,52,86,14,80,21,35,52,80,21,35,166,35,166,80,21,77,34,35,166,77,34,76,52,74,230,-2,203,2,196,74,230,2,196,7,197,74,230,7,197,11,197,74,230,11,197,15,197,74,230,15,197,18,197,74,230,18,197,25,196,74,230,25,196,29,193,74,230,29,193,32,187,74,230,32,187,34,178,74,230,34,178,35,166,74,230,35,166,76,52,74,230,76,52,76,228,94,286,96,278,96,294,96,294,96,278,99,272,96,294,99,272,99,301,99,301,99,272,104,266,99,301,104,266,104,306,104,306,104,266,111,263,104,306,111,263,111,310,111,310,111,263,118,262,111,310,118,262,119,311,119,311,118,262,126,263,119,311,126,263,127,310,127,310,126,263,133,266,127,310,133,266,133,306,133,306,133,266,139,272,133,306,139,272,139,301,139,301,139,272,143,278,139,301,143,278,143,294,143,294,143,278,144,286,97,9,86,14,113,0,97,9,113,0,113,7,113,0,31,20,24,13,113,0,24,13,12,9,113,0,12,9,-4,7,113,0,-4,7,-4,0,-4,286,-3,278,-3,294,-3,294,-3,278,0,272,-3,294,0,272,0,301,0,301,0,272,5,266,0,301,5,266,5,306,5,306,5,266,11,263,5,306,11,263,12,310,12,310,11,263,19,262,12,310,19,262,20,311,20,311,19,262,27,263,20,311,27,263,27,310,27,310,27,263,34,266,27,310,34,266,34,306,34,306,34,266,40,272,34,306,40,272,40,301,40,301,40,272,43,278,40,301,43,278,43,294,43,294,43,278,45,286,2,196,-2,203,-2,195, 212,328,195,343,148,318,135,326,122,332,107,337,90,340,71,342,50,329,66,326,80,323,93,318,105,311,118,302,57,270,74,255,135,287,151,272,163,256,172,239,179,220,184,200,170,212,159,221,148,226,136,229,123,230,89,224,59,208,35,182,20,148,15,108,20,70,35,38,58,15,88,0,123,-4,145,-2,165,3,182,13,196,26,209,44,218,60,225,79,231,99,234,120,235,142,233,179,225,215,211,248,192,278,166,304,16383,16383,190,101,187,69,179,44,167,25,151,13,132,9,104,18,83,41,70,73,62,108,60,141,62,165,70,185,83,201,99,212,118,216,142,211,162,195,177,171,187,139,190,101, 136,229,123,230,142,211,142,211,123,230,118,216,99,212,118,216,123,230,99,212,123,230,89,224,122,332,118,302,135,287,122,332,135,287,135,326,135,326,135,287,151,272,135,326,151,272,148,318,148,318,151,272,166,304,148,318,166,304,195,343,195,343,166,304,212,328,107,337,90,340,93,318,107,337,93,318,105,311,107,337,105,311,118,302,107,337,118,302,122,332,50,329,66,326,71,342,71,342,66,326,80,323,71,342,80,323,90,340,90,340,80,323,93,318,187,69,179,44,182,13,182,13,179,44,167,25,182,13,167,25,165,3,165,3,167,25,151,13,165,3,151,13,145,-2,145,-2,151,13,132,9,145,-2,132,9,123,-4,123,-4,132,9,104,18,123,-4,104,18,88,0,88,0,104,18,83,41,88,0,83,41,70,73,88,0,70,73,58,15,58,15,70,73,62,108,58,15,62,108,60,141,60,141,62,165,59,208,59,208,62,165,70,185,59,208,70,185,89,224,89,224,70,185,83,201,89,224,83,201,99,212,15,108,20,70,20,148,20,148,20,70,35,38,20,148,35,38,35,182,35,182,35,38,58,15,35,182,58,15,59,208,59,208,58,15,60,141,151,272,163,256,166,304,166,304,163,256,172,239,166,304,172,239,192,278,192,278,172,239,179,220,192,278,179,220,184,200,118,302,57,270,74,255,118,302,74,255,135,287,184,200,187,139,192,278,192,278,187,139,190,101,196,26,190,101,187,69,233,179,225,215,225,79,233,179,225,79,231,99,233,179,231,99,234,120,233,179,234,120,235,142,196,26,209,44,211,248,211,248,209,44,218,60,211,248,218,60,225,215,225,215,218,60,225,79,192,278,190,101,196,26,192,278,196,26,211,248,187,139,184,200,177,171,177,171,184,200,170,212,177,171,170,212,162,195,162,195,170,212,159,221,162,195,159,221,148,226,148,226,136,229,142,211,148,226,142,211,162,195,187,69,182,13,196,26, 196,319,191,309,186,302,181,297,176,295,170,294,165,294,160,295,154,297,149,299,143,301,131,307,124,311,110,315,103,316,96,316,82,314,70,308,59,298,51,284,46,266,60,266,64,274,68,281,73,285,79,288,85,289,89,289,97,287,102,285,106,283,118,278,128,273,137,269,144,267,151,266,158,266,173,268,185,274,195,284,203,299,210,319,16383,16383,243,0,243,7,230,9,221,13,216,19,213,29,212,42,212,153,210,180,202,201,190,217,174,227,153,230,139,229,125,224,111,216,96,205,81,190,80,190,80,228,76,230,50,220,37,216,23,212,8,208,8,199,10,200,13,200,16,201,22,201,30,200,35,197,38,191,40,181,40,47,39,32,37,21,31,14,22,9,9,7,9,0,114,0,114,7,101,9,92,13,86,18,83,26,82,36,82,174,95,186,105,194,115,199,124,202,133,203,147,201,157,195,164,185,169,171,170,152,170,52,169,35,166,23,161,15,152,10,139,7,138,0, 37,21,31,14,114,0,114,0,31,14,22,9,114,0,22,9,9,7,13,200,16,201,23,212,23,212,16,201,19,201,23,212,19,201,22,201,22,201,30,200,23,212,23,212,30,200,37,216,23,212,8,208,10,200,23,212,10,200,13,200,30,200,35,197,37,216,37,216,35,197,38,191,37,216,38,191,50,220,50,220,38,191,40,181,50,220,40,181,40,169,83,26,40,169,40,47,83,26,40,47,86,18,86,18,40,47,92,13,80,228,76,230,80,190,80,190,76,230,82,36,80,190,82,36,81,190,81,190,82,36,82,174,81,190,82,174,96,205,96,205,82,174,95,186,96,205,95,186,105,194,64,274,68,281,70,308,70,308,68,281,73,285,70,308,73,285,82,314,82,314,73,285,79,288,82,314,79,288,85,289,85,289,89,289,96,316,96,316,89,289,93,288,96,316,93,288,97,287,60,266,64,274,70,308,60,266,70,308,59,298,60,266,59,298,51,284,60,266,51,284,46,266,96,316,97,287,103,316,103,316,97,287,102,285,103,316,102,285,106,283,106,283,118,278,110,315,110,315,118,278,117,313,96,316,82,314,85,289,110,315,103,316,106,283,117,313,118,278,124,311,124,311,118,278,128,273,124,311,128,273,131,307,131,307,128,273,137,269,131,307,137,269,143,301,143,301,137,269,144,267,143,301,144,267,149,299,149,299,144,267,151,266,149,299,151,266,154,297,154,297,151,266,158,266,154,297,158,266,160,295,160,295,158,266,173,268,160,295,173,268,165,294,165,294,173,268,170,294,176,295,170,294,173,268,176,295,173,268,185,274,96,205,105,194,111,216,111,216,105,194,115,199,111,216,115,199,125,224,125,224,115,199,124,202,125,224,124,202,133,203,133,203,147,201,139,229,139,229,147,201,153,230,82,36,76,230,63,225,82,36,63,225,83,26,139,229,125,224,133,203,166,23,161,15,243,0,243,0,161,15,152,10,243,0,152,10,139,7,157,195,164,185,174,227,174,227,164,185,169,171,174,227,169,171,170,152,216,19,170,152,170,52,216,19,170,52,221,13,221,13,170,52,169,35,221,13,169,35,243,0,243,0,169,35,166,23,153,230,147,201,157,195,153,230,157,195,174,227,212,42,212,153,210,180,212,42,210,180,202,201,212,42,202,201,213,29,230,9,221,13,243,0,230,9,243,0,243,7,213,29,202,201,190,217,213,29,190,217,174,227,213,29,174,227,170,152,213,29,170,152,216,19,196,319,191,309,195,284,196,319,195,284,203,299,196,319,203,299,210,319,186,302,181,297,185,274,186,302,185,274,195,284,186,302,195,284,191,309,114,0,114,7,101,9,114,0,101,9,92,13,114,0,92,13,39,32,114,0,39,32,37,21,50,220,40,169,83,26,50,220,83,26,63,225,10,200,8,208,8,199,114,0,9,7,9,0,39,32,92,13,40,47,176,295,185,274,181,297,243,0,139,7,138,0, 166,253,94,328,89,332,84,335,80,337,72,339,66,338,61,336,57,333,55,329,54,323,55,318,57,314,60,309,64,305,69,301,146,253,16383,16383,235,116,230,154,215,186,191,210,162,225,127,230,90,225,58,209,35,185,20,153,15,114,20,75,35,42,58,17,88,1,123,-4,160,1,191,17,215,43,230,76,235,116,16383,16383,190,102,187,70,180,44,168,25,151,13,131,9,120,10,110,13,101,18,93,25,86,34,76,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,98,212,118,216,130,215,140,211,149,206,158,199,165,191,174,177,181,161,186,142,189,122,190,102, 146,253,166,253,94,328,146,253,94,328,89,332,146,253,89,332,84,335,146,253,84,335,80,337,146,253,80,337,76,338,146,253,76,338,72,339,146,253,72,339,69,301,54,323,55,318,55,329,55,329,55,318,57,314,55,329,57,314,57,333,57,333,57,314,60,309,57,333,60,309,61,336,61,336,60,309,64,305,61,336,64,305,66,338,66,338,64,305,69,301,66,338,69,301,72,339,64,91,58,17,69,70,69,70,58,17,88,1,69,70,88,1,76,51,76,51,88,1,86,34,93,25,86,34,88,1,93,25,88,1,123,-4,162,225,127,230,130,215,130,215,127,230,118,216,98,212,118,216,127,230,98,212,127,230,90,225,187,70,180,44,191,17,191,17,180,44,168,25,191,17,168,25,160,1,160,1,168,25,151,13,160,1,151,13,131,9,131,9,120,10,123,-4,123,-4,120,10,110,13,123,-4,110,13,101,18,140,211,149,206,162,225,162,225,149,206,158,199,162,225,158,199,165,191,165,191,174,177,191,210,191,210,174,177,181,161,191,210,181,161,186,142,230,154,215,186,215,43,230,154,215,43,230,76,230,154,230,76,235,116,187,70,191,17,190,102,190,102,191,17,191,210,191,210,191,17,215,43,191,210,215,43,215,186,191,210,186,142,189,122,191,210,189,122,190,102,191,210,162,225,165,191,131,9,123,-4,160,1,58,17,61,113,60,137,60,137,62,164,58,209,58,209,62,164,70,186,58,209,70,186,90,225,90,225,70,186,82,202,90,225,82,202,98,212,58,17,60,137,58,209,58,17,58,209,35,42,35,42,58,209,35,185,35,42,35,185,20,75,20,75,35,185,20,153,20,75,20,153,15,114,61,113,58,17,64,91,162,225,130,215,140,211,93,25,123,-4,101,18, 77,253,97,253,174,302,180,306,184,310,187,314,189,318,189,323,188,329,186,333,182,336,177,338,171,339,163,337,160,335,156,332,151,328,16383,16383,235,116,230,154,215,186,191,210,162,225,127,230,90,225,58,209,35,185,20,153,15,114,20,75,35,42,58,17,88,1,123,-4,160,1,191,17,215,43,230,76,235,116,16383,16383,190,102,187,70,180,44,168,25,151,13,131,9,120,10,110,13,101,18,93,25,86,34,76,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,98,212,118,216,130,215,140,211,149,206,158,199,165,191,174,177,181,161,186,142,189,122,190,102, 171,339,174,302,177,338,177,338,174,302,180,306,177,338,180,306,182,336,182,336,180,306,184,310,182,336,184,310,186,333,186,333,184,310,187,314,186,333,187,314,188,329,188,329,187,314,189,318,188,329,189,318,189,323,174,302,171,339,167,338,174,302,167,338,163,337,174,302,163,337,160,335,174,302,160,335,156,332,174,302,156,332,151,328,174,302,151,328,97,253,64,91,58,17,69,70,69,70,58,17,88,1,69,70,88,1,76,51,76,51,88,1,86,34,93,25,86,34,88,1,93,25,88,1,123,-4,162,225,127,230,130,215,130,215,127,230,118,216,98,212,118,216,127,230,98,212,127,230,90,225,187,70,180,44,191,17,191,17,180,44,168,25,191,17,168,25,160,1,160,1,168,25,151,13,160,1,151,13,131,9,131,9,120,10,123,-4,123,-4,120,10,110,13,123,-4,110,13,101,18,140,211,149,206,162,225,162,225,149,206,158,199,162,225,158,199,165,191,165,191,174,177,191,210,191,210,174,177,181,161,191,210,181,161,186,142,230,154,215,186,215,43,230,154,215,43,230,76,230,154,230,76,235,116,187,70,191,17,190,102,190,102,191,17,191,210,191,210,191,17,215,43,191,210,215,43,215,186,191,210,186,142,189,122,191,210,189,122,190,102,191,210,162,225,165,191,131,9,123,-4,160,1,58,17,61,113,60,137,60,137,62,164,58,209,58,209,62,164,70,186,58,209,70,186,90,225,90,225,70,186,82,202,90,225,82,202,98,212,58,17,60,137,58,209,58,17,58,209,35,42,35,42,58,209,35,185,35,42,35,185,20,75,20,75,35,185,20,153,20,75,20,153,15,114,61,113,58,17,64,91,162,225,130,215,140,211,93,25,123,-4,101,18,97,253,151,328,77,253, 200,253,138,337,107,337,45,253,62,253,123,305,184,253,16383,16383,235,116,230,154,215,186,191,210,162,225,127,230,90,225,58,209,35,185,20,153,15,114,20,75,35,42,58,17,88,1,123,-4,160,1,191,17,215,43,230,76,235,116,16383,16383,190,102,187,70,180,44,168,25,151,13,131,9,120,10,110,13,101,18,93,25,86,34,76,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,98,212,118,216,130,215,140,211,149,206,158,199,165,191,174,177,181,161,186,142,189,122,190,102, 45,253,62,253,107,337,107,337,62,253,123,305,107,337,123,305,138,337,138,337,123,305,184,253,138,337,184,253,200,253,64,91,58,17,69,70,69,70,58,17,88,1,69,70,88,1,76,51,76,51,88,1,86,34,93,25,86,34,88,1,93,25,88,1,123,-4,162,225,127,230,130,215,130,215,127,230,118,216,98,212,118,216,127,230,98,212,127,230,90,225,187,70,180,44,191,17,191,17,180,44,168,25,191,17,168,25,160,1,160,1,168,25,151,13,160,1,151,13,131,9,131,9,120,10,123,-4,123,-4,120,10,110,13,123,-4,110,13,101,18,140,211,149,206,162,225,162,225,149,206,158,199,162,225,158,199,165,191,165,191,174,177,191,210,191,210,174,177,181,161,191,210,181,161,186,142,230,154,215,186,215,43,230,154,215,43,230,76,230,154,230,76,235,116,187,70,191,17,190,102,190,102,191,17,191,210,191,210,191,17,215,43,191,210,215,43,215,186,191,210,186,142,189,122,191,210,189,122,190,102,191,210,162,225,165,191,131,9,123,-4,160,1,58,17,61,113,60,137,60,137,62,164,58,209,58,209,62,164,70,186,58,209,70,186,90,225,90,225,70,186,82,202,90,225,82,202,98,212,58,17,60,137,58,209,58,17,58,209,35,42,35,42,58,209,35,185,35,42,35,185,20,75,20,75,35,185,20,153,20,75,20,153,15,114,61,113,58,17,64,91,162,225,130,215,140,211,93,25,123,-4,101,18, 190,319,185,309,181,302,176,297,170,295,164,294,159,294,154,295,149,297,137,301,126,307,118,311,104,315,97,316,90,316,76,314,64,308,54,298,46,284,40,266,55,266,58,274,63,281,68,285,73,288,80,289,84,289,92,287,100,283,112,278,123,273,131,269,139,267,145,266,152,266,168,268,180,274,190,284,198,299,205,319,16383,16383,235,116,230,154,215,186,191,210,162,225,127,230,90,225,58,209,35,185,20,153,15,114,20,75,35,42,58,17,88,1,123,-4,160,1,191,17,215,43,230,76,235,116,16383,16383,190,102,187,70,180,44,168,25,151,13,131,9,120,10,110,13,101,18,93,25,86,34,76,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,98,212,118,216,130,215,140,211,149,206,158,199,165,191,174,177,181,161,186,142,189,122,190,102, 58,274,63,281,64,308,64,308,63,281,68,285,64,308,68,285,76,314,76,314,68,285,73,288,76,314,73,288,80,289,80,289,84,289,90,316,90,316,84,289,88,288,90,316,88,288,92,287,55,266,58,274,64,308,55,266,64,308,54,298,55,266,54,298,46,284,55,266,46,284,40,266,90,316,92,287,97,316,97,316,92,287,96,285,97,316,96,285,100,283,100,283,112,278,104,315,104,315,112,278,111,313,90,316,76,314,80,289,104,315,97,316,100,283,111,313,112,278,118,311,118,311,112,278,123,273,118,311,123,273,126,307,126,307,123,273,131,269,126,307,131,269,137,301,137,301,131,269,139,267,137,301,139,267,143,299,143,299,139,267,145,266,143,299,145,266,149,297,149,297,145,266,152,266,149,297,152,266,154,295,154,295,152,266,168,268,154,295,168,268,159,294,159,294,168,268,164,294,170,295,164,294,168,268,170,295,168,268,180,274,190,319,185,309,190,284,190,319,190,284,198,299,190,319,198,299,205,319,181,302,176,297,180,274,181,302,180,274,190,284,181,302,190,284,185,309,64,91,58,17,69,70,69,70,58,17,88,1,69,70,88,1,76,51,76,51,88,1,86,34,93,25,86,34,88,1,93,25,88,1,123,-4,162,225,127,230,130,215,130,215,127,230,118,216,98,212,118,216,127,230,98,212,127,230,90,225,187,70,180,44,191,17,191,17,180,44,168,25,191,17,168,25,160,1,160,1,168,25,151,13,160,1,151,13,131,9,131,9,120,10,123,-4,123,-4,120,10,110,13,123,-4,110,13,101,18,140,211,149,206,162,225,162,225,149,206,158,199,162,225,158,199,165,191,165,191,174,177,191,210,191,210,174,177,181,161,191,210,181,161,186,142,230,154,215,186,215,43,230,154,215,43,230,76,230,154,230,76,235,116,187,70,191,17,190,102,190,102,191,17,191,210,191,210,191,17,215,43,191,210,215,43,215,186,191,210,186,142,189,122,191,210,189,122,190,102,191,210,162,225,165,191,131,9,123,-4,160,1,58,17,61,113,60,137,60,137,62,164,58,209,58,209,62,164,70,186,58,209,70,186,90,225,90,225,70,186,82,202,90,225,82,202,98,212,58,17,60,137,58,209,58,17,58,209,35,42,35,42,58,209,35,185,35,42,35,185,20,75,20,75,35,185,20,153,20,75,20,153,15,114,61,113,58,17,64,91,162,225,130,215,140,211,93,25,123,-4,101,18,170,295,180,274,176,297, 197,286,196,294,192,301,186,306,180,310,172,311,164,310,157,306,152,301,149,294,147,286,149,278,152,272,157,266,164,263,171,262,179,263,186,266,192,272,196,278,197,286,16383,16383,98,286,96,294,93,301,87,306,80,310,73,311,65,310,58,306,53,301,49,294,48,286,49,278,53,272,58,266,64,263,72,262,80,263,87,266,93,272,96,278,98,286,16383,16383,235,116,230,154,215,186,191,210,162,225,127,230,90,225,58,209,35,185,20,153,15,114,20,75,35,42,58,17,88,1,123,-4,160,1,191,17,215,43,230,76,235,116,16383,16383,190,102,187,70,180,44,168,25,151,13,131,9,120,10,110,13,101,18,93,25,86,34,76,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,98,212,118,216,130,215,140,211,149,206,158,199,165,191,174,177,181,161,186,142,189,122,190,102, 48,286,49,278,49,294,49,294,49,278,53,272,49,294,53,272,53,301,53,301,53,272,58,266,53,301,58,266,58,306,58,306,58,266,64,263,58,306,64,263,65,310,65,310,64,263,72,262,65,310,72,262,73,311,73,311,72,262,80,263,73,311,80,263,80,310,80,310,80,263,87,266,80,310,87,266,87,306,87,306,87,266,93,272,87,306,93,272,93,301,93,301,93,272,96,278,93,301,96,278,96,294,96,294,96,278,98,286,64,91,58,17,69,70,69,70,58,17,88,1,69,70,88,1,76,51,76,51,88,1,86,34,93,25,86,34,88,1,93,25,88,1,123,-4,162,225,127,230,130,215,130,215,127,230,118,216,98,212,118,216,127,230,98,212,127,230,90,225,147,286,149,278,149,294,149,294,149,278,152,272,149,294,152,272,152,301,152,301,152,272,157,266,152,301,157,266,157,306,157,306,157,266,164,263,157,306,164,263,164,310,164,310,164,263,171,262,164,310,171,262,172,311,172,311,171,262,179,263,172,311,179,263,180,310,180,310,179,263,186,266,180,310,186,266,186,306,186,306,186,266,192,272,186,306,192,272,192,301,192,301,192,272,196,278,192,301,196,278,196,294,196,294,196,278,197,286,187,70,180,44,191,17,191,17,180,44,168,25,191,17,168,25,160,1,160,1,168,25,151,13,160,1,151,13,131,9,131,9,120,10,123,-4,123,-4,120,10,110,13,123,-4,110,13,101,18,140,211,149,206,162,225,162,225,149,206,158,199,162,225,158,199,165,191,165,191,174,177,191,210,191,210,174,177,181,161,191,210,181,161,186,142,230,154,215,186,215,43,230,154,215,43,230,76,230,154,230,76,235,116,187,70,191,17,190,102,190,102,191,17,191,210,191,210,191,17,215,43,191,210,215,43,215,186,191,210,186,142,189,122,191,210,189,122,190,102,191,210,162,225,165,191,131,9,123,-4,160,1,58,17,61,113,60,137,60,137,62,164,58,209,58,209,62,164,70,186,58,209,70,186,90,225,90,225,70,186,82,202,90,225,82,202,98,212,58,17,60,137,58,209,58,17,58,209,35,42,35,42,58,209,35,185,35,42,35,185,20,75,20,75,35,185,20,153,20,75,20,153,15,114,61,113,58,17,64,91,162,225,130,215,140,211,93,25,123,-4,101,18, 169,229,168,238,164,246,158,252,150,256,142,258,133,256,125,252,119,246,115,239,113,230,115,221,119,214,125,208,132,204,141,203,150,204,158,208,164,214,168,221,169,229,16383,16383,267,110,267,143,15,143,15,110,16383,16383,169,22,168,31,164,38,158,45,150,49,142,50,133,49,125,45,119,39,115,31,113,22,115,14,119,6,125,0,132,-3,141,-4,150,-3,158,0,164,6,168,13,169,22, 113,230,115,221,115,239,115,239,115,221,119,214,115,239,119,214,119,246,119,246,119,214,125,208,119,246,125,208,125,252,125,252,125,208,132,204,125,252,132,204,133,256,133,256,132,204,141,203,133,256,141,203,142,258,142,258,141,203,150,204,142,258,150,204,150,256,150,256,150,204,158,208,150,256,158,208,158,252,158,252,158,208,164,214,158,252,164,214,164,246,164,246,164,214,168,221,164,246,168,221,168,238,168,238,168,221,169,229,15,143,15,110,267,110,15,143,267,110,267,143,113,22,115,14,115,31,115,31,115,14,119,6,115,31,119,6,119,39,119,39,119,6,125,0,119,39,125,0,125,45,125,45,125,0,132,-3,125,45,132,-3,133,49,133,49,132,-3,141,-4,133,49,141,-4,142,50,142,50,141,-4,150,-3,142,50,150,-3,150,49,150,49,150,-3,158,0,150,49,158,0,158,45,158,45,158,0,164,6,158,45,164,6,164,38,164,38,164,6,168,13,164,38,168,13,168,31,168,31,168,13,169,22, 219,276,199,276,171,221,161,224,152,227,143,229,134,230,124,230,88,224,58,208,35,184,20,152,15,113,15,100,17,87,20,74,30,50,35,42,40,36,46,29,53,22,63,14,26,-55,45,-55,77,6,87,1,105,-3,114,-4,123,-4,159,1,190,18,214,44,229,78,235,117,233,141,227,162,218,181,204,198,186,213,16383,16383,79,46,72,63,66,81,63,99,60,118,60,138,62,164,70,186,82,202,99,212,118,216,127,215,135,213,143,210,151,205,158,198,16383,16383,170,183,178,167,183,152,187,136,189,120,190,102,187,69,180,44,168,25,151,13,131,9,121,10,112,12,104,16,97,22,89,30, 63,14,63,14,45,-55,63,14,45,-55,77,6,63,14,77,6,63,99,63,14,63,99,60,118,63,14,60,118,60,138,63,14,60,138,58,208,63,14,58,208,53,22,58,208,35,184,35,42,58,208,35,42,40,36,58,208,40,36,46,29,58,208,46,29,53,22,35,184,20,152,20,74,35,184,20,74,25,62,35,184,25,62,30,50,35,184,30,50,35,42,20,152,15,113,15,100,20,152,15,100,17,87,20,152,17,87,20,74,124,230,118,216,127,215,124,230,127,215,134,230,134,230,127,215,135,213,134,230,135,213,143,229,143,229,135,213,143,210,143,229,143,210,152,227,152,227,143,210,151,205,152,227,151,205,158,198,187,69,180,44,190,18,190,18,180,44,168,25,190,18,168,25,159,1,159,1,168,25,151,13,159,1,151,13,131,9,131,9,121,10,123,-4,123,-4,121,10,114,-4,112,12,104,16,105,-3,112,12,105,-3,114,-4,112,12,114,-4,121,10,87,1,96,-1,89,30,89,30,96,-1,97,22,97,22,96,-1,105,-3,97,22,105,-3,104,16,161,224,158,198,170,183,161,224,170,183,171,221,171,221,170,183,178,167,171,221,178,167,186,213,186,213,178,167,183,152,186,213,183,152,187,136,199,276,171,221,186,213,199,276,186,213,219,276,158,198,79,46,89,30,158,198,89,30,170,183,79,46,72,63,77,6,79,46,77,6,87,1,79,46,87,1,89,30,66,81,63,99,77,6,66,81,77,6,72,63,229,78,235,117,233,141,229,78,233,141,227,162,229,78,227,162,218,181,229,78,218,181,214,44,187,69,190,18,190,102,190,102,190,18,204,198,204,198,190,18,214,44,204,198,214,44,218,181,186,213,187,136,204,198,204,198,187,136,189,120,204,198,189,120,190,102,131,9,123,-4,159,1,70,186,82,202,88,224,88,224,82,202,99,212,88,224,99,212,124,230,124,230,99,212,118,216,60,138,62,164,58,208,58,208,62,164,70,186,58,208,70,186,88,224,45,-55,63,14,26,-55,152,227,158,198,161,224, 170,253,97,328,92,332,88,335,84,337,80,338,75,339,69,338,64,336,61,333,58,329,57,323,58,318,60,314,63,309,67,305,73,301,150,253,16383,16383,240,25,237,25,225,26,217,29,212,34,209,42,209,225,129,225,129,217,145,215,155,212,162,206,165,197,166,184,166,59,164,53,162,48,159,43,147,34,139,29,130,26,121,25,113,24,102,26,92,31,84,40,79,51,78,64,78,225,4,225,4,218,17,216,26,213,32,207,35,197,36,185,36,59,38,38,46,20,58,6,75,-1,97,-4,109,-3,123,0,138,8,153,21,168,38,169,38,169,-2,171,-3,186,1,199,6,225,14,240,18, 150,253,170,253,97,328,150,253,97,328,92,332,150,253,92,332,88,335,150,253,88,335,84,337,150,253,84,337,80,338,150,253,80,338,75,339,150,253,75,339,73,301,57,323,58,318,58,329,58,329,58,318,60,314,58,329,60,314,61,333,61,333,60,314,63,309,61,333,63,309,64,336,64,336,63,309,67,305,64,336,67,305,69,338,69,338,67,305,73,301,69,338,73,301,75,339,78,225,4,225,17,216,78,225,17,216,26,213,78,225,26,213,32,207,78,225,32,207,35,197,78,225,35,197,36,185,78,225,36,185,38,38,78,225,38,38,46,20,78,225,46,20,58,6,78,225,58,6,75,-1,78,225,75,-1,78,64,164,53,162,48,168,38,168,38,162,48,159,43,168,38,159,43,155,40,155,40,147,34,153,21,153,21,147,34,139,29,153,21,139,29,138,8,138,8,139,29,130,26,138,8,130,26,123,0,123,0,130,26,121,25,123,0,121,25,113,24,113,24,102,26,109,-3,109,-3,102,26,97,-4,97,-4,102,26,92,31,97,-4,92,31,84,40,97,-4,84,40,79,51,97,-4,79,51,75,-1,78,64,75,-1,79,51,113,24,109,-3,123,0,166,184,168,38,209,225,209,225,168,38,169,38,209,225,169,38,171,-3,171,-3,169,38,169,-2,168,38,166,184,166,69,168,38,166,69,166,59,168,38,166,59,164,53,155,40,153,21,168,38,225,26,217,29,225,14,225,14,217,29,212,34,225,14,212,34,212,10,212,10,212,34,209,42,212,10,209,42,199,6,199,6,209,42,209,54,199,6,209,54,209,225,209,225,171,-3,186,1,209,225,186,1,199,6,209,225,129,225,145,215,209,225,145,215,155,212,209,225,155,212,162,206,209,225,162,206,165,197,209,225,165,197,166,184,237,25,225,26,225,14,237,25,225,14,240,18,237,25,240,18,240,25,38,38,36,185,36,59,145,215,129,225,129,217,17,216,4,225,4,218, 78,253,98,253,175,302,181,306,185,310,188,314,189,318,190,323,189,329,187,333,183,336,179,338,172,339,168,338,165,337,161,335,156,332,151,328,16383,16383,240,25,237,25,225,26,217,29,212,34,209,42,209,225,129,225,129,217,145,215,155,212,162,206,165,197,166,184,166,59,164,53,162,48,159,43,147,34,139,29,130,26,121,25,113,24,102,26,92,31,84,40,79,51,78,64,78,225,4,225,4,218,17,216,26,213,32,207,35,197,36,185,36,59,38,38,46,20,58,6,75,-1,97,-4,109,-3,123,0,138,8,153,21,168,38,169,38,169,-2,171,-3,186,1,199,6,225,14,240,18, 209,225,129,225,145,215,209,225,145,215,155,212,209,225,155,212,162,206,209,225,162,206,165,197,209,225,165,197,166,184,209,225,166,184,168,38,209,225,168,38,169,38,209,225,169,38,171,-3,209,225,171,-3,186,1,209,225,186,1,199,6,209,225,199,6,209,54,166,184,166,69,168,38,237,25,225,26,225,14,237,25,225,14,240,18,237,25,240,18,240,25,209,54,199,6,209,42,209,42,199,6,212,10,209,42,212,10,212,34,212,34,212,10,225,14,212,34,225,14,217,29,217,29,225,14,225,26,172,339,175,302,179,338,179,338,175,302,181,306,179,338,181,306,183,336,183,336,181,306,185,310,183,336,185,310,187,333,187,333,185,310,188,314,187,333,188,314,189,329,189,329,188,314,189,318,189,329,189,318,190,323,175,302,172,339,168,338,175,302,168,338,165,337,175,302,165,337,161,335,175,302,161,335,156,332,175,302,156,332,151,328,175,302,151,328,98,253,78,225,4,225,17,216,78,225,17,216,26,213,78,225,26,213,32,207,78,225,32,207,35,197,78,225,35,197,36,185,78,225,36,185,38,38,78,225,38,38,46,20,78,225,46,20,58,6,78,225,58,6,75,-1,78,225,75,-1,78,64,164,53,162,48,168,38,168,38,162,48,159,43,168,38,159,43,155,40,155,40,147,34,153,21,153,21,147,34,139,29,153,21,139,29,138,8,138,8,139,29,130,26,138,8,130,26,123,0,123,0,130,26,121,25,123,0,121,25,113,24,113,24,102,26,109,-3,109,-3,102,26,97,-4,97,-4,102,26,92,31,97,-4,92,31,84,40,97,-4,84,40,79,51,97,-4,79,51,75,-1,78,64,75,-1,79,51,113,24,109,-3,123,0,166,59,164,53,168,38,166,59,168,38,166,69,155,40,153,21,168,38,38,38,36,185,36,59,171,-3,169,38,169,-2,17,216,4,225,4,218,98,253,151,328,78,253,145,215,129,225,129,217, 200,253,138,337,107,337,45,253,62,253,123,305,184,253,16383,16383,240,25,237,25,225,26,217,29,212,34,209,42,209,225,129,225,129,217,145,215,155,212,162,206,165,197,166,184,166,59,164,53,162,48,159,43,147,34,139,29,130,26,121,25,113,24,102,26,92,31,84,40,79,51,78,64,78,225,4,225,4,218,17,216,26,213,32,207,35,197,36,185,36,59,38,38,46,20,58,6,75,-1,97,-4,109,-3,123,0,138,8,153,21,168,38,169,38,169,-2,171,-3,186,1,199,6,225,14,240,18, 209,225,129,225,145,215,209,225,145,215,155,212,209,225,155,212,162,206,209,225,162,206,165,197,209,225,165,197,166,184,209,225,166,184,168,38,209,225,168,38,169,38,209,225,169,38,171,-3,209,225,171,-3,186,1,209,225,186,1,199,6,209,225,199,6,209,54,166,184,166,69,168,38,237,25,225,26,225,14,237,25,225,14,240,18,237,25,240,18,240,25,209,54,199,6,209,42,209,42,199,6,212,10,209,42,212,10,212,34,212,34,212,10,225,14,212,34,225,14,217,29,217,29,225,14,225,26,45,253,62,253,107,337,107,337,62,253,123,305,107,337,123,305,138,337,138,337,123,305,184,253,138,337,184,253,200,253,78,225,4,225,17,216,78,225,17,216,26,213,78,225,26,213,32,207,78,225,32,207,35,197,78,225,35,197,36,185,78,225,36,185,38,38,78,225,38,38,46,20,78,225,46,20,58,6,78,225,58,6,75,-1,78,225,75,-1,78,64,164,53,162,48,168,38,168,38,162,48,159,43,168,38,159,43,155,40,155,40,147,34,153,21,153,21,147,34,139,29,153,21,139,29,138,8,138,8,139,29,130,26,138,8,130,26,123,0,123,0,130,26,121,25,123,0,121,25,113,24,113,24,102,26,109,-3,109,-3,102,26,97,-4,97,-4,102,26,92,31,97,-4,92,31,84,40,97,-4,84,40,79,51,97,-4,79,51,75,-1,78,64,75,-1,79,51,113,24,109,-3,123,0,166,59,164,53,168,38,166,59,168,38,166,69,155,40,153,21,168,38,38,38,36,185,36,59,171,-3,169,38,169,-2,17,216,4,225,4,218,145,215,129,225,129,217, 196,286,195,294,192,301,186,306,179,310,171,311,164,310,157,306,152,301,148,294,147,286,148,278,151,272,157,266,163,263,171,262,179,263,186,266,192,272,195,278,196,286,16383,16383,97,286,96,294,92,301,87,306,80,310,72,311,64,310,58,306,52,301,49,294,47,286,49,278,52,272,57,266,64,263,71,262,79,263,86,266,92,272,96,278,97,286,16383,16383,240,25,237,25,225,26,217,29,212,34,209,42,209,225,129,225,129,217,145,215,155,212,162,206,165,197,166,184,166,59,164,53,162,48,159,43,147,34,139,29,130,26,121,25,113,24,102,26,92,31,84,40,79,51,78,64,78,225,4,225,4,218,17,216,26,213,32,207,35,197,36,185,36,59,38,38,46,20,58,6,75,-1,97,-4,109,-3,123,0,138,8,153,21,168,38,169,38,169,-2,171,-3,186,1,199,6,225,14,240,18, 209,225,129,225,145,215,209,225,145,215,155,212,209,225,155,212,162,206,209,225,162,206,165,197,209,225,165,197,166,184,209,225,166,184,168,38,209,225,168,38,169,38,209,225,169,38,171,-3,209,225,171,-3,186,1,209,225,186,1,199,6,209,225,199,6,209,54,166,184,166,69,168,38,237,25,225,26,225,14,237,25,225,14,240,18,237,25,240,18,240,25,209,54,199,6,209,42,209,42,199,6,212,10,209,42,212,10,212,34,212,34,212,10,225,14,212,34,225,14,217,29,217,29,225,14,225,26,147,286,148,278,148,294,148,294,148,278,151,272,148,294,151,272,152,301,152,301,151,272,157,266,152,301,157,266,157,306,157,306,157,266,163,263,157,306,163,263,164,310,164,310,163,263,171,262,164,310,171,262,171,311,171,311,171,262,179,263,171,311,179,263,179,310,179,310,179,263,186,266,179,310,186,266,186,306,186,306,186,266,192,272,186,306,192,272,192,301,192,301,192,272,195,278,192,301,195,278,195,294,195,294,195,278,196,286,47,286,49,278,49,294,49,294,49,278,52,272,49,294,52,272,52,301,52,301,52,272,57,266,52,301,57,266,58,306,58,306,57,266,64,263,58,306,64,263,64,310,64,310,64,263,71,262,64,310,71,262,72,311,72,311,71,262,79,263,72,311,79,263,80,310,80,310,79,263,86,266,80,310,86,266,87,306,87,306,86,266,92,272,87,306,92,272,92,301,92,301,92,272,96,278,92,301,96,278,96,294,96,294,96,278,97,286,78,225,4,225,17,216,78,225,17,216,26,213,78,225,26,213,32,207,78,225,32,207,35,197,78,225,35,197,36,185,78,225,36,185,38,38,78,225,38,38,46,20,78,225,46,20,58,6,78,225,58,6,75,-1,78,225,75,-1,78,64,164,53,162,48,168,38,168,38,162,48,159,43,168,38,159,43,155,40,155,40,147,34,153,21,153,21,147,34,139,29,153,21,139,29,138,8,138,8,139,29,130,26,138,8,130,26,123,0,123,0,130,26,121,25,123,0,121,25,113,24,113,24,102,26,109,-3,109,-3,102,26,97,-4,97,-4,102,26,92,31,97,-4,92,31,84,40,97,-4,84,40,79,51,97,-4,79,51,75,-1,78,64,75,-1,79,51,113,24,109,-3,123,0,166,59,164,53,168,38,166,59,168,38,166,69,155,40,153,21,168,38,38,38,36,185,36,59,171,-3,169,38,169,-2,17,216,4,225,4,218,145,215,129,225,129,217, 71,253,92,253,169,302,174,306,178,310,181,314,183,318,184,323,183,329,181,333,177,336,172,338,166,339,158,337,154,335,150,332,145,328,16383,16383,238,225,171,225,171,218,179,217,186,216,190,213,193,210,194,205,194,202,193,201,193,198,192,196,143,59,88,184,82,196,81,201,81,204,82,209,85,212,90,215,98,217,109,218,109,225,7,225,7,218,14,217,21,214,26,211,30,206,33,200,99,60,105,47,111,35,116,24,121,9,119,2,116,-8,112,-21,106,-34,100,-44,96,-51,85,-62,80,-65,75,-66,71,-66,69,-65,66,-64,62,-63,63,-63,57,-60,52,-58,42,-56,36,-56,30,-57,24,-60,19,-65,16,-72,15,-79,17,-88,21,-96,28,-102,38,-106,50,-108,71,-105,90,-94,106,-76,122,-49,137,-11,213,192,217,202,221,208,226,213,231,216,238,218, 166,339,169,302,172,338,172,338,169,302,174,306,172,338,174,306,177,336,177,336,174,306,178,310,177,336,178,310,181,333,181,333,178,310,181,314,181,333,181,314,183,329,183,329,181,314,183,318,183,329,183,318,184,323,169,302,166,339,162,338,169,302,162,338,158,337,169,302,158,337,154,335,169,302,154,335,150,332,169,302,150,332,145,328,169,302,145,328,92,253,90,-57,85,-62,90,-94,90,-94,85,-62,80,-65,90,-94,80,-65,75,-66,75,-66,73,-66,90,-94,90,-94,73,-66,71,-105,90,-57,106,-76,96,-51,96,-51,106,-76,100,-44,106,-34,100,-44,106,-76,106,-34,106,-76,122,-49,143,59,88,184,99,60,143,59,99,60,105,47,143,59,105,47,111,35,143,59,111,35,116,24,143,59,116,24,119,15,143,59,119,15,121,9,143,59,121,9,122,-49,143,59,122,-49,137,-11,143,59,137,-11,213,192,143,59,213,192,192,196,122,-49,121,9,119,2,99,60,88,184,86,188,99,60,86,188,84,192,99,60,84,192,82,196,99,60,82,196,81,201,99,60,81,201,33,200,33,200,81,201,81,204,81,204,82,209,33,200,33,200,82,209,85,212,33,200,85,212,109,225,109,225,85,212,90,215,109,225,90,215,98,217,194,202,193,201,213,192,213,192,193,201,193,198,213,192,193,198,192,196,238,225,171,225,179,217,238,225,179,217,186,216,238,225,186,216,190,213,238,225,190,213,193,210,238,225,193,210,194,205,238,225,194,205,226,213,238,225,226,213,231,216,238,225,231,216,238,218,194,205,213,192,217,202,194,205,217,202,221,208,194,205,221,208,226,213,194,204,194,202,213,192,194,204,213,192,194,205,122,-49,119,2,116,-8,122,-49,116,-8,112,-21,122,-49,112,-21,106,-34,71,-105,73,-66,71,-66,71,-105,71,-66,69,-65,71,-105,69,-65,66,-64,71,-105,66,-64,63,-63,71,-105,63,-63,57,-60,71,-105,57,-60,52,-58,71,-105,52,-58,50,-108,52,-58,47,-57,50,-108,50,-108,47,-57,42,-56,50,-108,42,-56,38,-106,38,-106,42,-56,36,-56,38,-106,36,-56,30,-57,38,-106,30,-57,28,-102,28,-102,30,-57,24,-60,28,-102,24,-60,21,-96,21,-96,24,-60,19,-65,21,-96,19,-65,17,-88,17,-88,19,-65,16,-72,17,-88,16,-72,15,-79,98,217,109,218,109,225,109,225,7,225,14,217,109,225,14,217,21,214,109,225,21,214,26,211,109,225,26,211,30,206,109,225,30,206,33,200,66,-64,62,-63,63,-63,14,217,7,225,7,218,90,-57,90,-94,106,-76,179,217,171,225,171,218,92,253,145,328,71,253, 79,339,76,342,63,337,51,333,38,329,23,325,4,320,4,311,8,311,9,312,13,312,23,311,30,308,35,303,37,295,37,-76,34,-86,27,-92,17,-96,2,-98,2,-107,123,-107,123,-98,104,-97,91,-93,84,-87,80,-75,79,-59,79,17,90,8,99,2,108,-1,118,-3,130,-4,164,1,193,19,215,47,230,82,235,123,231,160,221,190,204,212,180,225,151,230,135,229,120,224,106,216,92,205,79,190,16383,16383,79,166,83,175,91,184,103,192,117,198,131,200,152,196,170,185,182,166,189,140,192,107,189,75,181,49,169,29,152,16,131,11,117,13,103,19,91,27,82,36,79,45, 34,-86,27,-92,123,-107,123,-107,27,-92,17,-96,123,-107,17,-96,2,-98,8,311,9,312,23,325,23,325,9,312,11,312,23,325,11,312,13,312,13,312,23,311,23,325,23,325,23,311,38,329,23,325,4,320,6,311,23,325,6,311,8,311,30,308,35,303,38,329,38,329,35,303,37,295,38,329,37,295,37,284,80,-75,37,284,37,-63,80,-75,37,-63,84,-87,84,-87,37,-63,91,-93,79,190,79,339,76,342,79,190,76,342,79,-59,79,190,79,-59,79,166,79,190,79,166,92,205,235,123,231,160,230,82,230,82,231,160,221,190,230,82,221,190,215,47,215,47,221,190,204,212,215,47,204,212,193,19,193,19,204,212,192,107,193,19,192,107,189,75,193,19,189,75,181,49,152,196,170,185,180,225,180,225,170,185,182,166,180,225,182,166,204,212,204,212,182,166,189,140,204,212,189,140,192,107,135,229,131,200,152,196,135,229,152,196,151,230,151,230,152,196,180,225,108,-1,118,-3,117,13,117,13,118,-3,131,11,152,16,131,11,164,1,152,16,164,1,169,29,169,29,164,1,193,19,169,29,193,19,181,49,131,11,118,-3,130,-4,131,11,130,-4,164,1,123,-107,123,-98,104,-97,123,-107,104,-97,91,-93,123,-107,91,-93,37,-76,123,-107,37,-76,34,-86,82,36,79,45,90,8,90,8,79,45,79,17,80,-75,79,-59,51,333,80,-75,51,333,38,329,63,337,51,333,79,-59,63,337,79,-59,76,342,83,175,91,184,92,205,92,205,91,184,103,192,92,205,103,192,106,216,106,216,103,192,117,198,106,216,117,198,120,224,120,224,117,198,131,200,120,224,131,200,135,229,82,36,90,8,91,27,91,27,90,8,99,2,91,27,99,2,103,19,103,19,99,2,108,-1,103,19,108,-1,117,13,92,205,79,166,83,175,6,311,4,320,4,311,123,-107,2,-98,2,-107,37,-76,91,-93,37,-63,37,284,80,-75,38,329,38,329,23,311,30,308, 198,286,197,294,193,301,188,306,181,310,173,311,165,310,159,306,153,301,150,294,148,286,150,278,153,272,158,266,165,263,172,262,180,263,187,266,193,272,197,278,198,286,16383,16383,99,286,97,294,94,301,88,306,81,310,74,311,66,310,59,306,54,301,50,294,49,286,50,278,54,272,59,266,65,263,73,262,81,263,88,266,94,272,97,278,99,286,16383,16383,238,225,171,225,171,218,179,217,186,216,190,213,193,210,194,205,194,202,193,201,193,198,192,196,143,59,88,184,82,196,81,201,81,204,82,209,85,212,90,215,98,217,109,218,109,225,7,225,7,218,14,217,21,214,26,211,30,206,33,200,99,60,105,47,111,35,116,24,121,9,119,2,116,-8,112,-21,106,-34,100,-44,96,-51,85,-62,80,-65,75,-66,71,-66,69,-65,66,-64,62,-63,63,-63,57,-60,52,-58,42,-56,36,-56,30,-57,24,-60,19,-65,16,-72,15,-79,17,-88,21,-96,28,-102,38,-106,50,-108,71,-105,90,-94,106,-76,122,-49,137,-11,213,192,217,202,221,208,226,213,231,216,238,218, 148,286,150,278,150,294,150,294,150,278,153,272,150,294,153,272,153,301,153,301,153,272,158,266,153,301,158,266,159,306,159,306,158,266,165,263,159,306,165,263,165,310,165,310,165,263,172,262,165,310,172,262,173,311,173,311,172,262,180,263,173,311,180,263,181,310,181,310,180,263,187,266,181,310,187,266,188,306,188,306,187,266,193,272,188,306,193,272,193,301,193,301,193,272,197,278,193,301,197,278,197,294,197,294,197,278,198,286,49,286,50,278,50,294,50,294,50,278,54,272,50,294,54,272,54,301,54,301,54,272,59,266,54,301,59,266,59,306,59,306,59,266,65,263,59,306,65,263,66,310,66,310,65,263,73,262,66,310,73,262,74,311,74,311,73,262,81,263,74,311,81,263,81,310,81,310,81,263,88,266,81,310,88,266,88,306,88,306,88,266,94,272,88,306,94,272,94,301,94,301,94,272,97,278,94,301,97,278,97,294,97,294,97,278,99,286,90,-57,85,-62,90,-94,90,-94,85,-62,80,-65,90,-94,80,-65,75,-66,75,-66,73,-66,90,-94,90,-94,73,-66,71,-105,90,-57,106,-76,96,-51,96,-51,106,-76,100,-44,106,-34,100,-44,106,-76,106,-34,106,-76,122,-49,143,59,88,184,99,60,143,59,99,60,105,47,143,59,105,47,111,35,143,59,111,35,116,24,143,59,116,24,119,15,143,59,119,15,121,9,143,59,121,9,122,-49,143,59,122,-49,137,-11,143,59,137,-11,213,192,143,59,213,192,192,196,122,-49,121,9,119,2,99,60,88,184,86,188,99,60,86,188,84,192,99,60,84,192,82,196,99,60,82,196,81,201,99,60,81,201,33,200,33,200,81,201,81,204,81,204,82,209,33,200,33,200,82,209,85,212,33,200,85,212,109,225,109,225,85,212,90,215,109,225,90,215,98,217,194,202,193,201,213,192,213,192,193,201,193,198,213,192,193,198,192,196,238,225,171,225,179,217,238,225,179,217,186,216,238,225,186,216,190,213,238,225,190,213,193,210,238,225,193,210,194,205,238,225,194,205,226,213,238,225,226,213,231,216,238,225,231,216,238,218,194,205,213,192,217,202,194,205,217,202,221,208,194,205,221,208,226,213,194,204,194,202,213,192,194,204,213,192,194,205,122,-49,119,2,116,-8,122,-49,116,-8,112,-21,122,-49,112,-21,106,-34,71,-105,73,-66,71,-66,71,-105,71,-66,69,-65,71,-105,69,-65,66,-64,71,-105,66,-64,63,-63,71,-105,63,-63,57,-60,71,-105,57,-60,52,-58,71,-105,52,-58,50,-108,52,-58,47,-57,50,-108,50,-108,47,-57,42,-56,50,-108,42,-56,38,-106,38,-106,42,-56,36,-56,38,-106,36,-56,30,-57,38,-106,30,-57,28,-102,28,-102,30,-57,24,-60,28,-102,24,-60,21,-96,21,-96,24,-60,19,-65,21,-96,19,-65,17,-88,17,-88,19,-65,16,-72,17,-88,16,-72,15,-79,98,217,109,218,109,225,109,225,7,225,14,217,109,225,14,217,21,214,109,225,21,214,26,211,109,225,26,211,30,206,109,225,30,206,33,200,66,-64,62,-63,63,-63,14,217,7,225,7,218,90,-57,90,-94,106,-76,179,217,171,225,171,218, 166,253,94,328,89,332,85,335,81,337,73,339,66,338,61,336,58,333,55,329,55,318,57,314,60,309,70,301,147,253, 147,253,166,253,94,328,147,253,94,328,89,332,147,253,89,332,85,335,147,253,85,335,81,337,147,253,81,337,77,338,147,253,77,338,73,339,147,253,73,339,70,301,55,323,55,318,55,329,55,329,55,318,57,314,55,329,57,314,58,333,58,333,57,314,60,309,58,333,60,309,61,336,61,336,60,309,65,305,61,336,65,305,66,338,66,338,65,305,70,301,66,338,70,301,73,339, 55,253,75,253,151,301,157,305,161,309,164,314,166,318,166,329,163,333,160,336,155,338,148,339,140,337,136,335,132,332,127,328, 148,339,151,301,155,338,155,338,151,301,157,305,155,338,157,305,160,336,160,336,157,305,161,309,160,336,161,309,163,333,163,333,161,309,164,314,163,333,164,314,166,329,166,329,164,314,166,318,166,329,166,318,166,323,151,301,148,339,144,338,151,301,144,338,140,337,151,301,140,337,136,335,151,301,136,335,132,332,151,301,132,332,127,328,151,301,127,328,75,253,127,328,55,253,75,253, 203,253,140,337,109,337,47,253,64,253,124,305,185,253, 47,253,64,253,109,337,109,337,64,253,124,305,109,337,124,305,140,337,140,337,124,305,185,253,140,337,185,253,203,253, 193,319,188,309,183,302,178,297,173,294,161,294,155,295,148,298,139,302,128,307,121,311,107,315,100,316,93,316,79,314,67,308,56,298,48,284,42,266,57,266,61,274,65,281,70,285,76,288,83,289,88,289,92,288,98,286,105,282,114,278,125,273,134,269,141,267,148,266,155,266,170,268,182,274,192,284,201,299,208,319, 61,274,65,281,67,308,67,308,65,281,70,285,67,308,70,285,79,314,79,314,70,285,76,288,79,314,76,288,83,289,83,289,88,289,93,316,93,316,88,289,92,288,93,316,92,288,98,286,57,266,61,274,67,308,57,266,67,308,56,298,57,266,56,298,48,284,57,266,48,284,42,266,155,266,170,268,161,294,161,294,170,268,166,294,173,294,166,294,170,268,173,294,170,268,182,274,193,319,188,309,192,284,193,319,192,284,201,299,193,319,201,299,208,319,183,302,178,297,182,274,183,302,182,274,192,284,183,302,192,284,188,309,114,313,114,278,121,311,121,311,114,278,125,273,121,311,125,273,128,307,128,307,125,273,134,269,128,307,134,269,139,302,139,302,134,269,141,267,139,302,141,267,148,298,148,298,141,267,148,266,148,298,148,266,155,295,155,295,148,266,155,266,155,295,155,266,161,294,93,316,98,286,100,316,100,316,98,286,105,282,100,316,105,282,107,315,107,315,105,282,114,278,107,315,114,278,114,313,93,316,79,314,83,289,173,294,182,274,178,297, 203,273,203,300,47,300,47,273, 203,273,203,300,47,300,203,273,47,300,47,273, 250,385,250,410,0,410,0,385, 250,385,250,410,0,410,250,385,0,410,0,385, 180,332,171,313,162,300,151,290,139,285,124,283,107,285,93,291,82,301,73,315,68,332,54,332,56,305,64,283,78,267,98,257,123,253,145,256,164,266,178,281,188,303,194,332, 107,285,93,291,98,257,98,257,93,291,82,301,98,257,82,301,78,267,78,267,82,301,73,315,78,267,73,315,68,332,171,313,162,300,164,266,164,266,162,300,151,290,164,266,151,290,145,256,145,256,151,290,139,285,145,256,139,285,124,283,124,283,107,285,123,253,123,253,107,285,98,257,68,332,54,332,56,305,68,332,56,305,64,283,68,332,64,283,78,267,180,332,171,313,178,281,180,332,178,281,188,303,180,332,188,303,194,332,124,283,123,253,145,256,171,313,164,266,178,281, 150,286,148,294,145,301,140,306,133,310,124,311,116,310,109,306,104,301,101,294,100,286,101,278,105,272,110,266,117,263,124,262,132,263,139,266,145,271,148,278,150,286, 124,262,132,263,133,310,133,310,132,263,139,266,133,310,139,266,140,306,140,306,139,266,145,271,140,306,145,271,145,301,145,301,145,271,148,278,145,301,148,278,148,294,148,294,148,278,150,286,101,294,101,278,104,301,104,301,101,278,105,272,104,301,105,272,109,306,109,306,105,272,110,266,109,306,110,266,116,310,116,310,110,266,117,263,116,310,117,263,124,311,124,311,117,263,124,262,124,311,124,262,133,310,101,278,101,294,100,286, 200,286,198,294,195,301,189,306,182,310,175,311,167,310,160,306,155,301,151,294,150,286,151,278,155,272,160,266,166,263,174,262,182,263,189,266,195,272,198,278,200,286,16383,16383,100,286,99,294,95,301,90,306,83,310,75,311,67,310,60,306,55,301,51,294,50,286,51,278,55,272,60,266,67,263,75,262,83,263,90,266,95,272,99,278,100,286, 75,311,75,262,83,310,83,310,75,262,83,263,83,310,83,263,90,306,90,306,83,263,90,266,90,306,90,266,95,301,95,301,90,266,95,272,95,301,95,272,99,294,99,294,95,272,99,278,99,294,99,278,100,286,50,286,51,278,51,294,51,294,51,278,55,272,51,294,55,272,55,301,55,301,55,272,60,266,55,301,60,266,60,306,60,306,60,266,67,263,60,306,67,263,67,310,67,310,67,263,75,262,67,310,75,262,75,311,150,286,151,278,151,294,151,294,151,278,155,272,151,294,155,272,155,301,155,301,155,272,160,266,155,301,160,266,160,306,160,306,160,266,166,263,160,306,166,263,167,310,167,310,166,263,174,262,167,310,174,262,175,311,175,311,174,262,182,263,175,311,182,263,182,310,182,310,182,263,189,266,182,310,189,266,189,306,189,306,189,266,195,272,189,306,195,272,195,301,195,301,195,272,198,278,195,301,198,278,198,294,198,294,198,278,200,286, 109,291,109,246,126,246,127,263,131,263,147,266,160,274,171,287,178,303,181,321,179,337,175,352,165,364,150,373,129,376,122,375,116,374,109,372,104,370,99,367,94,363,91,359,88,354,86,346,87,342,89,338,92,335,96,333,100,332,109,335,113,343,116,353,121,361,131,364,139,362,146,356,150,347,153,336,153,325,152,314,146,304,138,297,128,292,116,291, 131,364,129,376,122,375,131,364,122,375,121,361,131,364,150,373,129,376,121,361,122,375,116,353,116,353,122,375,116,374,116,353,116,374,113,343,113,343,116,374,109,372,113,343,109,372,109,335,109,335,109,372,104,370,109,335,104,370,100,332,100,332,104,370,99,367,100,332,99,367,96,333,96,333,99,367,94,363,96,333,94,363,92,335,92,335,94,363,91,359,92,335,91,359,89,338,89,338,91,359,88,354,89,338,88,354,87,342,87,342,88,354,87,350,87,342,87,350,86,346,181,321,179,337,178,303,178,303,179,337,175,352,178,303,175,352,171,287,171,287,175,352,165,364,171,287,165,364,160,274,160,274,165,364,153,325,153,336,153,325,165,364,153,336,165,364,150,373,153,336,150,373,150,347,150,373,131,364,139,362,150,373,139,362,146,356,150,373,146,356,150,347,152,314,146,304,147,266,152,314,147,266,160,274,152,314,160,274,153,325,126,246,127,263,128,292,128,292,127,263,131,263,128,292,131,263,138,297,138,297,131,263,147,266,138,297,147,266,146,304,126,246,128,292,116,291,126,246,116,291,109,291,126,246,109,291,109,246, 175,305,173,321,165,335,155,346,141,353,126,355,110,353,96,346,85,335,78,322,75,306,78,290,85,276,95,266,109,259,124,256,140,259,154,266,165,276,173,290,175,305,16383,16383,158,306,156,295,152,286,144,279,135,275,124,273,114,275,106,279,99,286,94,295,93,306,94,316,99,325,106,332,115,337,124,339,135,337,144,332,151,325,156,316,158,306, 156,295,152,286,154,266,154,266,152,286,144,279,154,266,144,279,140,259,140,259,144,279,135,275,140,259,135,275,124,256,124,256,135,275,124,273,126,355,124,339,135,337,126,355,135,337,141,353,141,353,135,337,144,332,141,353,144,332,155,346,155,346,144,332,151,325,155,346,151,325,156,316,175,305,173,321,173,290,173,290,173,321,165,335,173,290,165,335,165,276,165,276,165,335,158,306,156,316,158,306,165,335,156,316,165,335,155,346,156,295,154,266,165,276,156,295,165,276,158,306,99,325,106,332,110,353,110,353,106,332,115,337,110,353,115,337,126,355,126,355,115,337,124,339,96,346,85,335,93,306,96,346,93,306,94,316,96,346,94,316,99,325,96,346,99,325,110,353,99,286,94,295,95,266,95,266,94,295,93,306,114,275,106,279,109,259,114,275,109,259,124,256,114,275,124,256,124,273,99,286,95,266,109,259,99,286,109,259,106,279,75,306,78,290,78,322,78,322,78,290,85,276,78,322,85,276,85,335,85,335,85,276,95,266,85,335,95,266,93,306, 118,253,137,253,214,301,220,305,224,310,227,314,229,324,228,329,226,333,222,336,218,338,212,339,208,339,204,338,200,336,196,333,190,328,16383,16383,40,253,60,253,137,301,142,305,146,310,149,314,151,319,151,324,150,329,148,333,144,336,140,338,134,339,130,339,126,338,123,336,118,333,113,328, 212,339,214,301,218,338,218,338,214,301,220,305,218,338,220,305,222,336,222,336,220,305,224,310,222,336,224,310,226,333,226,333,224,310,227,314,226,333,227,314,228,329,228,329,227,314,228,319,228,329,228,319,229,324,214,301,212,339,208,339,214,301,208,339,204,338,214,301,204,338,200,336,214,301,200,336,196,333,214,301,196,333,190,328,214,301,190,328,137,253,134,339,137,301,140,338,140,338,137,301,142,305,140,338,142,305,144,336,144,336,142,305,146,310,144,336,146,310,148,333,148,333,146,310,149,314,148,333,149,314,150,329,150,329,149,314,151,319,150,329,151,319,151,324,137,301,134,339,130,339,137,301,130,339,126,338,137,301,126,338,123,336,137,301,123,336,118,333,137,301,118,333,113,328,137,301,113,328,60,253,60,253,113,328,40,253,137,253,190,328,118,253, 203,337,185,337,125,286,65,337,47,337,109,253,141,253, 203,337,185,337,141,253,141,253,185,337,125,286,141,253,125,286,109,253,109,253,125,286,65,337,109,253,65,337,47,337, 142,250,142,350,115,350,115,250, 142,250,142,350,115,350,142,250,115,350,115,250, 174,250,174,350,146,350,146,250,16383,16383,104,250,104,350,77,350,77,250, 146,350,146,250,174,250,146,350,174,250,174,350,77,350,77,250,104,250,77,350,104,250,104,350, 229,253,156,328,151,333,146,336,142,338,138,339,134,339,129,338,124,336,121,333,119,329,118,324,118,319,120,314,123,310,127,305,132,301,209,253,16383,16383,151,253,78,328,73,333,68,336,64,338,60,339,56,339,51,338,46,336,43,333,40,329,40,319,42,314,44,310,49,305,54,301,131,253, 209,253,229,253,156,328,209,253,156,328,151,333,209,253,151,333,146,336,209,253,146,336,142,338,209,253,142,338,138,339,209,253,138,339,134,339,209,253,134,339,132,301,118,324,118,319,119,329,119,329,118,319,120,314,119,329,120,314,121,333,121,333,120,314,123,310,121,333,123,310,124,336,124,336,123,310,127,305,124,336,127,305,129,338,129,338,127,305,132,301,129,338,132,301,134,339,131,253,151,253,78,328,131,253,78,328,73,333,131,253,73,333,68,336,131,253,68,336,64,338,131,253,64,338,60,339,131,253,60,339,56,339,131,253,56,339,54,301,40,324,40,319,40,329,40,329,40,319,42,314,40,329,42,314,43,333,43,333,42,314,44,310,43,333,44,310,46,336,46,336,44,310,49,305,46,336,49,305,51,338,51,338,49,305,54,301,51,338,54,301,56,339, 353,0,353,9,340,12,330,17,321,26,314,38,306,55,184,337,174,337,70,93,55,58,44,34,33,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,99,108,230,108,251,61,257,45,259,38,260,31,261,26,260,22,258,18,256,15,252,13,248,12,226,9,226,0,16383,16383,224,128,108,128,166,266, 55,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,174,337,76,51,99,108,174,337,99,108,108,128,108,128,99,108,230,108,108,128,230,108,224,128,224,128,230,108,306,55,224,128,306,55,184,337,258,18,256,15,353,0,353,0,256,15,252,13,353,0,252,13,248,12,261,26,353,0,330,17,261,26,330,17,321,26,261,26,321,26,314,38,261,26,314,38,306,55,261,26,306,55,260,31,306,55,230,108,251,61,306,55,251,61,254,53,306,55,254,53,257,45,306,55,257,45,259,38,306,55,259,38,260,31,174,337,108,128,166,266,174,337,166,266,224,128,174,337,224,128,184,337,70,93,55,58,72,30,70,93,74,43,75,47,70,93,75,47,76,51,70,93,76,51,174,337,340,12,330,17,353,0,340,12,353,0,353,9,260,22,258,18,353,0,260,22,353,0,261,26,226,9,226,0,353,0,226,9,353,0,248,12,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,44,34,107,0,44,34,33,20,107,0,33,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,55,58, 211,175,235,181,254,191,268,205,277,224,280,248,274,277,258,300,232,317,195,327,148,331,8,331,8,321,29,320,43,316,51,308,55,295,56,275,56,56,55,37,51,24,42,16,29,11,8,9,8,0,177,0,217,4,250,15,275,34,291,58,296,89,292,116,281,138,263,155,239,167,211,174,16383,16383,108,183,108,303,109,307,112,310,115,312,119,313,162,310,192,302,213,289,225,270,228,245,225,223,214,205,197,193,172,186,139,183,16383,16383,108,163,140,163,171,161,198,155,220,142,234,121,239,89,234,59,220,39,198,26,170,20,138,18,126,19,118,21,112,26,109,32,108,41, 51,24,42,16,177,0,177,0,42,16,29,11,177,0,29,11,8,9,55,295,56,275,112,310,55,295,112,310,148,331,148,331,112,310,115,312,148,331,115,312,119,313,119,313,162,310,148,331,148,331,162,310,195,327,239,89,234,59,250,15,250,15,234,59,220,39,250,15,220,39,217,4,217,4,220,39,198,26,217,4,198,26,177,0,177,0,198,26,170,20,177,0,170,20,138,18,138,18,126,19,177,0,177,0,126,19,118,21,177,0,118,21,55,37,55,37,118,21,56,56,213,289,225,270,232,317,232,317,225,270,228,245,235,181,228,245,225,223,195,327,162,310,192,302,195,327,192,302,213,289,195,327,213,289,232,317,235,181,254,191,258,300,258,300,254,191,268,205,258,300,268,205,274,277,274,277,268,205,277,224,274,277,277,224,280,248,232,317,228,245,235,181,232,317,235,181,258,300,234,121,239,167,220,142,220,142,239,167,211,174,220,142,211,174,198,155,198,155,211,174,211,175,198,155,211,175,214,205,214,205,211,175,235,181,214,205,235,181,225,223,140,163,171,161,172,186,172,186,171,161,198,155,172,186,198,155,197,193,197,193,198,155,214,205,140,163,172,186,139,183,140,163,139,183,108,183,140,163,108,183,108,163,109,32,108,41,56,275,109,32,56,275,56,56,296,89,292,116,291,58,291,58,292,116,281,138,291,58,281,138,275,34,275,34,281,138,263,155,275,34,263,155,250,15,250,15,263,155,239,167,250,15,239,167,239,89,56,56,118,21,112,26,56,56,112,26,109,32,56,275,108,41,108,296,56,275,108,296,108,303,56,275,108,303,109,307,56,275,109,307,112,310,148,331,8,331,29,320,148,331,29,320,43,316,148,331,43,316,51,308,148,331,51,308,55,295,29,320,8,331,8,321,177,0,8,9,8,0,51,24,177,0,55,37,239,167,234,121,239,89, 289,247,286,331,6,331,6,321,25,319,38,315,45,307,49,294,50,276,50,62,49,40,45,25,37,16,25,12,6,9,6,0,146,0,146,9,126,11,113,16,105,24,101,37,100,56,100,292,101,300,103,306,106,310,111,311,118,312,206,312,232,310,251,303,264,291,272,273,276,247, 38,315,45,307,286,331,286,331,45,307,111,311,286,331,111,311,118,312,286,331,118,312,206,312,286,331,206,312,232,310,286,331,232,310,251,303,286,331,251,303,264,291,286,331,264,291,272,273,286,331,272,273,276,247,286,331,276,247,289,247,100,56,100,292,50,276,50,276,100,292,101,300,50,276,101,300,103,306,50,276,103,306,106,310,50,276,106,310,49,294,50,276,101,37,100,56,111,311,45,307,49,294,111,311,49,294,106,310,25,319,38,315,286,331,25,319,286,331,6,331,25,319,6,331,6,321,146,0,146,9,126,11,146,0,126,11,113,16,146,0,113,16,49,40,146,0,49,40,45,25,146,0,45,25,37,16,146,0,37,16,25,12,146,0,25,12,6,9,146,0,6,9,6,0,50,62,49,40,113,16,50,62,113,16,105,24,50,62,105,24,101,37,50,62,101,37,50,276, 338,0,184,337,174,337,24,0,16383,16383,262,46,68,46,166,266, 174,337,24,0,68,46,68,46,24,0,338,0,68,46,338,0,262,46,262,46,338,0,184,337,262,46,184,337,174,337,174,337,68,46,166,266,174,337,166,266,262,46, 299,84,285,84,271,57,254,38,230,26,197,20,151,18,132,19,117,21,108,25,102,31,100,42,100,164,176,164,198,162,213,158,222,150,229,136,233,115,244,115,244,232,233,232,229,212,222,198,213,190,198,185,176,184,100,184,100,294,101,302,103,307,106,310,111,312,118,312,179,311,219,306,243,297,255,282,261,259,273,259,271,331,6,331,6,321,25,320,38,315,45,307,49,294,50,275,50,57,49,37,45,24,38,16,25,12,6,9,6,0,276,0, 45,24,38,16,276,0,276,0,38,16,25,12,276,0,25,12,6,9,38,315,45,307,271,331,271,331,45,307,111,312,271,331,111,312,118,312,118,312,179,311,271,331,271,331,179,311,219,306,271,331,219,306,243,297,271,331,243,297,255,282,271,331,255,282,261,259,271,331,261,259,273,259,45,24,117,21,49,37,49,37,117,21,108,25,49,37,108,25,50,57,50,57,108,25,102,31,50,57,102,31,50,275,50,275,102,31,100,42,50,275,100,42,100,294,100,184,100,164,176,164,100,184,176,164,176,184,198,185,176,184,198,162,198,185,198,162,213,190,213,190,198,162,213,158,213,190,213,158,222,198,222,198,213,158,222,150,222,198,222,150,229,212,229,212,222,150,229,136,229,212,229,136,233,232,233,232,229,136,233,115,233,232,233,115,244,115,50,275,100,294,101,302,50,275,101,302,103,307,50,275,103,307,106,310,50,275,106,310,49,294,106,310,111,312,45,307,106,310,45,307,49,294,25,320,38,315,271,331,25,320,271,331,6,331,25,320,6,331,6,321,254,38,230,26,276,0,276,0,230,26,197,20,276,0,197,20,151,18,151,18,132,19,276,0,276,0,132,19,117,21,276,0,117,21,45,24,276,0,299,84,285,84,276,0,285,84,271,57,276,0,271,57,254,38,176,184,176,164,198,162,233,232,244,115,244,232,276,0,6,9,6,0, 299,88,287,88,282,72,278,59,273,49,266,40,257,33,249,28,240,24,228,21,215,20,199,19,73,19,289,324,289,331,26,331,16,246,29,246,32,260,35,271,38,279,43,287,50,295,58,301,68,306,81,309,97,311,117,312,224,312,5,7,5,0,286,0, 35,271,38,279,26,331,26,331,38,279,43,287,26,331,43,287,50,295,50,295,58,301,26,331,26,331,58,301,68,306,26,331,68,306,81,309,73,19,289,324,224,312,224,312,289,324,289,331,224,312,289,331,117,312,97,311,117,312,289,331,97,311,289,331,26,331,26,331,16,246,29,246,26,331,29,246,32,260,26,331,32,260,35,271,224,312,5,7,73,19,73,19,5,7,286,0,73,19,286,0,199,19,199,19,286,0,215,20,278,59,273,49,286,0,286,0,273,49,266,40,286,0,266,40,257,33,257,33,249,28,286,0,286,0,249,28,240,24,286,0,240,24,228,21,286,0,299,88,287,88,286,0,287,88,282,72,286,0,282,72,278,59,286,0,5,7,5,0,215,20,286,0,228,21,26,331,81,309,97,311, 352,0,352,9,333,12,320,17,312,25,308,37,307,55,307,274,308,293,312,307,320,315,333,319,352,321,352,331,211,331,211,321,231,319,244,315,251,307,255,294,256,274,256,180,104,180,104,274,106,294,110,307,118,315,130,319,149,321,149,331,9,331,9,321,28,319,41,315,49,307,53,294,54,274,54,61,53,39,49,25,42,16,29,12,9,9,9,0,148,0,148,9,129,12,117,17,109,25,105,38,104,56,104,157,256,157,256,62,255,41,252,26,244,17,232,12,212,9,212,0, 49,25,42,16,148,0,148,0,42,16,29,12,148,0,29,12,9,9,149,331,9,331,28,319,149,331,28,319,41,315,149,331,41,315,49,307,149,331,49,307,53,294,149,331,53,294,118,315,149,331,118,315,130,319,149,331,130,319,149,321,54,274,105,38,104,56,104,180,104,157,256,157,104,180,256,157,256,180,256,180,256,157,312,25,256,180,312,25,308,37,54,274,104,56,104,274,54,274,104,274,106,294,54,274,106,294,110,307,54,274,110,307,118,315,54,274,118,315,53,294,252,26,244,17,352,0,352,0,244,17,232,12,352,0,232,12,212,9,333,319,352,321,352,331,333,319,352,331,320,315,320,315,352,331,255,294,320,315,255,294,256,274,308,37,256,274,256,180,307,55,307,274,256,274,256,274,307,274,308,293,256,274,308,293,312,307,352,331,211,331,231,319,352,331,231,319,244,315,352,331,244,315,251,307,352,331,251,307,255,294,352,0,352,9,333,12,352,0,333,12,320,17,352,0,320,17,255,41,352,0,255,41,252,26,256,62,255,41,320,17,256,62,320,17,312,25,256,62,312,25,256,157,148,0,148,9,129,12,148,0,129,12,117,17,148,0,117,17,53,39,148,0,53,39,49,25,54,61,53,39,117,17,54,61,117,17,109,25,54,61,109,25,105,38,54,61,105,38,54,274,148,0,9,9,9,0,352,0,212,9,212,0,256,274,308,37,307,55,231,319,211,331,211,321,320,315,256,274,312,307,28,319,9,331,9,321, 251,118,249,129,247,142,245,170,245,189,246,197,247,204,251,220,238,220,235,211,231,203,226,197,218,193,209,191,156,191,146,192,139,196,133,201,129,209,124,220,112,220,114,210,116,197,117,184,117,172,118,161,118,153,115,126,113,118,125,118,129,129,134,138,139,144,146,148,156,149,209,149,219,148,226,144,231,137,235,128,238,118,16383,16383,344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,134,308,149,314,180,338,180,338,149,314,164,318,180,338,164,318,180,320,180,320,194,319,235,330,235,330,194,319,207,316,235,330,180,338,180,320,247,142,246,156,238,220,238,220,246,156,245,170,238,220,245,170,245,180,245,180,245,189,238,220,238,220,245,189,246,197,238,220,246,197,247,204,249,212,251,220,238,220,249,212,238,220,247,204,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,234,1,235,26,223,19,234,1,223,19,209,15,234,1,209,15,196,12,234,1,196,12,181,11,234,1,181,11,180,-6,226,144,231,137,231,203,231,203,231,137,235,128,231,203,235,128,235,211,235,211,235,128,238,118,235,211,238,118,238,220,238,220,238,118,249,129,238,220,249,129,247,142,156,149,209,149,209,191,218,193,209,191,219,148,218,193,219,148,226,197,226,197,219,148,226,144,226,197,226,144,231,203,209,191,156,191,156,149,146,148,156,149,156,191,146,148,156,191,146,192,146,148,146,192,139,144,139,144,146,192,139,196,139,144,139,196,134,138,134,138,139,196,133,201,134,138,133,201,129,129,129,129,133,201,129,209,129,129,129,209,125,118,125,118,129,209,124,220,125,118,124,220,118,161,118,161,124,220,117,172,124,220,112,220,114,210,124,220,114,210,116,197,124,220,116,197,117,184,124,220,117,184,117,172,125,118,118,161,118,153,125,118,118,153,117,144,125,118,117,144,116,135,125,118,116,135,115,126,125,118,115,126,113,118,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,154,15,180,-6,167,12,167,12,180,-6,181,11,142,19,130,25,180,-6,142,19,180,-6,154,15,81,24,74,166,46,61,126,330,134,308,180,338,209,191,209,149,219,148,249,129,238,118,251,118, 157,0,157,9,137,11,122,16,114,24,109,37,108,56,108,276,109,295,113,308,122,316,136,320,157,321,157,331,9,331,9,321,30,320,44,316,53,308,57,295,57,56,56,36,52,23,44,15,30,11,9,9,9,0, 52,23,44,15,157,0,157,0,44,15,30,11,157,0,30,11,9,9,157,331,9,331,30,320,157,331,30,320,44,316,157,331,44,316,53,308,157,331,53,308,57,295,157,331,57,295,122,316,157,331,122,316,136,320,157,331,136,320,157,321,122,16,114,24,57,56,57,56,114,24,109,37,57,56,109,37,57,276,57,276,109,37,108,56,57,276,108,56,108,276,57,276,108,276,109,295,57,276,109,295,113,308,57,276,113,308,122,316,57,276,122,316,57,295,157,0,157,9,137,11,157,0,137,11,122,16,157,0,122,16,56,36,157,0,56,36,52,23,157,0,9,9,9,0,56,36,122,16,57,56,30,320,9,331,9,321, 362,0,362,9,349,11,336,16,322,25,305,41,283,64,166,192,259,281,278,298,292,309,305,316,320,320,338,321,338,331,208,331,208,321,220,321,229,320,235,318,238,315,240,311,241,305,239,298,234,289,226,280,202,256,113,174,113,293,117,307,124,315,137,319,158,321,158,331,17,331,17,321,37,319,50,315,57,306,61,293,62,275,62,63,61,40,57,26,50,17,36,12,17,9,17,0,157,0,157,9,139,12,126,16,118,23,114,36,113,55,113,148,126,158,176,107,198,84,217,63,232,46,241,32,244,22,244,18,241,15,237,12,231,11,224,10,210,9,210,0, 158,321,158,321,137,319,137,319,158,321,158,331,137,319,158,331,124,315,124,315,158,331,61,293,124,315,61,293,62,275,114,36,62,275,62,63,114,36,62,63,118,23,118,23,62,63,126,16,62,275,114,36,113,55,113,174,113,148,126,158,113,174,126,158,202,256,202,256,126,158,166,192,202,256,166,192,259,281,62,275,113,55,113,274,62,275,113,274,113,293,62,275,113,293,117,307,62,275,117,307,124,315,158,331,17,331,37,319,158,331,37,319,50,315,158,331,50,315,57,306,158,331,57,306,61,293,234,289,226,280,259,281,259,281,226,280,215,269,259,281,215,269,202,256,338,331,208,331,220,321,338,331,220,321,229,320,338,331,229,320,235,318,338,331,235,318,238,315,338,331,238,315,240,311,338,331,240,311,241,305,338,331,241,305,305,316,338,331,305,316,320,320,338,331,320,320,338,321,241,305,259,281,278,298,241,305,278,298,292,309,241,305,292,309,305,316,239,298,234,289,259,281,239,298,259,281,241,305,241,15,237,12,362,0,362,0,237,12,231,11,362,0,231,11,224,10,244,22,362,0,336,16,244,22,336,16,322,25,244,22,322,25,305,41,244,22,305,41,283,64,244,22,283,64,241,32,283,64,166,192,176,107,283,64,176,107,198,84,283,64,198,84,217,63,283,64,217,63,232,46,283,64,232,46,241,32,349,11,336,16,362,0,349,11,362,0,362,9,244,18,241,15,362,0,244,18,362,0,244,22,210,9,210,0,362,0,210,9,362,0,224,10,157,0,157,9,139,12,157,0,139,12,126,16,157,0,126,16,61,40,157,0,61,40,57,26,157,0,57,26,50,17,157,0,50,17,36,12,157,0,36,12,17,9,157,0,17,9,17,0,61,40,126,16,62,63,176,107,166,192,126,158,220,321,208,331,208,321,37,319,17,331,17,321, 344,0,344,9,330,12,320,17,311,26,304,38,296,55,179,337,169,337,70,93,56,58,44,34,34,20,22,13,7,9,7,0,107,0,107,9,94,10,84,12,77,16,73,22,72,30,72,34,73,38,74,43,76,51,160,267,161,267,241,61,244,51,247,44,249,37,250,31,251,26,249,18,244,13,236,11,227,10,216,9,216,0, 56,58,73,22,72,30,72,30,72,34,70,93,70,93,72,34,73,38,70,93,73,38,74,43,161,267,169,337,160,267,160,267,169,337,76,51,75,47,76,51,169,337,75,47,169,337,70,93,251,26,344,0,320,17,251,26,320,17,311,26,251,26,311,26,304,38,251,26,304,38,296,55,251,26,296,55,250,31,296,55,179,337,241,61,296,55,241,61,244,51,296,55,244,51,247,44,296,55,247,44,249,37,296,55,249,37,250,31,169,337,161,267,241,61,169,337,241,61,179,337,70,93,56,58,72,30,330,12,320,17,344,0,330,12,344,0,344,9,249,18,244,13,344,0,249,18,344,0,251,26,344,0,244,13,236,11,344,0,236,11,227,10,344,0,227,10,216,9,344,0,216,9,216,0,107,0,107,9,94,10,107,0,94,10,84,12,107,0,84,12,34,20,107,0,34,20,22,13,107,0,22,13,7,9,107,0,7,9,7,0,44,34,34,20,84,12,44,34,84,12,77,16,44,34,77,16,73,22,44,34,73,22,56,58,75,47,70,93,74,43, 432,0,432,9,413,12,401,17,393,25,389,38,388,56,388,275,389,294,393,307,401,316,413,320,431,321,431,331,332,331,222,80,106,331,7,331,7,321,28,319,42,315,50,307,54,294,55,275,55,75,54,47,49,29,41,18,27,12,6,9,6,0,123,0,123,9,103,12,90,18,82,29,78,48,76,75,76,275,203,0,209,0,337,286,337,61,336,40,333,26,325,17,312,12,292,9,292,0, 49,29,41,18,123,0,123,0,41,18,27,12,123,0,27,12,6,9,333,26,325,17,432,0,432,0,325,17,312,12,432,0,312,12,292,9,413,320,431,321,431,331,413,320,431,331,401,316,401,316,431,331,337,286,401,316,337,286,393,307,393,307,337,286,389,294,401,17,393,25,337,61,337,61,393,25,389,38,337,61,389,38,337,286,337,286,389,38,388,56,337,286,388,56,388,275,203,0,209,0,222,80,222,80,209,0,337,286,222,80,337,286,332,331,332,331,337,286,431,331,106,331,7,331,28,319,106,331,28,319,42,315,106,331,42,315,50,307,106,331,50,307,54,294,106,331,54,294,55,275,106,331,55,275,76,275,106,331,76,275,203,0,106,331,203,0,222,80,76,75,76,275,55,275,76,75,55,275,78,48,78,48,55,275,55,75,78,48,55,75,82,29,82,29,55,75,54,47,82,29,54,47,90,18,90,18,54,47,49,29,90,18,49,29,123,0,432,0,432,9,413,12,432,0,413,12,401,17,432,0,401,17,336,40,432,0,336,40,333,26,103,12,90,18,123,0,103,12,123,0,123,9,123,0,6,9,6,0,432,0,292,9,292,0,336,40,401,17,337,61,28,319,7,331,7,321,389,294,337,286,388,275, 353,331,235,331,235,321,247,320,256,319,263,317,275,309,278,303,281,295,283,285,284,274,284,89,91,331,6,331,6,321,19,321,29,318,37,313,46,306,55,295,55,75,54,48,49,30,41,19,27,13,6,9,6,0,123,0,123,9,103,13,90,20,82,31,78,49,76,75,76,269,297,-5,306,-5,306,274,308,289,311,299,315,307,320,313,324,315,329,318,335,319,343,320,353,321, 49,30,41,19,123,0,123,0,41,19,27,13,123,0,27,13,6,9,256,319,263,317,353,331,353,331,263,317,269,313,353,331,269,313,275,309,275,309,278,303,353,331,353,331,278,303,281,295,353,331,281,295,324,315,324,315,281,295,320,313,324,315,320,313,320,312,320,312,320,313,315,307,315,307,320,313,284,274,315,307,284,274,284,259,297,-5,284,259,284,89,297,-5,284,89,91,331,353,331,324,315,329,318,353,331,329,318,335,319,353,331,335,319,343,320,353,331,343,320,353,321,306,-5,306,253,297,-5,297,-5,306,253,306,274,297,-5,306,274,284,259,284,259,306,274,308,289,284,259,308,289,311,299,283,285,284,274,320,313,283,285,320,313,281,295,247,320,256,319,353,331,247,320,353,331,235,331,247,320,235,331,235,321,91,331,6,331,19,321,91,331,19,321,29,318,91,331,29,318,37,313,91,331,37,313,46,306,91,331,46,306,55,295,91,331,55,295,76,269,91,331,76,269,297,-5,55,295,78,49,76,75,54,48,49,30,90,20,90,20,49,30,123,0,90,20,123,0,103,13,103,13,123,0,123,9,55,75,54,48,82,31,55,75,82,31,78,49,55,75,78,49,55,295,123,0,6,9,6,0,54,48,90,20,82,31,19,321,6,331,6,321,76,269,55,295,76,75,315,307,284,259,311,299, 295,247,295,331,26,331,26,246,39,246,43,263,48,276,55,284,66,289,79,290,242,290,256,289,266,284,274,276,279,263,282,247,16383,16383,252,109,252,225,240,225,239,211,235,200,229,193,219,189,207,188,114,188,102,189,93,193,87,200,83,211,81,225,70,225,70,109,81,109,84,122,87,132,93,140,101,146,113,147,205,147,218,146,227,141,234,133,239,123,240,109,16383,16383,307,0,307,85,295,85,293,70,287,57,278,49,265,44,248,42,70,42,56,44,44,49,35,57,29,69,27,85,15,85,15,0, 295,331,26,331,66,289,295,331,66,289,79,290,295,331,79,290,242,290,295,331,242,290,256,289,295,331,256,289,266,284,295,331,266,284,274,276,295,331,274,276,279,263,295,331,279,263,282,247,295,331,282,247,295,247,26,331,26,246,39,246,26,331,39,246,43,263,26,331,43,263,48,276,26,331,48,276,55,284,26,331,55,284,66,289,219,189,207,188,218,146,218,146,207,188,205,147,205,147,207,188,114,188,205,147,114,188,113,147,101,146,113,147,102,189,101,146,102,189,93,193,83,211,84,122,87,200,87,200,84,122,87,132,87,200,87,132,93,193,93,193,87,132,93,140,93,193,93,140,101,146,83,211,81,225,84,122,84,122,81,225,81,109,81,109,81,225,70,225,81,109,70,225,70,109,240,225,239,211,240,109,240,225,240,109,252,109,240,225,252,109,252,225,240,109,239,211,239,123,239,123,239,211,235,200,239,123,235,200,234,133,234,133,235,200,229,193,234,133,229,193,227,141,227,141,229,193,219,189,227,141,219,189,218,146,287,57,278,49,307,0,307,0,278,49,265,44,307,0,265,44,248,42,307,0,307,85,295,85,307,0,295,85,293,70,307,0,293,70,287,57,248,42,70,42,307,0,307,0,70,42,56,44,307,0,56,44,15,0,15,0,56,44,44,49,15,0,44,49,35,57,15,0,35,57,15,85,15,85,35,57,29,69,15,85,29,69,27,85,113,147,114,188,102,189, 344,166,336,222,314,269,280,306,235,330,180,338,126,330,81,307,46,271,24,224,17,167,24,109,46,61,81,24,126,1,180,-6,234,1,279,24,314,60,336,108,344,166,16383,16383,287,169,285,134,280,103,272,76,260,53,246,35,235,26,223,19,209,15,196,12,181,11,167,12,154,15,142,19,130,25,119,33,103,52,90,75,81,102,76,132,74,166,76,194,80,222,87,247,97,269,108,286,121,298,134,308,149,314,164,318,180,320,194,319,207,316,219,311,231,305,242,296,257,279,270,257,279,231,285,201,287,169, 149,314,180,338,134,308,134,308,180,338,126,330,134,308,126,330,121,298,121,298,126,330,108,286,97,269,108,286,126,330,97,269,126,330,81,307,81,102,81,24,90,75,90,75,81,24,126,1,90,75,126,1,103,52,103,52,126,1,119,33,130,25,119,33,126,1,130,25,126,1,180,-6,207,316,235,330,194,319,194,319,235,330,180,320,164,318,180,320,180,338,164,318,180,338,149,314,81,307,46,271,46,61,81,307,46,61,74,166,81,307,74,166,76,194,81,307,76,194,80,222,81,307,80,222,87,247,81,307,87,247,97,269,81,102,76,132,81,24,81,24,76,132,74,166,24,109,46,61,46,271,24,109,46,271,24,224,24,109,24,224,17,167,223,19,209,15,234,1,234,1,209,15,196,12,234,1,196,12,181,11,181,11,167,12,180,-6,180,-6,167,12,154,15,180,-6,154,15,142,19,207,316,219,311,235,330,235,330,219,311,231,305,235,330,231,305,242,296,242,296,257,279,280,306,280,306,257,279,270,257,280,306,270,257,279,231,235,330,180,338,180,320,280,103,272,76,279,24,279,24,272,76,260,53,279,24,260,53,246,35,246,35,235,26,279,24,279,24,235,26,234,1,344,166,336,222,336,108,336,108,336,222,314,269,336,108,314,269,314,60,314,60,314,269,287,169,285,201,287,169,314,269,285,201,314,269,280,306,285,201,280,306,279,231,280,306,235,330,242,296,314,60,287,169,285,134,314,60,285,134,280,103,314,60,280,103,279,24,181,11,180,-6,234,1,81,24,74,166,46,61,223,19,234,1,235,26,130,25,180,-6,142,19, 352,0,352,9,333,12,320,17,312,25,308,37,307,55,307,274,308,293,312,307,320,315,333,319,352,321,352,331,9,331,9,321,28,319,41,315,49,307,53,294,54,274,54,61,53,39,49,25,42,16,29,12,9,9,9,0,148,0,148,9,129,12,117,17,109,25,105,38,104,56,104,296,105,303,107,307,111,310,116,312,238,312,245,311,251,310,254,306,256,301,256,62,255,41,252,26,244,17,232,12,212,9,212,0, 49,25,42,16,148,0,148,0,42,16,29,12,148,0,29,12,9,9,53,294,54,274,111,310,53,294,111,310,49,307,49,307,111,310,116,312,49,307,116,312,352,331,352,331,116,312,123,312,252,26,244,17,352,0,352,0,244,17,232,12,352,0,232,12,212,9,352,331,123,312,238,312,352,331,238,312,245,311,352,331,245,311,251,310,352,331,251,310,254,306,352,331,254,306,256,301,352,331,256,301,256,294,352,331,256,294,320,315,352,331,320,315,333,319,352,331,333,319,352,321,307,55,307,274,256,294,256,294,307,274,308,293,256,294,308,293,312,307,320,17,312,25,256,62,256,62,312,25,308,37,256,62,308,37,256,294,117,17,109,25,54,61,54,61,109,25,105,38,54,61,105,38,54,274,54,274,105,38,104,56,54,274,104,56,104,296,54,274,104,296,105,303,54,274,105,303,107,307,54,274,107,307,111,310,352,331,9,331,28,319,352,331,28,319,41,315,352,331,41,315,49,307,352,0,352,9,333,12,352,0,333,12,320,17,352,0,320,17,255,41,352,0,255,41,252,26,148,0,148,9,129,12,148,0,129,12,117,17,148,0,117,17,53,39,148,0,53,39,49,25,148,0,9,9,9,0,53,39,117,17,54,61,352,0,212,9,212,0,255,41,320,17,256,62,256,294,308,37,307,55,28,319,9,331,9,321,320,315,256,294,312,307, 8,331,8,321,27,319,39,315,46,307,49,294,50,276,50,39,47,25,40,16,27,12,8,9,8,0,148,0,148,9,128,12,114,16,106,24,102,37,101,56,101,146,109,145,115,145,122,144,136,144,164,145,188,147,208,153,225,161,243,175,253,185,260,197,266,210,270,225,271,240,270,254,267,268,262,280,255,291,246,300,231,310,213,319,191,325,166,329,137,331,16383,16383,101,295,101,302,103,307,106,310,111,312,118,313,155,310,182,302,202,288,213,266,217,238,213,213,202,192,185,177,162,167,132,164,120,164,114,165,108,165,101,166, 111,312,118,312,118,313,137,331,118,313,155,310,137,331,155,310,166,329,166,329,155,310,182,302,166,329,182,302,191,325,191,325,182,302,202,288,191,325,202,288,213,319,213,319,202,288,213,266,213,319,213,266,231,310,231,310,213,266,217,238,231,310,217,238,225,161,225,161,213,213,208,153,208,153,213,213,202,192,208,153,202,192,188,147,188,147,202,192,185,177,188,147,185,177,164,145,164,145,185,177,162,167,164,145,162,167,136,144,136,144,162,167,132,164,136,144,132,164,128,144,128,144,132,164,126,164,128,144,126,164,122,144,122,144,126,164,120,164,122,144,120,164,115,145,115,145,120,164,114,165,115,145,114,165,109,145,109,145,114,165,108,165,109,145,108,165,101,166,101,56,101,166,50,276,101,56,50,276,102,37,102,37,50,276,50,61,101,166,101,146,109,145,271,240,270,254,270,225,270,225,270,254,267,268,270,225,267,268,266,210,266,210,267,268,262,280,266,210,262,280,260,197,260,197,262,280,255,291,260,197,255,291,253,185,253,185,255,291,246,300,253,185,246,300,243,175,243,175,246,300,231,310,243,175,231,310,225,161,137,331,8,331,27,319,137,331,27,319,39,315,137,331,39,315,46,307,137,331,46,307,49,294,137,331,49,294,50,276,137,331,50,276,106,310,137,331,106,310,111,312,137,331,111,312,118,313,101,295,101,302,50,276,101,295,50,276,101,166,103,307,106,310,50,276,103,307,50,276,101,302,148,0,148,9,128,12,148,0,128,12,114,16,148,0,114,16,50,39,148,0,50,39,47,25,148,0,47,25,40,16,148,0,40,16,27,12,148,0,27,12,8,9,148,0,8,9,8,0,50,61,50,39,114,16,50,61,114,16,106,24,50,61,106,24,102,37,27,319,8,331,8,321,213,213,225,161,217,238,155,310,118,313,118,312, 300,102,289,102,283,82,275,66,264,56,249,49,229,47,74,47,193,184,86,312,190,312,214,310,234,305,248,294,259,276,266,251,278,251,278,331,15,331,15,324,148,162,15,7,15,0,286,0, 278,331,15,331,86,312,278,331,86,312,190,312,278,331,190,312,214,310,278,331,214,310,234,305,278,331,234,305,248,294,278,331,248,294,259,276,278,331,259,276,266,251,278,331,266,251,278,251,148,162,15,7,74,47,148,162,74,47,193,184,148,162,193,184,86,312,148,162,86,312,15,331,148,162,15,331,15,324,275,66,264,56,286,0,286,0,264,56,249,49,286,0,249,49,229,47,286,0,300,102,289,102,286,0,289,102,283,82,286,0,283,82,275,66,286,0,229,47,74,47,286,0,74,47,15,7,286,0,15,7,15,0, 296,246,293,331,12,331,8,246,21,246,28,274,37,292,50,303,70,309,97,310,127,310,127,61,126,39,123,25,115,16,101,12,80,9,80,0,226,0,226,9,205,11,192,16,183,23,179,36,178,55,178,310,208,310,235,309,254,303,268,292,277,274,284,246, 293,331,12,331,70,309,293,331,70,309,97,310,293,331,97,310,127,310,293,331,127,310,178,310,293,331,178,310,208,310,293,331,208,310,235,309,293,331,235,309,254,303,293,331,254,303,268,292,293,331,268,292,277,274,293,331,277,274,284,246,293,331,284,246,296,246,192,16,183,23,127,61,127,61,183,23,179,36,127,61,179,36,127,310,127,310,179,36,178,55,127,310,178,55,178,310,12,331,8,246,21,246,12,331,21,246,28,274,12,331,28,274,37,292,12,331,37,292,50,303,12,331,50,303,70,309,226,0,226,9,205,11,226,0,205,11,192,16,226,0,192,16,126,39,226,0,126,39,123,25,226,0,123,25,115,16,226,0,115,16,101,12,226,0,101,12,80,9,226,0,80,9,80,0,126,39,192,16,127,61, 352,329,345,332,338,334,332,335,320,335,289,330,259,315,232,290,211,258,198,218,196,218,186,260,169,293,146,318,117,332,81,337,67,336,53,332,39,327,26,319,15,311,18,303,25,305,33,308,41,310,49,311,55,312,84,306,109,289,130,257,146,211,157,147,157,61,156,39,153,25,144,16,130,12,107,9,107,0,260,0,260,9,239,11,224,15,215,23,210,36,209,55,209,152,215,204,233,251,261,288,296,313,335,322,342,322,348,320,352,320, 18,303,25,305,26,319,26,319,25,305,33,308,26,319,33,308,39,327,39,327,33,308,41,310,39,327,41,310,53,332,53,332,41,310,49,311,53,332,49,311,55,312,55,312,84,306,67,336,67,336,84,306,81,337,67,336,53,332,55,312,198,218,196,218,210,36,198,218,210,36,209,55,198,218,209,55,209,152,198,218,209,152,211,258,332,335,326,335,335,322,335,322,326,335,320,335,335,322,320,335,296,313,296,313,320,335,289,330,296,313,289,330,261,288,261,288,289,330,259,315,261,288,259,315,233,251,233,251,259,315,232,290,233,251,232,290,215,204,215,204,232,290,211,258,215,204,211,258,209,152,338,334,335,322,339,322,338,334,339,322,345,332,345,332,339,322,342,322,345,332,342,322,345,321,348,320,352,320,352,329,348,320,352,329,345,321,345,321,352,329,345,332,260,0,260,9,239,11,260,0,239,11,224,15,260,0,224,15,156,39,260,0,156,39,153,25,260,0,153,25,144,16,260,0,144,16,130,12,260,0,130,12,107,9,260,0,107,9,107,0,169,293,157,147,210,36,169,293,210,36,186,260,186,260,210,36,196,218,156,39,224,15,157,61,157,61,224,15,215,23,157,61,215,23,157,147,157,147,215,23,210,36,84,306,109,289,117,332,117,332,109,289,130,257,117,332,130,257,146,318,146,318,130,257,146,211,146,318,146,211,169,293,169,293,146,211,157,147,81,337,84,306,117,332,335,322,338,334,332,335,18,303,26,319,15,311, 216,290,217,301,221,310,230,316,245,320,267,321,267,331,114,331,114,321,136,320,151,317,160,311,164,302,165,290,165,280,122,276,82,263,49,241,26,209,17,165,23,128,39,97,67,72,106,57,156,51,165,51,165,42,163,29,157,20,146,14,132,10,114,9,114,0,267,0,267,9,248,11,234,15,224,20,218,29,216,43,216,51,228,51,264,56,300,69,332,91,355,123,364,165,355,209,332,241,298,263,258,276,216,280,16383,16383,215,262,250,256,276,240,295,216,306,188,310,159,304,128,290,103,268,85,243,74,215,70,16383,16383,166,70,133,75,107,88,88,107,76,132,72,159,76,189,89,216,109,240,135,256,166,262, 267,321,267,321,245,320,245,320,267,321,267,331,245,320,267,331,230,316,230,316,267,331,164,302,230,316,164,302,165,290,166,262,165,290,165,280,166,262,165,280,135,256,135,256,165,280,122,276,135,256,122,276,109,240,109,240,122,276,89,216,216,43,215,70,166,262,166,262,215,70,215,262,166,262,215,262,216,290,216,290,215,262,216,280,166,262,216,290,217,301,166,262,217,301,221,310,166,262,218,29,216,43,165,290,166,262,221,310,165,290,221,310,230,316,267,331,114,331,136,320,267,331,136,320,151,317,267,331,151,317,160,311,267,331,160,311,164,302,82,263,49,241,72,159,82,263,72,159,76,189,82,263,76,189,89,216,82,263,89,216,122,276,17,165,23,128,26,209,26,209,23,128,39,97,26,209,39,97,49,241,49,241,39,97,67,72,49,241,67,72,72,159,332,91,310,159,304,128,332,91,304,128,300,69,300,69,304,128,290,103,300,69,290,103,268,85,306,188,310,159,332,241,332,241,310,159,332,91,332,241,332,91,355,209,355,209,332,91,355,123,355,209,355,123,364,165,298,263,258,276,276,240,298,263,276,240,295,216,298,263,295,216,306,188,298,263,306,188,332,241,250,256,276,240,258,276,250,256,258,276,216,280,250,256,216,280,215,262,216,51,228,51,243,74,243,74,228,51,264,56,243,74,264,56,268,85,268,85,264,56,300,69,216,43,216,51,215,70,215,70,216,51,243,74,267,0,267,9,248,11,267,0,248,11,234,15,267,0,234,15,165,42,267,0,165,42,163,29,267,0,163,29,157,20,267,0,157,20,146,14,267,0,146,14,132,10,267,0,132,10,114,9,267,0,114,9,114,0,166,70,133,75,156,51,166,70,156,51,165,51,166,70,165,51,224,20,166,70,224,20,218,29,166,70,218,29,166,262,165,51,165,42,234,15,165,51,234,15,224,20,107,88,88,107,106,57,107,88,106,57,156,51,107,88,156,51,133,75,76,132,72,159,67,72,76,132,67,72,106,57,76,132,106,57,88,107,136,320,114,331,114,321, 352,0,352,9,338,12,327,16,317,22,307,32,296,46,200,184,272,272,289,292,303,305,316,314,331,319,348,321,348,331,229,331,229,321,243,320,253,319,259,316,262,311,263,305,263,301,260,296,257,290,251,282,243,272,188,202,166,234,151,255,139,272,131,286,126,297,124,306,125,312,128,316,133,319,139,320,147,321,161,321,161,331,11,331,11,321,29,319,44,312,59,299,78,276,103,242,156,164,78,66,58,42,43,26,31,17,19,12,5,9,5,0,121,0,121,9,106,11,95,13,88,17,84,21,83,26,84,31,87,38,92,46,100,57,109,70,169,145,217,74,226,60,233,48,238,38,241,31,242,25,241,20,238,16,233,14,226,12,217,11,204,9,204,0, 31,17,121,0,43,26,43,26,121,0,88,17,43,26,88,17,58,42,58,42,88,17,84,21,58,42,84,21,83,26,83,26,84,31,78,66,78,66,84,31,87,38,78,66,87,38,156,164,156,164,87,38,92,46,156,164,92,46,100,57,103,242,156,164,126,297,103,242,126,297,124,306,124,306,125,312,103,242,156,164,100,57,109,70,109,70,169,145,156,164,156,164,169,145,166,234,156,164,166,234,151,255,78,66,58,42,83,26,103,242,125,312,78,276,78,276,125,312,128,316,78,276,128,316,59,299,59,299,128,316,133,319,59,299,133,319,161,331,161,331,133,319,139,320,161,331,139,320,147,321,147,321,161,321,161,331,161,331,11,331,29,319,161,331,29,319,44,312,161,331,44,312,59,299,260,296,257,290,272,272,272,272,257,290,251,282,272,272,251,282,243,272,243,272,188,202,200,184,200,184,188,202,217,74,200,184,217,74,296,46,296,46,217,74,226,60,296,46,226,60,233,48,348,331,229,331,243,320,348,331,243,320,253,319,348,331,253,319,259,316,348,331,259,316,262,311,348,331,262,311,263,305,348,331,263,305,316,314,348,331,316,314,331,319,348,331,331,319,348,321,263,305,272,272,289,292,263,305,289,292,303,305,263,305,303,305,316,314,263,301,260,296,272,272,263,301,272,272,263,305,243,272,200,184,272,272,238,16,233,14,352,0,352,0,233,14,226,12,352,0,226,12,217,11,242,25,352,0,327,16,242,25,327,16,317,22,242,25,317,22,307,32,242,25,307,32,296,46,242,25,296,46,241,31,296,46,233,48,238,38,296,46,238,38,241,31,188,202,166,234,169,145,188,202,169,145,217,74,338,12,327,16,352,0,338,12,352,0,352,9,241,20,238,16,352,0,241,20,352,0,242,25,204,9,204,0,352,0,204,9,352,0,217,11,156,164,151,255,139,272,156,164,139,272,131,286,156,164,131,286,126,297,121,0,121,9,106,11,121,0,106,11,95,13,121,0,95,13,88,17,19,12,5,9,121,0,19,12,121,0,31,17,121,0,5,9,5,0,243,320,229,331,229,321,29,319,11,331,11,321, 362,345,332,341,310,328,295,309,287,284,285,254,283,226,278,198,267,175,248,159,218,153,212,153,212,281,214,299,221,311,232,318,246,321,263,321,263,331,110,331,110,321,128,321,142,317,152,310,159,299,161,281,161,153,156,153,125,159,106,175,95,198,90,226,89,254,86,284,78,309,64,328,42,341,11,345,11,335,21,330,28,320,32,308,34,295,35,283,34,274,34,265,33,256,33,247,32,238,39,199,59,170,87,150,122,139,161,135,161,62,160,40,156,25,147,16,132,12,110,9,110,0,263,0,263,9,244,11,229,14,220,22,214,35,212,55,212,135,251,139,286,150,314,170,333,199,340,238,340,256,339,265,339,295,341,308,345,320,352,330,362,335, 263,321,263,321,246,321,246,321,263,321,263,331,246,321,263,331,232,318,232,318,263,331,159,299,232,318,159,299,161,281,161,135,161,281,161,153,161,135,161,153,156,153,161,135,220,22,214,35,161,135,214,35,212,55,212,153,212,135,251,139,212,153,251,139,218,153,218,153,251,139,248,159,212,55,212,281,161,135,161,135,212,281,214,299,161,135,214,299,161,281,161,281,214,299,221,311,161,281,221,311,232,318,263,331,110,331,128,321,263,331,128,321,142,317,263,331,142,317,152,310,263,331,152,310,159,299,310,328,295,309,314,170,314,170,295,309,287,284,314,170,287,284,286,150,286,150,287,284,285,254,286,150,285,254,283,226,310,328,314,170,332,341,332,341,314,170,333,199,332,341,333,199,339,295,339,295,333,199,339,283,339,274,339,283,333,199,339,274,333,199,340,238,352,330,362,335,362,345,352,330,362,345,345,320,345,320,362,345,332,341,345,320,332,341,341,308,341,308,332,341,339,295,248,159,251,139,267,175,267,175,251,139,286,150,267,175,286,150,278,198,278,198,286,150,283,226,340,238,340,247,340,256,340,238,340,256,339,265,340,238,339,265,339,274,263,0,263,9,244,11,263,0,244,11,229,14,263,0,229,14,160,40,263,0,160,40,156,25,263,0,156,25,147,16,263,0,147,16,132,12,263,0,132,12,110,9,263,0,110,9,110,0,161,62,160,40,229,14,161,62,229,14,220,22,161,62,220,22,161,135,125,159,106,175,122,139,125,159,122,139,161,135,125,159,161,135,156,153,90,226,89,254,87,150,90,226,87,150,95,198,95,198,87,150,122,139,95,198,122,139,106,175,87,150,89,254,86,284,87,150,86,284,78,309,87,150,78,309,64,328,87,150,64,328,59,170,42,341,11,345,21,330,42,341,21,330,28,320,42,341,28,320,32,308,42,341,32,308,34,295,42,341,34,295,35,283,42,341,35,283,39,199,42,341,39,199,59,170,42,341,59,170,64,328,39,199,35,283,34,274,39,199,34,274,34,265,39,199,34,265,33,256,39,199,33,256,33,247,39,199,33,247,32,238,21,330,11,345,11,335,128,321,110,331,110,321, 358,0,358,84,345,84,343,71,339,61,333,53,325,49,314,47,237,47,238,66,275,80,305,100,327,126,341,159,345,199,338,242,318,280,285,310,241,331,186,338,130,330,86,309,53,277,33,239,26,199,31,159,44,126,65,100,95,80,132,66,133,47,58,47,46,48,38,52,32,59,28,70,27,85,15,85,15,0,158,0,153,80,129,93,110,114,96,140,87,170,84,200,88,235,100,268,120,295,149,313,186,320,222,314,250,298,271,273,284,239,289,200,285,168,276,138,261,112,242,92,218,80,214,0, 58,47,46,48,158,0,158,0,46,48,38,52,158,0,38,52,15,0,15,0,38,52,32,59,15,0,32,59,15,85,15,85,32,59,28,70,15,85,28,70,27,85,26,199,31,159,33,239,33,239,31,159,44,126,33,239,44,126,53,277,53,277,44,126,65,100,53,277,65,100,86,309,86,309,65,100,84,200,95,80,84,200,65,100,186,338,149,313,186,320,186,320,222,314,241,331,241,331,222,314,250,298,241,331,250,298,285,310,285,310,250,298,271,273,285,310,271,273,284,239,289,200,305,100,318,280,318,280,305,100,327,126,318,280,327,126,338,242,338,242,327,126,341,159,338,242,341,159,345,199,285,310,284,239,289,200,285,310,289,200,318,280,241,331,186,338,186,320,261,112,275,80,276,138,276,138,275,80,305,100,276,138,305,100,285,168,285,168,305,100,289,200,214,0,237,47,218,80,218,80,237,47,238,66,218,80,238,66,242,92,242,92,238,66,275,80,242,92,275,80,261,112,339,61,333,53,358,0,358,0,333,53,325,49,358,0,325,49,314,47,358,0,358,84,345,84,358,0,345,84,343,71,358,0,343,71,339,61,237,47,214,0,358,0,237,47,358,0,314,47,130,330,86,309,100,268,130,330,100,268,120,295,130,330,120,295,149,313,130,330,149,313,186,338,86,309,84,200,88,235,86,309,88,235,100,268,132,66,133,47,153,80,132,66,153,80,129,93,132,66,129,93,110,114,132,66,110,114,96,140,132,66,96,140,95,80,87,170,84,200,95,80,87,170,95,80,96,140,133,47,58,47,158,0,133,47,158,0,153,80, 158,411,157,419,153,426,148,432,141,435,133,436,125,435,118,432,113,426,110,420,108,412,109,404,113,397,118,392,125,388,132,387,140,388,148,392,153,397,157,404,158,411,16383,16383,59,411,57,419,54,426,48,432,41,435,33,436,26,435,19,432,14,426,10,420,9,412,10,404,14,397,19,392,25,388,33,387,41,388,48,392,54,397,57,404,59,411,16383,16383,157,0,157,9,137,11,122,16,114,24,109,37,108,56,108,276,109,295,113,308,122,316,136,320,157,321,157,331,9,331,9,321,30,320,44,316,53,308,57,295,57,56,56,36,52,23,44,15,30,11,9,9,9,0, 9,412,10,404,10,420,10,420,10,404,14,397,10,420,14,397,14,426,14,426,14,397,19,392,14,426,19,392,19,432,19,432,19,392,25,388,19,432,25,388,26,435,26,435,25,388,33,387,26,435,33,387,33,436,33,436,33,387,41,388,33,436,41,388,41,435,41,435,41,388,48,392,41,435,48,392,48,432,48,432,48,392,54,397,48,432,54,397,54,426,54,426,54,397,57,404,54,426,57,404,57,419,57,419,57,404,59,411,52,23,44,15,157,0,157,0,44,15,30,11,157,0,30,11,9,9,157,331,9,331,30,320,157,331,30,320,44,316,157,331,44,316,53,308,157,331,53,308,57,295,157,331,57,295,122,316,157,331,122,316,136,320,157,331,136,320,157,321,122,16,114,24,57,56,57,56,114,24,109,37,57,56,109,37,57,276,57,276,109,37,108,56,57,276,108,56,108,276,57,276,108,276,109,295,57,276,109,295,113,308,57,276,113,308,122,316,57,276,122,316,57,295,108,412,109,404,110,420,110,420,109,404,113,397,110,420,113,397,113,426,113,426,113,397,118,392,113,426,118,392,118,432,118,432,118,392,125,388,118,432,125,388,125,435,125,435,125,388,132,387,125,435,132,387,133,436,133,436,132,387,140,388,133,436,140,388,141,435,141,435,140,388,148,392,141,435,148,392,148,432,148,432,148,392,153,397,148,432,153,397,153,426,153,426,153,397,157,404,153,426,157,404,157,419,157,419,157,404,158,411,157,0,157,9,137,11,157,0,137,11,122,16,157,0,122,16,56,36,157,0,56,36,52,23,157,0,9,9,9,0,56,36,122,16,57,56,30,320,9,331,9,321, 257,411,256,419,252,426,247,432,240,435,233,436,225,435,218,432,213,426,209,420,208,412,209,404,213,397,218,392,225,388,232,387,240,388,247,392,252,397,256,404,257,411,16383,16383,158,411,157,419,153,426,148,432,141,435,133,436,125,435,118,432,113,426,110,420,108,412,109,404,113,397,118,392,125,388,132,387,140,388,148,392,153,397,157,404,158,411,16383,16383,352,329,345,332,338,334,332,335,320,335,289,330,259,315,232,290,211,258,198,218,196,218,186,260,169,293,146,318,117,332,81,337,67,336,53,332,39,327,26,319,15,311,18,303,25,305,33,308,41,310,49,311,55,312,84,306,109,289,130,257,146,211,157,147,157,61,156,39,153,25,144,16,130,12,107,9,107,0,260,0,260,9,239,11,224,15,215,23,210,36,209,55,209,152,215,204,233,251,261,288,296,313,335,322,342,322,348,320,352,320, 18,303,25,305,26,319,26,319,25,305,33,308,26,319,33,308,39,327,39,327,33,308,41,310,39,327,41,310,53,332,53,332,41,310,49,311,53,332,49,311,55,312,55,312,84,306,67,336,67,336,84,306,81,337,67,336,53,332,55,312,198,218,196,218,210,36,198,218,210,36,209,55,198,218,209,55,209,152,198,218,209,152,211,258,260,0,260,9,239,11,260,0,239,11,224,15,260,0,224,15,156,39,260,0,156,39,153,25,260,0,153,25,144,16,260,0,144,16,130,12,260,0,130,12,107,9,260,0,107,9,107,0,169,293,157,147,210,36,169,293,210,36,186,260,186,260,210,36,196,218,156,39,224,15,157,61,157,61,224,15,215,23,157,61,215,23,157,147,157,147,215,23,210,36,332,335,326,335,335,322,335,322,326,335,320,335,335,322,320,335,296,313,296,313,320,335,289,330,296,313,289,330,261,288,261,288,289,330,259,315,261,288,259,315,233,251,233,251,259,315,232,290,233,251,232,290,215,204,215,204,232,290,211,258,215,204,211,258,209,152,338,334,335,322,339,322,338,334,339,322,345,332,345,332,339,322,342,322,345,332,342,322,345,321,348,320,352,320,352,329,348,320,352,329,345,321,345,321,352,329,345,332,208,412,209,404,209,420,209,420,209,404,213,397,209,420,213,397,213,426,213,426,213,397,218,392,213,426,218,392,218,432,218,432,218,392,225,388,218,432,225,388,225,435,225,435,225,388,232,387,225,435,232,387,233,436,233,436,232,387,240,388,233,436,240,388,240,435,240,435,240,388,247,392,240,435,247,392,247,432,247,432,247,392,252,397,247,432,252,397,252,426,252,426,252,397,256,404,252,426,256,404,256,419,256,419,256,404,257,411,108,412,109,404,110,420,110,420,109,404,113,397,110,420,113,397,113,426,113,426,113,397,118,392,113,426,118,392,118,432,118,432,118,392,125,388,118,432,125,388,125,435,125,435,125,388,132,387,125,435,132,387,133,436,133,436,132,387,140,388,133,436,140,388,141,435,141,435,140,388,148,392,141,435,148,392,148,432,148,432,148,392,153,397,148,432,153,397,153,426,153,426,153,397,157,404,153,426,157,404,157,419,157,419,157,404,158,411,84,306,109,289,117,332,117,332,109,289,130,257,117,332,130,257,146,318,146,318,130,257,146,211,146,318,146,211,169,293,169,293,146,211,157,147,81,337,84,306,117,332,335,322,338,334,332,335,18,303,26,319,15,311, 108,253,126,253,158,294,163,299,167,304,169,309,171,313,172,316,171,322,168,326,165,329,157,331,151,330,147,329,143,327,140,324,138,320,16383,16383,257,65,255,50,252,39,248,32,245,27,241,26,232,31,223,43,216,60,210,78,206,94,261,225,212,225,190,157,182,178,171,198,156,215,137,226,113,230,79,224,52,207,31,181,19,148,15,112,19,73,32,41,52,16,78,1,108,-4,129,-1,147,5,162,17,174,32,185,50,190,32,196,17,204,5,213,-1,225,-4,239,0,250,8,258,24,263,43,265,65,16383,16383,166,104,162,84,155,59,145,35,131,16,113,9,90,19,75,43,66,76,61,109,60,137,63,167,70,189,81,204,95,213,110,216,129,208,144,187,154,159,161,130,166,104, 63,167,70,189,79,224,79,224,70,189,81,204,79,224,81,204,113,230,113,230,81,204,95,213,113,230,95,213,110,216,110,216,129,208,113,230,113,230,129,208,137,226,157,331,158,294,161,330,161,330,158,294,163,299,161,330,163,299,165,329,165,329,163,299,167,304,165,329,167,304,168,326,168,326,167,304,169,309,168,326,169,309,171,322,171,322,169,309,171,313,171,322,171,313,172,316,158,294,157,331,151,330,158,294,151,330,147,329,158,294,147,329,143,327,158,294,143,327,140,324,158,294,140,324,138,320,158,294,138,320,126,253,144,187,154,159,156,215,156,215,154,159,161,130,156,215,161,130,171,198,171,198,161,130,166,104,171,198,166,104,174,32,171,198,174,32,182,178,182,178,174,32,185,50,182,178,185,50,190,157,190,157,185,50,190,32,190,157,190,32,212,225,212,225,190,32,196,17,212,225,196,17,206,94,206,94,196,17,204,5,206,94,204,5,213,-1,137,226,129,208,144,187,137,226,144,187,156,215,174,32,166,104,162,84,174,32,162,84,162,17,162,17,162,84,155,59,162,17,155,59,147,5,147,5,155,59,145,35,147,5,145,35,131,16,78,1,108,-4,90,19,90,19,108,-4,113,9,131,16,113,9,129,-1,131,16,129,-1,147,5,210,78,206,94,213,-1,212,225,206,94,261,225,252,39,248,32,250,8,250,8,248,32,245,27,250,8,245,27,241,26,241,26,232,31,239,0,239,0,232,31,225,-4,210,78,213,-1,216,60,216,60,213,-1,225,-4,216,60,225,-4,223,43,223,43,225,-4,232,31,258,24,263,43,265,65,258,24,265,65,257,65,258,24,257,65,255,50,258,24,255,50,252,39,258,24,252,39,250,8,241,26,239,0,250,8,113,9,108,-4,129,-1,90,19,75,43,78,1,78,1,75,43,66,76,78,1,66,76,52,16,52,16,66,76,61,109,52,16,61,109,60,137,60,137,63,167,52,207,52,207,63,167,79,224,52,16,60,137,52,207,52,16,52,207,32,41,32,41,52,207,31,181,32,41,31,181,19,73,19,73,31,181,19,148,19,73,19,148,15,112,126,253,138,320,108,253, 76,253,94,253,127,294,135,304,138,309,139,313,140,316,139,322,137,326,133,329,125,331,119,330,115,329,111,327,108,324,106,320,16383,16383,196,73,182,54,166,39,149,29,131,22,110,20,95,22,80,27,69,36,60,49,57,65,61,81,70,94,83,102,97,107,111,108,117,108,125,106,128,106,133,105,142,106,148,108,153,111,156,115,157,118,156,122,154,124,150,127,145,128,138,129,131,128,121,126,115,125,108,124,92,127,80,133,72,142,67,154,65,167,67,182,74,195,83,206,96,213,112,215,127,215,140,212,148,208,154,203,156,195,155,193,155,190,154,187,154,183,153,179,155,171,158,166,163,161,168,158,175,157,182,158,188,161,194,165,198,171,199,179,194,199,181,214,163,223,142,228,121,230,87,226,60,217,40,202,28,184,24,165,26,152,31,141,39,131,49,123,63,118,47,113,33,103,22,91,15,77,12,61,14,46,21,29,37,13,65,0,108,-4,130,-1,151,6,171,20,189,40,204,68, 37,13,65,0,47,113,47,113,65,0,57,65,63,118,57,65,61,81,63,118,61,81,70,94,72,142,67,154,70,94,70,94,67,154,65,167,63,118,65,167,60,217,63,118,60,217,49,123,49,123,60,217,40,202,49,123,40,202,39,131,39,131,40,202,31,141,142,228,121,230,127,215,127,215,121,230,112,215,96,213,112,215,121,230,96,213,121,230,87,226,125,331,127,294,129,330,129,330,127,294,131,299,129,330,131,299,133,329,133,329,131,299,135,304,133,329,135,304,137,326,137,326,135,304,138,309,137,326,138,309,139,322,139,322,138,309,139,313,139,322,139,313,140,316,127,294,125,331,119,330,127,294,119,330,115,329,127,294,115,329,111,327,127,294,111,327,108,324,127,294,108,324,106,320,127,294,106,320,94,253,194,199,181,214,182,158,194,199,182,158,188,161,194,199,188,161,194,165,194,199,194,165,198,171,194,199,198,171,199,179,158,166,163,161,163,223,163,223,163,161,168,158,163,223,168,158,181,214,181,214,168,158,175,157,181,214,175,157,182,158,127,215,140,212,142,228,142,228,140,212,148,208,142,228,148,208,163,223,163,223,148,208,154,203,163,223,154,203,156,195,156,195,158,166,163,223,156,195,155,193,158,166,158,166,155,193,155,190,158,166,155,190,155,171,155,171,155,190,154,187,155,171,154,187,154,183,87,226,60,217,67,182,87,226,67,182,74,195,87,226,74,195,83,206,87,226,83,206,96,213,67,182,60,217,65,167,28,184,24,165,26,152,28,184,26,152,31,141,28,184,31,141,40,202,83,102,97,107,92,127,92,127,97,107,108,124,115,125,108,124,111,108,83,102,92,127,80,133,83,102,80,133,72,142,83,102,72,142,70,94,63,118,70,94,65,167,111,108,108,124,97,107,117,108,121,107,121,126,121,126,121,107,125,106,121,126,125,106,126,127,126,127,125,106,128,106,126,127,128,106,131,128,131,128,128,106,133,105,131,128,133,105,138,129,138,129,133,105,142,106,138,129,142,106,145,128,145,128,142,106,148,108,145,128,148,108,150,127,150,127,148,108,153,111,150,127,153,111,154,124,154,124,153,111,156,115,154,124,156,115,156,122,156,122,156,115,157,118,115,125,111,108,117,108,115,125,117,108,121,126,80,27,108,-4,95,22,95,22,108,-4,110,20,131,22,110,20,130,-1,131,22,130,-1,151,6,69,36,60,49,65,0,69,36,65,0,108,-4,69,36,108,-4,80,27,57,65,65,0,60,49,12,61,14,46,15,77,15,77,14,46,21,29,15,77,21,29,22,91,22,91,21,29,37,13,22,91,37,13,33,103,33,103,37,13,47,113,204,68,196,73,189,40,189,40,196,73,182,54,189,40,182,54,171,20,171,20,182,54,166,39,171,20,166,39,151,6,151,6,166,39,149,29,151,6,149,29,131,22,110,20,108,-4,130,-1,47,113,57,65,63,118,155,171,154,183,153,179,94,253,106,320,76,253, 84,253,101,253,134,294,142,304,145,309,147,313,147,316,146,322,144,326,140,329,132,331,122,329,119,327,116,324,113,320,16383,16383,226,-107,223,-101,221,-94,219,-86,218,-76,218,160,216,182,208,202,196,217,180,226,159,230,145,229,131,224,117,216,102,205,87,190,86,190,84,205,81,215,76,223,68,226,56,228,44,225,33,216,22,203,13,188,5,172,12,170,15,176,25,188,30,193,36,194,39,193,41,190,44,184,45,173,46,156,46,0,88,0,88,174,100,185,111,194,120,199,130,202,140,203,153,201,163,195,170,185,174,172,176,154,176,-79,177,-89,179,-97,181,-103,184,-107, 15,176,20,182,22,203,22,203,20,182,25,188,22,203,25,188,33,216,33,216,25,188,30,193,33,216,30,193,36,194,36,194,39,193,44,225,44,225,39,193,41,190,44,225,41,190,44,184,13,188,5,172,12,170,13,188,12,170,15,176,13,188,15,176,22,203,87,190,86,190,88,0,87,190,88,0,88,174,87,190,88,174,102,205,88,174,100,185,102,205,102,205,100,185,111,194,102,205,111,194,117,216,117,216,111,194,120,199,117,216,120,199,131,224,131,224,120,199,130,202,131,224,130,202,140,203,140,203,153,201,145,229,145,229,153,201,159,230,88,0,86,190,84,205,88,0,84,205,81,215,88,0,81,215,76,223,88,0,76,223,68,226,88,0,68,226,56,228,88,0,56,228,46,156,88,0,46,156,46,0,145,229,131,224,140,203,218,-65,218,160,216,182,218,-65,216,182,208,202,218,-65,208,202,218,-76,196,217,180,226,181,-103,196,217,181,-103,184,-107,196,217,184,-107,218,-76,196,217,218,-76,208,202,184,-107,226,-107,223,-101,184,-107,223,-101,221,-94,184,-107,221,-94,219,-86,184,-107,219,-86,218,-76,180,226,159,230,163,195,180,226,163,195,170,185,180,226,170,185,174,172,180,226,174,172,176,154,180,226,176,154,176,-79,180,226,176,-79,177,-89,180,226,177,-89,179,-97,180,226,179,-97,181,-103,176,154,176,-64,176,-79,132,331,134,294,136,330,136,330,134,294,138,299,136,330,138,299,140,329,140,329,138,299,142,304,140,329,142,304,144,326,144,326,142,304,145,309,144,326,145,309,146,322,146,322,145,309,147,313,146,322,147,313,147,316,134,294,132,331,127,330,134,294,127,330,122,329,134,294,122,329,119,327,134,294,119,327,116,324,134,294,116,324,113,320,134,294,113,320,101,253,45,173,46,156,56,228,45,173,56,228,44,225,45,173,44,225,44,184,44,225,33,216,36,194,101,253,113,320,84,253,159,230,153,201,163,195, 40,253,57,253,90,294,98,304,101,309,103,313,103,316,102,322,100,326,96,329,93,330,89,331,83,330,78,329,75,327,72,324,70,320,16383,16383,126,54,120,43,115,36,110,31,105,29,99,28,95,29,91,33,90,36,89,40,89,228,88,230,72,224,57,219,41,214,26,208,10,204,10,195,15,196,37,196,42,193,45,188,47,181,47,39,48,26,51,14,57,4,65,-2,77,-4,92,-1,105,7,116,20,126,35,133,50, 89,331,90,294,93,330,93,330,90,294,94,299,93,330,94,299,96,329,96,329,94,299,98,304,96,329,98,304,100,326,100,326,98,304,101,309,100,326,101,309,102,322,102,322,101,309,103,313,102,322,103,313,103,316,90,294,89,331,83,330,90,294,83,330,78,329,90,294,78,329,75,327,90,294,75,327,72,324,90,294,72,324,70,320,90,294,70,320,57,253,45,188,57,219,42,193,42,193,57,219,41,214,42,193,41,214,37,196,37,196,41,214,31,196,28,196,31,196,41,214,28,196,41,214,26,208,57,4,65,-2,72,224,72,224,65,-2,77,-4,72,224,77,-4,88,230,88,230,77,-4,89,40,88,230,89,40,89,228,91,33,92,-1,93,31,93,31,92,-1,105,7,93,31,105,7,95,29,95,29,105,7,99,28,105,29,99,28,105,7,105,29,105,7,116,20,133,50,126,54,126,35,126,35,126,54,120,43,126,35,120,43,116,20,116,20,120,43,115,36,116,20,115,36,110,31,92,-1,91,33,90,36,92,-1,90,36,89,40,92,-1,89,40,77,-4,57,219,45,188,47,181,57,219,47,181,47,172,57,219,47,172,48,26,57,219,48,26,51,14,57,219,51,14,57,4,57,219,57,4,72,224,47,172,47,39,48,26,26,208,10,204,15,196,26,208,15,196,20,196,26,208,20,196,24,196,26,208,24,196,28,196,15,196,10,204,10,195,105,29,116,20,110,31,57,253,70,320,40,253, 202,278,201,286,197,293,192,298,185,302,177,303,169,302,163,298,157,293,154,286,152,278,154,271,157,264,163,258,169,255,177,253,185,255,192,258,197,264,201,271,202,278,16383,16383,100,253,118,253,151,294,159,304,162,309,163,313,164,316,163,322,161,326,157,329,149,331,143,330,139,329,135,327,132,324,130,320,16383,16383,103,278,101,286,98,293,92,298,85,302,78,303,70,302,63,298,58,293,54,286,53,278,54,271,58,264,63,258,70,255,78,253,85,255,92,258,98,264,101,271,103,278,16383,16383,127,230,127,220,139,218,149,214,159,209,168,201,177,191,186,176,193,159,198,141,201,122,202,104,200,75,193,49,182,28,165,14,142,9,121,14,106,28,97,47,92,68,91,87,91,193,90,205,86,215,80,222,71,226,60,228,47,225,36,216,26,203,16,188,8,172,15,170,18,176,28,188,33,193,39,194,43,192,46,187,48,180,49,170,49,99,51,66,60,38,76,15,102,0,139,-4,174,1,204,18,227,43,242,75,247,113,241,155,226,188,202,211,173,225,141,230, 18,176,23,182,26,203,26,203,23,182,28,188,26,203,28,188,36,216,36,216,28,188,33,193,36,216,33,193,39,194,39,194,43,192,47,225,47,225,43,192,46,187,47,225,46,187,48,180,16,188,8,172,15,170,16,188,15,170,18,176,16,188,18,176,26,203,49,99,51,66,49,159,49,170,49,159,60,228,49,170,60,228,48,180,48,180,60,228,47,225,54,286,54,271,58,293,58,293,54,271,58,264,58,293,58,264,63,298,63,298,58,264,63,258,63,298,63,258,70,302,70,302,63,258,70,255,70,302,70,255,78,303,78,303,70,255,78,253,78,303,78,253,85,302,85,302,78,253,85,255,85,302,85,255,92,298,92,298,85,255,92,258,92,298,92,258,98,293,98,293,92,258,98,264,98,293,98,264,101,286,101,286,98,264,101,271,101,286,101,271,103,278,91,87,91,193,90,205,91,87,90,205,86,215,91,87,86,215,80,222,91,87,80,222,92,68,141,230,127,230,139,218,141,230,139,218,149,214,141,230,149,214,173,225,200,75,193,49,204,18,204,18,193,49,182,28,204,18,182,28,174,1,174,1,182,28,165,14,174,1,165,14,142,9,142,9,121,14,139,-4,139,-4,121,14,106,28,139,-4,106,28,102,0,102,0,106,28,97,47,102,0,97,47,92,68,76,15,102,0,92,68,76,15,92,68,80,222,76,15,80,222,71,226,76,15,71,226,60,228,76,15,60,228,60,38,60,228,49,159,51,66,60,228,51,66,60,38,47,225,36,216,39,194,149,214,159,209,173,225,173,225,159,209,168,201,173,225,168,201,177,191,177,191,186,176,202,211,202,211,186,176,193,159,202,211,193,159,198,141,202,211,202,104,204,18,202,211,204,18,226,188,226,188,204,18,227,43,226,188,227,43,241,155,241,155,227,43,242,75,241,155,242,75,247,113,202,211,198,141,201,122,202,211,201,122,202,104,202,211,173,225,177,191,142,9,139,-4,174,1,154,286,154,271,157,293,157,293,154,271,157,264,157,293,157,264,163,298,163,298,157,264,163,258,163,298,163,258,169,302,169,302,163,258,169,255,169,302,169,255,177,303,177,303,169,255,177,253,177,303,177,253,185,302,185,302,177,253,185,255,185,302,185,255,192,298,192,298,185,255,192,258,192,298,192,258,197,293,197,293,192,258,197,264,197,293,197,264,201,286,201,286,197,264,201,271,201,286,201,271,202,278,149,331,151,294,153,330,153,330,151,294,155,299,153,330,155,299,157,329,157,329,155,299,159,304,157,329,159,304,161,326,161,326,159,304,162,309,161,326,162,309,163,322,163,322,162,309,163,313,163,322,163,313,164,316,151,294,149,331,143,330,151,294,143,330,139,329,151,294,139,329,135,327,151,294,135,327,132,324,151,294,132,324,130,320,151,294,130,320,118,253,118,253,130,320,100,253,154,271,154,286,152,278,200,75,204,18,202,104,139,218,127,230,127,220,54,271,54,286,53,278, 257,65,255,50,252,39,248,32,245,27,241,26,232,31,223,43,216,60,210,78,206,94,261,225,212,225,190,157,182,178,171,198,156,215,137,226,113,230,79,224,52,207,31,181,19,148,15,112,19,73,32,41,52,16,78,1,108,-4,129,-1,147,5,162,17,174,32,185,50,190,32,196,17,204,5,213,-1,225,-4,239,0,250,8,258,24,263,43,265,65,16383,16383,166,104,162,84,155,59,145,35,131,16,113,9,90,19,75,43,66,76,61,109,60,137,63,167,70,189,81,204,95,213,110,216,129,208,144,187,154,159,161,130,166,104, 63,167,70,189,79,224,79,224,70,189,81,204,79,224,81,204,113,230,113,230,81,204,95,213,113,230,95,213,110,216,110,216,129,208,113,230,113,230,129,208,137,226,144,187,154,159,156,215,156,215,154,159,161,130,156,215,161,130,171,198,171,198,161,130,166,104,171,198,166,104,174,32,171,198,174,32,182,178,182,178,174,32,185,50,182,178,185,50,190,157,190,157,185,50,190,32,190,157,190,32,212,225,212,225,190,32,196,17,212,225,196,17,206,94,206,94,196,17,204,5,206,94,204,5,213,-1,137,226,129,208,144,187,137,226,144,187,156,215,174,32,166,104,162,84,174,32,162,84,162,17,162,17,162,84,155,59,162,17,155,59,147,5,147,5,155,59,145,35,147,5,145,35,131,16,78,1,108,-4,90,19,90,19,108,-4,113,9,131,16,113,9,129,-1,131,16,129,-1,147,5,210,78,206,94,213,-1,212,225,206,94,261,225,252,39,248,32,250,8,250,8,248,32,245,27,250,8,245,27,241,26,241,26,232,31,239,0,239,0,232,31,225,-4,210,78,213,-1,216,60,216,60,213,-1,225,-4,216,60,225,-4,223,43,223,43,225,-4,232,31,258,24,263,43,265,65,258,24,265,65,257,65,258,24,257,65,255,50,258,24,255,50,252,39,258,24,252,39,250,8,241,26,239,0,250,8,113,9,108,-4,129,-1,90,19,75,43,78,1,78,1,75,43,66,76,78,1,66,76,52,16,52,16,66,76,61,109,52,16,61,109,60,137,60,137,63,167,52,207,52,207,63,167,79,224,52,16,60,137,52,207,52,16,52,207,32,41,32,41,52,207,31,181,32,41,31,181,19,73,19,73,31,181,19,148,19,73,19,148,15,112, 172,200,181,204,190,209,196,215,202,222,206,229,209,236,211,244,213,251,213,257,214,264,209,289,197,311,179,327,157,338,133,342,102,337,76,322,54,293,41,249,36,186,36,-67,34,-85,30,-101,27,-107,70,-107,72,-102,74,-95,76,-87,78,-67,78,16,88,7,98,1,108,-2,119,-3,131,-4,164,2,192,19,214,46,228,78,233,114,231,137,223,158,211,176,194,190,173,199,16383,16383,78,243,78,250,79,276,85,297,95,314,108,324,124,328,144,322,158,309,167,290,172,268,173,247,172,235,170,225,166,215,160,209,152,206,147,207,141,208,136,209,130,210,118,210,112,208,108,206,106,203,105,200,106,195,109,192,113,189,118,188,125,187,130,187,142,190,148,190,158,187,169,178,179,162,187,136,190,101,187,72,179,47,167,28,150,16,129,11,114,13,100,19,88,26,80,35,78,45, 108,324,124,328,124,328,133,342,124,328,144,322,133,342,144,322,157,338,157,338,144,322,158,309,157,338,158,309,179,327,179,327,158,309,167,290,179,327,167,290,172,268,172,200,181,204,172,235,172,200,172,235,170,225,172,200,170,225,169,178,172,200,169,178,179,162,172,200,179,162,173,199,233,114,231,137,228,78,228,78,231,137,223,158,228,78,223,158,214,46,214,46,223,158,211,176,214,46,211,176,194,190,192,19,214,46,194,190,192,19,194,190,190,101,192,19,190,101,187,72,192,19,187,72,179,47,192,19,179,47,167,28,192,19,167,28,164,2,194,190,173,199,179,162,194,190,179,162,187,136,194,190,187,136,190,101,170,225,166,215,169,178,169,178,166,215,160,209,169,178,160,209,158,187,158,187,160,209,152,206,129,11,131,-4,150,16,150,16,131,-4,164,2,150,16,164,2,167,28,85,297,95,314,102,337,102,337,95,314,108,324,102,337,108,324,133,342,133,342,108,324,124,328,78,250,79,276,76,322,78,250,76,322,76,-87,78,250,76,-87,77,-77,78,250,77,-77,78,-67,76,322,79,276,85,297,76,322,85,297,102,337,76,322,54,293,70,-107,76,322,70,-107,72,-102,76,322,72,-102,74,-95,76,322,74,-95,76,-87,70,-107,54,293,41,249,70,-107,41,249,36,186,70,-107,36,186,36,-67,70,-107,36,-67,35,-76,70,-107,35,-76,34,-85,70,-107,34,-85,32,-93,70,-107,32,-93,30,-101,70,-107,30,-101,27,-107,114,13,100,19,108,-2,114,13,108,-2,119,-3,114,13,119,-3,129,11,108,-2,100,19,98,1,98,1,100,19,88,26,98,1,88,26,88,7,88,7,88,26,80,35,88,7,80,35,78,45,78,45,78,16,88,7,148,190,152,206,147,207,148,190,147,207,142,190,118,188,125,187,127,210,127,210,125,187,130,187,127,210,130,187,130,210,130,210,130,187,134,188,130,210,134,188,136,209,136,209,134,188,138,189,136,209,138,189,141,208,141,208,138,189,142,190,141,208,142,190,147,207,106,203,106,195,108,206,108,206,106,195,109,192,108,206,109,192,112,208,112,208,109,192,113,189,112,208,113,189,118,210,118,210,113,189,118,188,118,210,118,188,127,210,173,247,181,204,179,327,173,247,179,327,172,268,206,229,209,236,209,289,209,289,209,236,211,244,209,289,211,244,214,264,214,264,211,244,213,251,214,264,213,251,213,257,190,209,196,215,197,311,197,311,196,215,202,222,197,311,202,222,209,289,209,289,202,222,206,229,197,311,179,327,181,204,197,311,181,204,190,209,172,235,181,204,173,247,148,190,158,187,152,206,131,-4,129,11,119,-3,106,195,106,203,105,200, 222,225,172,225,120,49,115,84,108,130,97,177,78,214,49,228,32,224,20,212,12,195,7,173,5,150,12,150,16,166,21,178,28,187,35,192,41,194,66,179,84,143,96,96,103,50,107,18,103,9,100,0,96,-7,90,-25,84,-47,82,-57,81,-66,81,-74,82,-85,85,-94,90,-101,96,-106,105,-108,118,-105,127,-98,133,-87,135,-73,136,-58,136,-45,135,-32,133,-19,131,-8,129,0, 35,192,41,194,41,194,49,228,41,194,66,179,49,228,66,179,78,214,78,214,66,179,84,143,78,214,84,143,97,177,97,177,84,143,96,96,97,177,96,96,103,50,120,49,115,84,118,-105,118,-105,115,84,108,130,118,-105,108,130,107,18,107,18,108,130,103,50,103,50,108,130,97,177,118,-105,127,-98,120,49,120,49,127,-98,129,0,120,49,129,0,172,225,172,225,129,0,222,225,107,18,103,9,105,-108,107,18,105,-108,118,-105,100,0,96,-7,96,-106,100,0,96,-106,105,-108,100,0,105,-108,103,9,96,-7,93,-16,96,-106,96,-106,93,-16,90,-25,96,-106,90,-25,90,-101,90,-101,90,-25,87,-36,90,-101,87,-36,85,-94,85,-94,87,-36,84,-47,85,-94,84,-47,82,-57,82,-85,85,-94,82,-57,82,-85,82,-57,81,-66,82,-85,81,-66,81,-74,135,-73,136,-58,136,-45,135,-73,136,-45,135,-32,135,-73,135,-32,133,-19,135,-73,133,-19,133,-87,133,-87,133,-19,131,-8,133,-87,131,-8,129,0,133,-87,129,0,127,-98,21,178,28,187,32,224,32,224,28,187,35,192,32,224,35,192,49,228,49,228,35,192,41,194,20,212,12,195,12,150,20,212,12,150,16,166,20,212,16,166,21,178,20,212,21,178,32,224,7,173,5,150,12,150,7,173,12,150,12,195, 110,213,77,203,50,187,31,164,19,137,15,108,20,74,34,44,56,18,86,1,123,-4,161,1,192,17,215,43,230,76,235,116,232,141,225,164,213,184,197,202,176,217,145,233,114,248,87,261,68,274,61,290,64,302,72,310,83,316,95,319,106,320,137,316,154,307,165,296,176,286,191,282,198,284,203,288,206,293,208,299,209,304,203,318,188,328,168,336,145,340,124,342,102,340,81,334,61,324,47,309,42,289,45,269,54,251,68,237,87,224,110,213,16383,16383,190,104,187,71,180,45,168,25,151,13,130,9,121,10,111,13,101,19,93,26,85,35,76,52,69,70,64,88,61,106,60,121,62,144,70,165,84,183,103,195,127,200,149,190,167,172,179,149,187,126,190,104, 42,289,45,269,47,309,47,309,45,269,54,251,47,309,54,251,61,324,61,324,54,251,61,290,68,237,61,290,54,251,64,302,72,310,81,334,81,334,72,310,83,316,81,334,83,316,102,340,102,340,83,316,95,319,102,340,95,319,106,320,106,320,137,316,124,342,124,342,137,316,145,340,61,324,61,290,64,302,61,324,64,302,81,334,198,284,203,288,203,318,203,318,203,288,206,293,203,318,206,293,209,304,209,304,206,293,208,299,154,307,165,296,168,336,168,336,165,296,176,286,168,336,176,286,188,328,188,328,176,286,191,282,188,328,191,282,203,318,203,318,191,282,198,284,145,340,137,316,154,307,145,340,154,307,168,336,235,116,232,141,230,76,230,76,232,141,225,164,230,76,225,164,215,43,215,43,225,164,213,184,215,43,213,184,197,202,192,17,215,43,197,202,192,17,197,202,190,104,192,17,190,104,187,71,192,17,187,71,180,45,192,17,180,45,168,25,192,17,168,25,161,1,197,202,176,217,179,149,197,202,179,149,187,126,197,202,187,126,190,104,145,233,127,200,149,190,145,233,149,190,176,217,176,217,149,190,167,172,176,217,167,172,179,149,111,13,123,-4,121,10,121,10,123,-4,130,9,151,13,130,9,161,1,151,13,161,1,168,25,130,9,123,-4,161,1,124,342,102,340,106,320,69,70,86,1,76,52,76,52,86,1,85,35,93,26,85,35,86,1,93,26,86,1,123,-4,68,274,68,237,87,261,87,261,68,237,87,224,87,261,87,224,114,248,114,248,87,224,110,213,114,248,110,213,127,200,62,144,70,165,77,203,77,203,70,165,84,183,77,203,84,183,110,213,110,213,84,183,103,195,110,213,103,195,127,200,77,203,50,187,62,144,62,144,50,187,60,121,61,106,60,121,56,18,61,106,56,18,64,88,64,88,56,18,86,1,64,88,86,1,69,70,56,18,60,121,50,187,56,18,50,187,34,44,34,44,50,187,31,164,34,44,31,164,20,74,20,74,31,164,19,137,20,74,19,137,15,108,101,19,93,26,123,-4,101,19,123,-4,111,13,61,290,68,237,68,274,127,200,145,233,114,248, 196,73,182,54,166,39,149,29,131,22,110,20,95,22,80,27,69,36,60,49,57,65,61,81,70,94,83,102,97,107,111,108,117,108,125,106,128,106,133,105,142,106,148,108,153,111,156,115,157,118,156,122,154,124,150,127,145,128,138,129,131,128,121,126,115,125,108,124,92,127,80,133,72,142,67,154,65,167,67,182,74,195,83,206,96,213,112,215,127,215,140,212,148,208,154,203,156,195,155,193,155,190,154,187,154,183,153,179,155,171,158,166,163,161,168,158,175,157,182,158,188,161,194,165,198,171,199,179,194,199,181,214,163,223,142,228,121,230,87,226,60,217,40,202,28,184,24,165,26,152,31,141,39,131,49,123,63,118,47,113,33,103,22,91,15,77,12,61,14,46,21,29,37,13,65,0,108,-4,130,-1,151,6,171,20,189,40,204,68, 37,13,65,0,47,113,47,113,65,0,57,65,63,118,57,65,61,81,63,118,61,81,70,94,72,142,67,154,70,94,70,94,67,154,65,167,63,118,65,167,60,217,63,118,60,217,49,123,49,123,60,217,40,202,49,123,40,202,39,131,39,131,40,202,31,141,142,228,121,230,127,215,127,215,121,230,112,215,96,213,112,215,121,230,96,213,121,230,87,226,194,199,181,214,182,158,194,199,182,158,188,161,194,199,188,161,194,165,194,199,194,165,198,171,194,199,198,171,199,179,158,166,163,161,163,223,163,223,163,161,168,158,163,223,168,158,181,214,181,214,168,158,175,157,181,214,175,157,182,158,127,215,140,212,142,228,142,228,140,212,148,208,142,228,148,208,163,223,163,223,148,208,154,203,163,223,154,203,156,195,156,195,158,166,163,223,156,195,155,193,158,166,158,166,155,193,155,190,158,166,155,190,155,171,155,171,155,190,154,187,155,171,154,187,154,183,87,226,60,217,67,182,87,226,67,182,74,195,87,226,74,195,83,206,87,226,83,206,96,213,67,182,60,217,65,167,28,184,24,165,26,152,28,184,26,152,31,141,28,184,31,141,40,202,83,102,97,107,92,127,92,127,97,107,108,124,115,125,108,124,111,108,83,102,92,127,80,133,83,102,80,133,72,142,83,102,72,142,70,94,63,118,70,94,65,167,111,108,108,124,97,107,117,108,121,107,121,126,121,126,121,107,125,106,121,126,125,106,126,127,126,127,125,106,128,106,126,127,128,106,131,128,131,128,128,106,133,105,131,128,133,105,138,129,138,129,133,105,142,106,138,129,142,106,145,128,145,128,142,106,148,108,145,128,148,108,150,127,150,127,148,108,153,111,150,127,153,111,154,124,154,124,153,111,156,115,154,124,156,115,156,122,156,122,156,115,157,118,115,125,111,108,117,108,115,125,117,108,121,126,80,27,108,-4,95,22,95,22,108,-4,110,20,131,22,110,20,130,-1,131,22,130,-1,151,6,69,36,60,49,65,0,69,36,65,0,108,-4,69,36,108,-4,80,27,57,65,65,0,60,49,12,61,14,46,15,77,15,77,14,46,21,29,15,77,21,29,22,91,22,91,21,29,37,13,22,91,37,13,33,103,33,103,37,13,47,113,204,68,196,73,189,40,189,40,196,73,182,54,189,40,182,54,171,20,171,20,182,54,166,39,171,20,166,39,151,6,151,6,166,39,149,29,151,6,149,29,131,22,110,20,108,-4,130,-1,47,113,57,65,63,118,155,171,154,183,153,179, 76,342,59,335,45,327,35,318,29,308,27,296,30,283,38,272,48,265,60,260,71,259,72,257,52,225,36,196,25,166,19,135,17,100,21,58,33,28,49,9,71,-1,95,-4,105,-4,117,-2,128,-1,137,0,143,0,158,-1,170,-5,180,-12,186,-22,188,-34,186,-47,180,-58,170,-67,159,-72,147,-74,140,-72,134,-69,128,-64,123,-61,117,-59,110,-60,104,-63,99,-68,97,-73,96,-80,98,-90,103,-98,111,-103,121,-107,132,-108,151,-104,170,-93,187,-76,199,-55,204,-29,201,-3,192,16,177,30,156,38,128,41,117,41,113,40,103,40,78,44,61,55,49,72,43,93,41,117,44,151,53,184,65,213,80,238,94,257,119,262,142,271,161,283,174,297,179,311,178,316,175,321,171,325,166,327,159,328,142,325,125,315,108,302,94,287,84,273,74,274,65,277,57,281,52,288,50,298,51,305,55,312,61,320,70,328,81,334, 43,93,41,117,41,117,36,196,41,117,44,151,36,196,44,151,52,225,52,225,44,151,53,184,52,225,53,184,72,257,72,257,53,184,65,213,72,257,65,213,80,238,48,265,50,298,45,327,48,265,45,327,38,272,38,272,45,327,35,318,38,272,35,318,30,283,30,283,35,318,29,308,30,283,29,308,27,296,51,305,55,312,59,335,59,335,55,312,61,320,59,335,61,320,76,342,76,342,61,320,70,328,76,342,70,328,81,334,51,305,59,335,45,327,51,305,45,327,50,298,108,302,94,287,94,257,94,257,94,287,84,273,94,257,84,273,80,238,80,238,84,273,74,274,80,238,74,274,72,257,72,257,74,274,71,259,166,327,159,328,161,283,161,283,159,328,142,325,161,283,142,325,142,271,142,271,142,325,125,315,142,271,125,315,119,262,119,262,125,315,108,302,119,262,108,302,94,257,65,277,57,281,60,260,65,277,60,260,71,259,65,277,71,259,74,274,52,288,50,298,48,265,52,288,48,265,60,260,52,288,60,260,57,281,71,-1,95,-4,78,44,78,44,95,-4,103,40,108,40,103,40,105,-4,108,40,105,-4,117,-2,61,55,49,72,49,9,61,55,49,9,71,-1,61,55,71,-1,78,44,43,93,41,117,33,28,43,93,33,28,49,9,43,93,49,9,49,72,41,117,36,196,33,28,33,28,36,196,25,166,33,28,25,166,21,58,21,58,25,166,19,135,21,58,19,135,17,100,177,30,156,38,158,-1,158,-1,156,38,143,0,137,0,143,0,156,38,137,0,156,38,128,41,128,-1,137,0,128,41,128,-1,128,41,123,41,128,-1,123,41,117,41,128,-1,117,41,117,-2,113,40,108,40,117,-2,113,40,117,-2,117,41,128,-64,132,-108,134,-69,134,-69,132,-108,151,-104,134,-69,151,-104,140,-72,140,-72,151,-104,147,-74,159,-72,147,-74,151,-104,159,-72,151,-104,170,-93,204,-29,201,-3,199,-55,199,-55,201,-3,192,16,199,-55,192,16,188,-34,188,-34,187,-76,199,-55,158,-1,170,-5,177,30,177,30,170,-5,180,-12,177,30,180,-12,192,16,192,16,180,-12,186,-22,192,16,186,-22,188,-34,187,-76,188,-34,186,-47,187,-76,186,-47,180,-58,187,-76,180,-58,170,-67,187,-76,170,-67,170,-93,110,-60,111,-103,117,-59,117,-59,111,-103,121,-107,117,-59,121,-107,123,-61,123,-61,121,-107,132,-108,123,-61,132,-108,128,-64,97,-73,98,-90,99,-68,99,-68,98,-90,103,-98,99,-68,103,-98,104,-63,104,-63,103,-98,111,-103,104,-63,111,-103,110,-60,175,321,171,325,174,297,175,321,174,297,179,311,175,321,179,311,178,316,166,327,161,283,174,297,166,327,174,297,171,325,103,40,95,-4,105,-4,98,-90,97,-73,96,-80,159,-72,170,-93,170,-67, 226,-107,223,-101,221,-94,219,-86,218,-76,218,160,216,182,208,202,196,217,180,226,159,230,145,229,131,224,117,216,102,205,87,190,86,190,84,205,81,215,76,223,68,226,56,228,44,225,33,216,22,203,13,188,5,172,12,170,15,176,25,188,30,193,36,194,39,193,41,190,44,184,45,173,46,156,46,0,88,0,88,174,100,185,111,194,120,199,130,202,140,203,153,201,163,195,170,185,174,172,176,154,176,-79,177,-89,179,-97,181,-103,184,-107, 15,176,20,182,22,203,22,203,20,182,25,188,22,203,25,188,33,216,33,216,25,188,30,193,33,216,30,193,36,194,36,194,39,193,44,225,44,225,39,193,41,190,44,225,41,190,44,184,13,188,5,172,12,170,13,188,12,170,15,176,13,188,15,176,22,203,87,190,86,190,88,0,87,190,88,0,88,174,87,190,88,174,102,205,88,174,100,185,102,205,102,205,100,185,111,194,102,205,111,194,117,216,117,216,111,194,120,199,117,216,120,199,131,224,131,224,120,199,130,202,131,224,130,202,140,203,140,203,153,201,145,229,145,229,153,201,159,230,88,0,86,190,84,205,88,0,84,205,81,215,88,0,81,215,76,223,88,0,76,223,68,226,88,0,68,226,56,228,88,0,56,228,46,156,88,0,46,156,46,0,145,229,131,224,140,203,218,-65,218,160,216,182,218,-65,216,182,208,202,218,-65,208,202,218,-76,196,217,180,226,181,-103,196,217,181,-103,184,-107,196,217,184,-107,218,-76,196,217,218,-76,208,202,184,-107,226,-107,223,-101,184,-107,223,-101,221,-94,184,-107,221,-94,219,-86,184,-107,219,-86,218,-76,180,226,159,230,163,195,180,226,163,195,170,185,180,226,170,185,174,172,180,226,174,172,176,154,180,226,176,154,176,-79,180,226,176,-79,177,-89,180,226,177,-89,179,-97,180,226,179,-97,181,-103,176,154,176,-64,176,-79,45,173,46,156,56,228,45,173,56,228,44,225,45,173,44,225,44,184,44,225,33,216,36,194,159,230,153,201,163,195, 234,166,233,198,230,228,226,254,220,277,211,296,199,313,185,325,169,334,150,340,126,342,87,333,55,310,32,273,18,226,13,170,14,144,15,120,18,100,23,81,28,64,40,41,55,21,74,7,96,-1,122,-4,161,3,192,27,215,63,229,110,234,166,16383,16383,59,177,59,193,62,247,70,285,83,310,99,324,119,328,150,318,171,292,182,256,188,216,189,177,16383,16383,189,158,187,109,180,67,168,36,151,16,128,9,98,18,78,42,67,77,61,118,59,161,189,161, 150,340,126,342,150,318,150,318,126,342,119,328,99,324,119,328,126,342,99,324,126,342,87,333,230,228,226,254,229,110,230,228,229,110,234,166,230,228,234,166,233,198,220,277,211,296,215,63,220,277,215,63,229,110,220,277,229,110,226,254,23,81,28,64,32,273,32,273,28,64,40,41,32,273,40,41,55,310,55,310,40,41,55,21,55,310,55,21,59,193,59,193,55,21,59,161,59,193,59,161,59,177,59,177,59,161,189,177,189,177,59,161,189,161,189,177,189,161,192,27,189,177,192,27,199,313,199,313,192,27,215,63,199,313,215,63,211,296,171,292,182,256,185,325,185,325,182,256,188,216,185,325,188,216,199,313,199,313,188,216,189,177,169,334,150,340,150,318,169,334,150,318,171,292,169,334,171,292,185,325,187,109,180,67,192,27,192,27,180,67,168,36,192,27,168,36,161,3,161,3,168,36,151,16,161,3,151,16,128,9,128,9,98,18,122,-4,122,-4,98,18,96,-1,78,42,67,77,74,7,78,42,74,7,96,-1,78,42,96,-1,98,18,59,161,55,21,61,118,61,118,55,21,74,7,61,118,74,7,67,77,189,158,187,109,192,27,189,158,192,27,189,161,128,9,122,-4,161,3,59,193,62,247,55,310,55,310,62,247,70,285,55,310,70,285,87,333,87,333,70,285,83,310,87,333,83,310,99,324,14,144,15,120,18,226,18,226,15,120,18,100,18,226,18,100,32,273,32,273,18,100,23,81,14,144,18,226,13,170, 126,54,120,43,115,36,110,31,105,29,99,28,95,29,91,33,90,36,89,40,89,228,88,230,72,224,57,219,41,214,26,208,10,204,10,195,15,196,37,196,42,193,45,188,47,181,47,39,48,26,51,14,57,4,65,-2,77,-4,92,-1,105,7,116,20,126,35,133,50, 45,188,57,219,42,193,42,193,57,219,41,214,42,193,41,214,37,196,37,196,41,214,31,196,28,196,31,196,41,214,28,196,41,214,26,208,57,4,65,-2,72,224,72,224,65,-2,77,-4,72,224,77,-4,88,230,88,230,77,-4,89,40,88,230,89,40,89,228,91,33,92,-1,93,31,93,31,92,-1,105,7,93,31,105,7,95,29,95,29,105,7,99,28,105,29,99,28,105,7,105,29,105,7,116,20,133,50,126,54,126,35,126,35,126,54,120,43,126,35,120,43,116,20,116,20,120,43,115,36,116,20,115,36,110,31,92,-1,91,33,90,36,92,-1,90,36,89,40,92,-1,89,40,77,-4,57,219,45,188,47,181,57,219,47,181,47,172,57,219,47,172,48,26,57,219,48,26,51,14,57,219,51,14,57,4,57,219,57,4,72,224,47,172,47,39,48,26,26,208,10,204,15,196,26,208,15,196,20,196,26,208,20,196,24,196,26,208,24,196,28,196,15,196,10,204,10,195,105,29,116,20,110,31, 252,0,252,7,239,10,228,13,219,19,209,27,199,39,113,140,131,158,147,172,161,181,174,185,188,187,194,186,201,185,207,183,213,182,220,181,227,182,233,185,239,189,243,196,245,206,244,214,240,220,234,225,226,229,215,230,202,228,184,222,160,205,127,176,83,129,83,229,81,230,70,226,48,220,35,216,18,212,3,208,3,200,10,200,14,201,20,201,28,200,34,197,38,192,40,183,41,171,41,0,83,0,83,113,148,34,151,30,155,24,156,22,156,20,155,15,153,12,149,9,144,8,137,7,133,7,133,0, 10,200,14,201,18,212,18,212,14,201,17,201,18,212,17,201,20,201,20,201,28,200,35,216,35,216,28,200,34,197,35,216,34,197,38,192,7,200,10,200,18,212,7,200,18,212,3,208,7,200,3,208,3,200,35,216,38,192,48,220,48,220,38,192,40,183,48,220,40,183,41,171,83,0,41,171,41,0,35,216,18,212,20,201,83,129,83,229,81,230,83,129,81,230,83,0,83,129,83,0,83,113,83,129,83,113,127,176,131,158,147,172,160,205,160,205,147,172,161,181,160,205,161,181,184,222,184,222,161,181,174,185,184,222,174,185,188,187,188,187,194,186,202,228,202,228,194,186,201,185,202,228,201,185,207,183,127,176,83,113,113,140,127,176,113,140,131,158,127,176,131,158,160,205,83,0,81,230,70,226,83,0,70,226,59,223,83,0,59,223,48,220,83,0,48,220,41,171,227,182,233,185,234,225,234,225,233,185,239,189,234,225,239,189,240,220,240,220,239,189,243,196,240,220,243,196,244,214,244,214,243,196,245,206,207,183,213,182,215,230,215,230,213,182,220,181,215,230,220,181,226,229,226,229,220,181,227,182,226,229,227,182,234,225,202,228,184,222,188,187,153,12,149,9,252,0,252,0,149,9,144,8,252,0,144,8,137,7,156,20,252,0,228,13,156,20,228,13,219,19,156,20,219,19,209,27,156,20,209,27,199,39,156,20,199,39,156,22,199,39,113,140,148,34,199,39,148,34,151,30,199,39,151,30,153,27,199,39,153,27,155,24,199,39,155,24,156,22,239,10,228,13,252,0,239,10,252,0,252,7,155,15,153,12,252,0,155,15,252,0,156,20,133,7,133,0,252,0,133,7,252,0,137,7,148,34,113,140,83,113,202,228,207,183,215,230, 238,69,235,53,229,42,222,35,215,31,209,30,200,32,193,38,186,47,181,58,176,71,121,266,113,292,104,313,95,329,83,338,68,342,51,337,39,325,32,308,28,288,26,268,34,268,38,284,43,295,49,302,56,305,64,306,74,304,83,296,92,283,100,267,107,248,113,225,6,0,56,0,128,177,164,45,169,29,176,15,184,4,193,-2,204,-5,219,-1,230,8,239,24,244,45,246,69, 56,305,64,306,64,306,68,342,64,306,74,304,68,342,74,304,83,338,83,338,74,304,83,296,83,338,83,296,95,329,95,329,83,296,92,283,95,329,92,283,100,267,113,292,107,248,113,225,113,292,113,225,121,266,121,266,113,225,128,177,121,266,128,177,176,71,176,71,128,177,164,45,176,71,164,45,169,29,104,313,95,329,100,267,104,313,100,267,107,248,104,313,107,248,113,292,176,71,169,29,176,15,176,71,176,15,184,4,113,225,6,0,56,0,113,225,56,0,128,177,200,32,193,38,193,-2,193,-2,193,38,186,47,193,-2,186,47,184,4,184,4,186,47,181,58,184,4,181,58,176,71,235,53,229,42,230,8,230,8,229,42,222,35,230,8,222,35,219,-1,219,-1,222,35,215,31,219,-1,215,31,209,30,209,30,200,32,204,-5,204,-5,200,32,193,-2,239,24,244,45,246,69,239,24,246,69,238,69,239,24,238,69,235,53,239,24,235,53,230,8,209,30,204,-5,219,-1,43,295,49,302,51,337,51,337,49,302,56,305,51,337,56,305,68,342,68,342,56,305,64,306,39,325,32,308,34,268,39,325,34,268,38,284,39,325,38,284,43,295,39,325,43,295,51,337,28,288,26,268,34,268,28,288,34,268,32,308, 251,53,244,42,239,35,234,31,230,29,224,28,221,29,218,31,216,36,215,45,214,56,214,225,172,225,172,59,171,53,169,48,166,44,161,40,153,33,144,29,136,26,128,24,121,24,108,26,96,32,87,41,80,53,78,69,78,225,36,225,36,-65,35,-75,34,-84,32,-93,30,-101,27,-107,69,-107,71,-102,73,-94,75,-85,76,-75,76,9,78,9,81,4,87,0,93,-2,101,-4,109,-4,119,-3,131,0,144,7,158,19,171,36,172,36,173,23,177,12,182,3,191,-2,203,-4,217,-1,230,7,241,20,250,35,258,50, 78,225,36,225,69,-107,78,225,69,-107,71,-102,78,225,71,-102,73,-94,78,225,73,-94,75,-85,78,225,75,-85,76,-75,78,225,76,-75,76,9,78,225,76,9,78,9,69,-107,36,225,36,-65,69,-107,36,-65,35,-75,69,-107,35,-75,34,-84,69,-107,34,-84,32,-93,69,-107,32,-93,30,-101,69,-107,30,-101,27,-107,87,0,93,-2,96,32,96,32,93,-2,101,-4,96,32,101,-4,108,26,108,26,101,-4,109,-4,108,26,109,-4,121,24,121,24,109,-4,119,-3,121,24,119,-3,131,0,171,53,169,48,171,36,171,36,169,48,166,44,171,36,166,44,161,40,161,40,153,33,158,19,158,19,153,33,144,29,158,19,144,29,144,7,144,7,144,29,136,26,144,7,136,26,131,0,131,0,136,26,128,24,131,0,128,24,121,24,87,41,80,53,81,4,87,41,81,4,87,0,87,41,87,0,96,32,81,4,80,53,78,69,81,4,78,69,78,9,214,225,172,225,173,23,173,23,172,225,172,68,173,23,172,68,172,36,172,36,172,68,172,59,172,36,172,59,171,36,171,36,172,59,171,53,161,40,158,19,171,36,214,225,173,23,177,12,214,225,177,12,182,3,214,225,182,3,191,-2,214,225,191,-2,203,-4,214,225,203,-4,214,56,244,42,239,35,241,20,241,20,239,35,234,31,241,20,234,31,230,7,230,7,234,31,230,29,230,7,230,29,224,28,224,28,221,29,230,7,230,7,221,29,218,31,230,7,218,31,217,-1,217,-1,218,31,216,36,217,-1,216,36,215,45,250,35,258,50,251,53,250,35,251,53,244,42,250,35,244,42,241,20,215,45,214,56,203,-4,215,45,203,-4,217,-1,76,9,76,-75,76,-64, 212,230,206,188,189,141,163,97,129,63,90,45,89,45,89,228,88,230,72,224,57,219,41,214,26,208,10,204,10,195,15,196,31,196,37,195,42,192,45,188,47,181,47,-6,59,-6,100,7,134,28,163,55,186,84,203,116,212,141,217,166,220,189,221,211,222,230, 45,188,57,219,42,192,42,192,57,219,41,214,42,192,41,214,37,195,37,195,41,214,31,196,28,196,31,196,41,214,28,196,41,214,26,208,89,228,88,230,89,45,89,45,88,230,72,224,89,45,72,224,59,-6,59,-6,72,224,57,219,59,-6,57,219,47,172,47,172,57,219,47,181,26,208,10,204,15,196,26,208,15,196,20,196,26,208,20,196,25,196,26,208,25,196,28,196,186,84,189,141,163,55,163,55,189,141,163,97,163,55,163,97,134,28,134,28,163,97,129,63,134,28,129,63,100,7,100,7,129,63,90,45,189,141,203,116,206,188,206,188,203,116,212,141,206,188,212,141,212,230,212,230,212,141,217,166,212,230,217,166,222,230,222,230,217,166,220,189,222,230,220,189,221,211,89,45,59,-6,100,7,89,45,100,7,90,45,47,172,47,-6,59,-6,15,196,10,204,10,195,189,141,186,84,203,116,57,219,45,188,47,181, 89,342,71,335,57,328,48,319,43,309,41,297,42,286,47,278,53,272,61,268,69,266,63,259,58,251,54,242,52,233,51,224,52,215,55,206,59,198,65,190,73,184,54,168,39,150,27,129,20,106,17,81,20,53,29,29,44,11,67,0,98,-4,107,-4,117,-2,128,-1,137,0,143,0,158,-1,170,-5,180,-12,186,-22,188,-34,186,-47,180,-59,170,-67,159,-72,147,-74,140,-72,134,-69,128,-64,123,-61,117,-59,110,-60,104,-63,99,-68,97,-73,96,-80,98,-90,103,-98,111,-103,121,-107,132,-108,151,-104,170,-93,187,-76,199,-53,204,-26,201,-3,192,15,177,29,156,38,128,41,118,41,111,40,98,40,79,42,63,48,51,59,43,75,40,98,43,118,50,136,62,152,77,164,94,174,102,172,110,171,117,170,142,170,157,173,171,178,181,186,185,197,184,204,179,210,172,214,164,216,153,217,140,216,127,213,113,208,101,202,89,194,83,199,78,204,74,211,72,218,71,225,73,235,77,243,83,251,93,256,106,258,126,260,144,264,160,271,171,280,175,291,174,297,171,301,166,305,160,307,151,307,139,306,125,303,111,297,96,290,83,281,76,283,70,286,66,291,64,297,63,305,64,310,66,316,72,322,80,328,93,334, 51,59,43,75,44,11,44,11,43,75,40,98,39,150,40,98,43,118,39,150,43,118,54,168,54,168,43,118,50,136,54,168,50,136,62,152,61,268,63,305,57,328,61,268,57,328,53,272,53,272,57,328,48,319,53,272,48,319,47,278,47,278,48,319,43,309,47,278,43,309,42,286,42,286,43,309,41,297,64,310,66,316,71,335,71,335,66,316,72,322,71,335,72,322,89,342,89,342,72,322,80,328,89,342,80,328,93,334,64,310,71,335,57,328,64,310,57,328,63,305,73,235,76,283,71,225,71,225,70,286,69,266,69,266,70,286,66,291,69,266,66,291,64,297,83,281,76,283,77,243,83,281,77,243,83,251,83,281,83,251,96,290,72,218,73,184,74,211,74,211,73,184,77,164,74,211,77,164,78,204,78,204,77,164,94,174,78,204,94,174,83,199,83,199,94,174,89,194,101,202,94,174,102,172,101,202,102,172,113,208,113,208,102,172,110,171,113,208,110,171,117,170,73,184,54,168,62,152,73,184,62,152,77,164,73,184,72,218,71,225,73,184,71,225,69,266,73,184,69,266,65,190,52,233,52,215,54,242,54,242,52,215,55,206,54,242,55,206,58,251,58,251,55,206,59,198,58,251,59,198,63,259,63,259,59,198,65,190,63,259,65,190,69,266,64,297,63,305,61,268,64,297,61,268,69,266,128,41,124,41,128,-1,128,-1,124,41,118,41,128,-1,118,41,117,-2,117,-2,118,41,111,40,117,-2,111,40,107,-4,107,-4,111,40,104,40,107,-4,104,40,98,-4,98,-4,104,40,98,40,177,29,156,38,158,-1,158,-1,156,38,143,0,137,0,143,0,156,38,137,0,156,38,128,41,128,-64,132,-108,134,-69,134,-69,132,-108,151,-104,134,-69,151,-104,140,-72,140,-72,151,-104,147,-74,159,-72,147,-74,151,-104,159,-72,151,-104,170,-93,204,-26,201,-3,199,-53,199,-53,201,-3,192,15,199,-53,192,15,188,-34,188,-34,187,-76,199,-53,158,-1,170,-5,177,29,177,29,170,-5,180,-12,177,29,180,-12,192,15,192,15,180,-12,186,-22,192,15,186,-22,188,-34,188,-34,186,-47,187,-76,187,-76,186,-47,180,-59,187,-76,180,-59,170,-93,170,-93,180,-59,170,-67,170,-93,170,-67,159,-72,110,-60,111,-103,117,-59,117,-59,111,-103,121,-107,117,-59,121,-107,123,-61,123,-61,121,-107,132,-108,123,-61,132,-108,128,-64,97,-73,98,-90,99,-68,99,-68,98,-90,103,-98,99,-68,103,-98,104,-63,104,-63,103,-98,111,-103,104,-63,111,-103,110,-60,181,186,185,197,184,204,181,186,184,204,179,210,181,186,179,210,172,214,181,186,172,214,171,178,117,170,124,170,127,213,127,213,124,170,131,170,127,213,131,170,140,216,140,216,131,170,142,170,140,216,142,170,153,217,153,217,142,170,157,173,153,217,157,173,164,216,164,216,157,173,171,178,164,216,171,178,172,214,160,307,160,271,166,305,166,305,160,271,171,280,166,305,171,280,171,301,171,301,171,280,175,291,171,301,175,291,174,297,125,303,126,260,139,306,139,306,126,260,144,264,139,306,144,264,151,307,151,307,144,264,160,271,151,307,160,271,160,307,83,251,93,256,96,290,96,290,93,256,106,258,96,290,106,258,111,297,111,297,106,258,126,260,111,297,126,260,125,303,79,42,63,48,67,0,79,42,67,0,98,-4,79,42,98,-4,98,40,51,59,44,11,67,0,51,59,67,0,63,48,29,29,44,11,40,98,29,29,40,98,39,150,29,29,39,150,27,129,29,29,27,129,20,53,20,106,17,81,20,53,20,106,20,53,27,129,113,208,117,170,127,213,98,-90,97,-73,96,-80,128,41,128,-1,137,0,52,215,52,233,51,224,94,174,101,202,89,194,70,286,71,225,76,283,76,283,73,235,77,243, 237,114,232,151,218,183,197,208,167,224,129,230,91,223,60,203,37,174,22,139,17,101,23,67,38,38,62,15,92,0,126,-4,161,2,191,20,215,47,231,79,237,114,16383,16383,192,95,190,74,183,52,172,31,156,17,134,11,107,19,87,38,73,65,65,95,62,122,64,145,70,169,80,191,97,207,119,214,148,205,168,184,182,155,190,124,192,95, 97,207,119,214,119,214,129,230,119,214,148,205,129,230,148,205,167,224,167,224,148,205,168,184,167,224,168,184,197,208,197,208,168,184,182,155,197,208,182,155,190,124,190,74,183,52,191,20,191,20,183,52,172,31,191,20,172,31,161,2,161,2,172,31,156,17,161,2,156,17,134,11,134,11,107,19,126,-4,126,-4,107,19,92,0,107,19,87,38,92,0,92,0,87,38,73,65,92,0,73,65,62,15,62,15,73,65,65,95,62,15,65,95,62,122,80,191,91,223,70,169,70,169,91,223,60,203,70,169,60,203,64,145,64,145,60,203,62,122,62,15,62,122,60,203,62,15,60,203,38,38,38,38,60,203,37,174,38,38,37,174,23,67,23,67,37,174,22,139,23,67,22,139,17,101,237,114,232,151,231,79,231,79,232,151,218,183,231,79,218,183,215,47,215,47,218,183,197,208,215,47,197,208,192,95,192,95,191,20,215,47,134,11,126,-4,161,2,97,207,119,214,129,230,97,207,129,230,91,223,97,207,91,223,80,191,190,74,191,20,192,95,197,208,190,124,192,95, 233,69,229,55,223,45,216,40,209,37,203,36,194,38,188,41,184,47,180,54,178,61,177,69,176,78,175,88,175,109,176,127,176,144,178,160,179,173,180,183,239,183,239,225,97,225,68,222,46,214,29,200,16,180,4,155,12,155,23,167,35,176,47,180,62,183,78,183,72,119,64,77,54,54,42,42,30,36,26,35,20,31,18,25,20,15,23,6,30,0,39,-5,52,-6,77,9,91,48,98,99,100,148,100,183,147,183,145,160,143,136,139,82,139,56,141,37,147,20,156,7,169,-1,185,-4,205,0,220,12,232,29,239,49,241,69, 72,119,64,77,77,9,77,9,64,77,54,54,77,9,54,54,52,-6,52,-6,54,54,42,42,52,-6,42,42,39,-5,39,-5,42,42,30,36,39,-5,30,36,30,0,30,0,30,36,26,35,30,0,26,35,23,6,23,6,26,35,23,33,23,6,23,33,20,31,20,15,23,6,20,31,20,15,20,31,19,28,20,15,19,28,18,25,97,225,68,222,78,183,78,183,91,48,97,225,97,225,91,48,98,99,97,225,98,99,100,183,100,183,98,99,100,148,180,183,239,183,239,225,180,183,239,225,147,183,147,183,239,225,100,183,176,78,175,88,169,-1,169,-1,175,88,175,99,169,-1,175,99,175,109,175,109,176,127,169,-1,169,-1,176,127,176,144,169,-1,176,144,156,7,156,7,176,144,178,160,156,7,178,160,179,173,147,20,180,183,147,183,147,20,147,183,145,160,179,173,180,183,147,20,179,173,147,20,156,7,97,225,100,183,239,225,4,155,12,155,16,180,16,180,12,155,23,167,16,180,23,167,29,200,29,200,23,167,35,176,29,200,35,176,46,214,46,214,35,176,47,180,46,214,47,180,68,222,68,222,47,180,62,183,68,222,62,183,78,183,188,41,184,47,185,-4,185,-4,184,47,180,54,185,-4,180,54,178,61,178,61,177,69,185,-4,185,-4,177,69,169,-1,188,41,205,0,194,38,194,38,205,0,203,36,209,37,203,36,205,0,209,37,205,0,220,12,233,69,229,55,232,29,233,69,232,29,239,49,233,69,239,49,241,69,223,45,216,40,220,12,223,45,220,12,232,29,223,45,232,29,229,55,143,136,141,109,141,37,143,136,141,37,147,20,143,136,147,20,145,160,139,82,139,56,141,37,139,82,141,37,141,109,78,183,72,119,77,9,78,183,77,9,91,48,176,78,169,-1,177,69,188,41,185,-4,205,0,209,37,220,12,216,40, 36,-65,35,-75,34,-84,32,-93,30,-101,27,-107,70,-107,72,-102,74,-95,76,-85,77,-75,78,-64,78,15,88,7,98,1,108,-2,118,-4,130,-4,164,1,192,19,214,47,228,82,233,123,228,158,214,188,191,210,163,225,129,230,101,225,75,210,54,182,41,138,36,76,16383,16383,78,137,79,163,85,185,94,202,107,212,123,216,145,211,163,197,177,175,186,144,190,106,187,75,179,49,166,29,150,16,129,11,115,13,101,18,89,26,81,35,78,44, 107,212,123,216,123,216,129,230,123,216,145,211,129,230,145,211,163,225,163,225,145,211,163,197,163,225,163,197,191,210,191,210,163,197,177,175,191,210,177,175,186,144,191,210,190,106,192,19,191,210,192,19,214,188,214,188,192,19,214,47,214,188,214,47,228,158,228,158,214,47,228,82,228,158,228,82,233,123,192,19,190,106,187,75,192,19,187,75,179,49,192,19,179,49,166,29,192,19,166,29,164,1,129,11,130,-4,150,16,150,16,130,-4,164,1,150,16,164,1,166,29,130,-4,129,11,118,-4,118,-4,129,11,115,13,118,-4,115,13,108,-2,108,-2,115,13,101,18,108,-2,101,18,98,1,98,1,101,18,89,26,98,1,89,26,88,7,88,7,89,26,81,35,88,7,81,35,78,44,85,185,94,202,101,225,101,225,94,202,107,212,101,225,107,212,129,230,129,230,107,212,123,216,78,137,79,163,75,210,78,137,75,210,76,-85,78,137,76,-85,77,-75,78,137,77,-75,78,-64,75,210,79,163,85,185,75,210,85,185,101,225,75,210,54,182,70,-107,75,210,70,-107,72,-102,75,210,72,-102,74,-95,75,210,74,-95,76,-85,70,-107,54,182,41,138,70,-107,41,138,36,76,70,-107,36,76,36,-65,70,-107,36,-65,35,-75,70,-107,35,-75,34,-84,70,-107,34,-84,32,-93,70,-107,32,-93,30,-101,70,-107,30,-101,27,-107,78,44,78,15,88,7,191,210,186,144,190,106, 216,176,213,191,205,206,190,218,169,227,142,230,107,223,73,202,45,171,25,130,17,83,21,45,33,20,50,5,71,-2,95,-4,105,-4,117,-2,128,-1,137,0,143,0,158,-1,170,-5,180,-12,186,-22,188,-34,186,-47,180,-58,170,-67,159,-72,147,-74,140,-72,134,-69,128,-64,123,-61,117,-59,110,-60,104,-63,99,-68,97,-73,96,-80,98,-90,103,-98,111,-103,121,-107,132,-108,151,-104,170,-93,187,-76,199,-55,204,-29,201,-3,192,16,177,30,156,38,128,41,119,41,115,40,103,40,78,45,60,54,48,68,42,85,41,105,45,135,58,158,76,174,97,183,118,186,141,182,158,174,170,163,181,155,192,151,201,153,208,157,212,163,215,169,216,176, 60,54,48,68,50,5,50,5,48,68,42,85,50,5,42,85,33,20,33,20,42,85,41,105,45,171,41,105,45,135,45,171,45,135,73,202,73,202,45,135,58,158,73,202,58,158,76,174,73,202,76,174,107,223,107,223,76,174,97,183,107,223,97,183,118,186,118,186,141,182,142,230,142,230,141,182,158,174,142,230,158,174,169,227,169,227,158,174,170,163,169,227,170,163,190,218,190,218,170,163,181,155,190,218,181,155,192,151,17,83,21,45,25,130,25,130,21,45,33,20,25,130,33,20,45,171,45,171,33,20,41,105,177,30,156,38,158,-1,158,-1,156,38,143,0,137,0,143,0,156,38,137,0,156,38,128,41,128,-1,137,0,128,41,128,-1,128,41,123,41,128,-1,123,41,119,41,128,-1,119,41,117,-2,105,-4,117,-2,107,40,111,40,107,40,117,-2,111,40,117,-2,115,40,115,40,117,-2,119,41,60,54,71,-2,78,45,78,45,71,-2,95,-4,78,45,95,-4,103,40,103,40,95,-4,105,-4,103,40,105,-4,107,40,128,-64,132,-108,134,-69,134,-69,132,-108,151,-104,134,-69,151,-104,140,-72,140,-72,151,-104,147,-74,159,-72,147,-74,151,-104,159,-72,151,-104,170,-93,204,-29,201,-3,199,-55,199,-55,201,-3,192,16,199,-55,192,16,188,-34,188,-34,187,-76,199,-55,158,-1,170,-5,177,30,177,30,170,-5,180,-12,177,30,180,-12,192,16,192,16,180,-12,186,-22,192,16,186,-22,188,-34,187,-76,188,-34,186,-47,187,-76,186,-47,180,-58,187,-76,180,-58,170,-67,187,-76,170,-67,170,-93,110,-60,111,-103,117,-59,117,-59,111,-103,121,-107,117,-59,121,-107,123,-61,123,-61,121,-107,132,-108,123,-61,132,-108,128,-64,97,-73,98,-90,99,-68,99,-68,98,-90,103,-98,99,-68,103,-98,104,-63,104,-63,103,-98,111,-103,104,-63,111,-103,110,-60,213,191,205,206,208,157,213,191,208,157,212,163,213,191,212,163,215,169,213,191,215,169,216,176,205,206,190,218,192,151,205,206,192,151,201,153,205,206,201,153,208,157,142,230,107,223,118,186,98,-90,97,-73,96,-80,159,-72,170,-93,170,-67,60,54,50,5,71,-2, 259,183,259,225,119,225,87,220,58,207,35,184,20,151,15,108,20,73,35,42,58,18,87,1,119,-4,156,1,187,16,212,38,228,65,233,94,229,121,218,138,203,152,186,165,171,183,16383,16383,189,85,186,63,180,42,168,25,152,13,131,9,110,15,90,30,75,54,64,84,60,117,65,145,78,164,97,176,118,182,137,183,153,172,167,155,178,134,186,110,189,85, 186,63,180,42,187,16,187,16,180,42,168,25,187,16,168,25,156,1,156,1,168,25,152,13,156,1,152,13,131,9,131,9,110,15,119,-4,119,-4,110,15,90,30,119,-4,90,30,87,1,87,1,90,30,75,54,87,1,75,54,64,84,58,207,60,117,65,145,58,207,65,145,87,220,87,220,65,145,78,164,87,220,78,164,97,176,58,18,87,1,64,84,58,18,64,84,60,117,58,18,60,117,58,207,58,18,58,207,35,184,58,18,35,184,35,42,20,151,15,108,20,73,20,151,20,73,35,42,20,151,35,42,35,184,153,172,167,155,171,183,171,183,167,155,178,134,171,183,259,225,137,183,119,225,87,220,97,176,119,225,97,176,118,182,119,225,118,182,137,183,119,225,137,183,259,225,137,183,153,172,171,183,233,94,229,121,228,65,228,65,229,121,218,138,228,65,218,138,212,38,212,38,218,138,203,152,212,38,203,152,189,85,189,85,203,152,186,165,189,85,186,165,186,110,186,165,171,183,178,134,186,165,178,134,186,110,189,85,187,16,212,38,131,9,119,-4,156,1,186,63,187,16,189,85,259,225,171,183,259,183, 221,183,221,225,81,225,55,219,34,204,18,183,7,160,2,138,9,138,16,153,25,166,37,175,50,181,66,183,107,183,102,164,96,142,92,119,88,95,87,71,89,49,94,28,103,11,118,0,138,-4,157,0,172,10,183,27,191,48,193,71,185,71,182,59,176,49,169,42,161,38,151,36,141,39,133,47,128,59,125,74,124,91,125,113,128,135,131,155,134,172,136,183, 9,138,16,153,18,183,18,183,16,153,25,166,18,183,25,166,34,204,34,204,25,166,37,175,34,204,37,175,55,219,55,219,37,175,50,181,55,219,50,181,66,183,81,225,66,183,107,183,81,225,107,183,221,225,221,225,107,183,136,183,221,225,136,183,221,183,7,160,2,138,9,138,7,160,9,138,18,183,118,0,125,74,124,91,124,91,125,113,118,0,118,0,125,113,107,183,118,0,107,183,103,11,103,11,107,183,102,164,103,11,102,164,96,142,128,135,131,155,107,183,107,183,131,155,134,172,107,183,134,172,136,183,138,-4,157,0,141,39,141,39,157,0,151,36,161,38,151,36,157,0,161,38,157,0,172,10,185,71,182,59,183,27,185,71,183,27,191,48,185,71,191,48,193,71,176,49,169,42,172,10,176,49,172,10,183,27,176,49,183,27,182,59,138,-4,141,39,133,47,138,-4,133,47,128,59,138,-4,128,59,125,74,138,-4,125,74,118,0,103,11,96,142,94,28,94,28,96,142,92,119,94,28,92,119,89,49,89,49,92,119,88,95,89,49,88,95,87,71,161,38,172,10,169,42,66,183,81,225,55,219,128,135,107,183,125,113, 127,230,127,220,139,218,149,214,159,209,168,201,177,191,186,176,193,159,198,141,201,122,202,104,200,75,193,49,182,28,165,14,142,9,121,14,106,28,97,47,92,68,91,87,91,193,90,205,86,215,80,222,71,226,60,228,47,225,36,216,26,203,16,188,8,172,15,170,18,176,28,188,33,193,39,194,43,192,46,187,48,180,49,170,49,99,51,66,60,38,76,15,102,0,139,-4,174,1,204,18,227,43,242,75,247,113,241,155,226,188,202,211,173,225,141,230, 18,176,23,182,26,203,26,203,23,182,28,188,26,203,28,188,36,216,36,216,28,188,33,193,36,216,33,193,39,194,39,194,43,192,47,225,47,225,43,192,46,187,47,225,46,187,48,180,16,188,8,172,15,170,16,188,15,170,18,176,16,188,18,176,26,203,49,99,51,66,49,159,49,170,49,159,60,228,49,170,60,228,48,180,48,180,60,228,47,225,91,87,91,193,90,205,91,87,90,205,86,215,91,87,86,215,80,222,91,87,80,222,92,68,141,230,127,230,139,218,141,230,139,218,149,214,141,230,149,214,173,225,200,75,193,49,204,18,204,18,193,49,182,28,204,18,182,28,174,1,174,1,182,28,165,14,174,1,165,14,142,9,142,9,121,14,139,-4,139,-4,121,14,106,28,139,-4,106,28,102,0,102,0,106,28,97,47,102,0,97,47,92,68,76,15,102,0,92,68,76,15,92,68,80,222,76,15,80,222,71,226,76,15,71,226,60,228,76,15,60,228,60,38,60,228,49,159,51,66,60,228,51,66,60,38,47,225,36,216,39,194,149,214,159,209,173,225,173,225,159,209,168,201,173,225,168,201,177,191,177,191,186,176,202,211,202,211,186,176,193,159,202,211,193,159,198,141,202,211,202,104,204,18,202,211,204,18,226,188,226,188,204,18,227,43,226,188,227,43,241,155,241,155,227,43,242,75,241,155,242,75,247,113,202,211,198,141,201,122,202,211,201,122,202,104,202,211,173,225,177,191,142,9,139,-4,174,1,200,75,204,18,202,104,139,218,127,230,127,220, 134,9,124,10,114,13,104,18,94,25,86,34,76,52,68,72,63,94,61,116,60,137,63,166,73,189,88,206,109,216,134,221,134,228,132,229,129,229,126,230,121,230,84,224,54,207,33,181,19,150,15,114,19,78,33,46,55,20,85,3,123,-3,134,-4,134,-107,176,-107,176,-4,220,1,254,18,277,43,292,75,296,111,291,151,278,184,258,209,233,224,207,230,195,229,184,226,175,221,167,215,160,208,148,187,141,162,137,134,135,105,134,76,16383,16383,176,9,176,129,177,155,178,179,182,198,189,211,201,216,218,209,232,190,243,164,249,134,252,103,250,74,243,49,231,28,214,14,191,9, 61,116,60,137,60,137,55,20,60,137,54,207,55,20,54,207,33,46,33,46,54,207,33,181,33,46,33,181,19,78,19,78,33,181,19,150,19,78,19,150,15,114,63,94,55,20,68,72,68,72,55,20,85,3,68,72,85,3,76,52,76,52,85,3,86,34,94,25,86,34,85,3,94,25,85,3,123,-3,61,116,60,137,55,20,61,116,55,20,63,94,135,105,134,76,176,-107,176,-107,134,76,134,9,176,-107,134,9,134,-4,134,-4,134,9,124,10,134,-4,124,10,123,-3,123,-3,124,10,114,13,123,-3,114,13,104,18,134,221,134,228,132,229,134,221,132,229,129,229,134,221,129,229,126,230,134,221,126,230,124,230,134,221,124,230,121,230,134,221,121,230,109,216,175,221,176,-107,176,129,176,9,176,-4,220,1,176,9,220,1,191,9,191,9,220,1,214,14,207,230,201,216,218,209,207,230,218,209,233,224,233,224,218,209,232,190,233,224,232,190,243,164,178,179,182,198,184,226,184,226,182,198,189,211,184,226,189,211,195,229,195,229,189,211,201,216,195,229,201,216,207,230,175,221,176,129,177,155,175,221,177,155,178,179,175,221,178,179,184,226,176,-107,175,221,167,215,176,-107,167,215,160,208,176,-107,160,208,148,187,176,-107,148,187,141,162,176,-107,141,162,137,134,176,-107,137,134,135,105,296,111,291,151,292,75,292,75,291,151,278,184,292,75,278,184,277,43,277,43,278,184,258,209,277,43,258,209,254,18,254,18,258,209,252,103,254,18,252,103,250,74,254,18,250,74,243,49,258,209,233,224,243,164,258,209,243,164,249,134,258,209,249,134,252,103,231,28,214,14,220,1,231,28,220,1,254,18,231,28,254,18,243,49,63,166,73,189,84,224,84,224,73,189,88,206,84,224,88,206,121,230,121,230,88,206,109,216,63,166,84,224,54,207,63,166,54,207,60,137,176,-107,134,-4,134,-107,94,25,123,-3,104,18, 243,225,194,225,123,93,113,139,103,177,92,206,79,224,63,230,49,227,38,217,31,202,27,182,26,156,34,156,37,171,41,182,46,190,51,194,56,195,67,192,77,183,85,168,93,147,101,119,110,78,6,-104,55,-104,126,26,136,-34,141,-57,148,-78,157,-94,168,-105,182,-109,198,-104,209,-90,216,-71,219,-52,220,-34,213,-34,210,-49,206,-61,201,-68,195,-72,187,-74,188,-74,177,-71,168,-63,160,-48,153,-27,147,1,138,41, 79,224,63,230,67,192,67,192,63,230,56,195,51,194,56,195,63,230,51,194,63,230,49,227,194,225,123,93,126,26,126,26,123,93,113,139,126,26,113,139,110,78,110,78,113,139,103,177,110,78,103,177,101,119,67,192,77,183,79,224,79,224,77,183,85,168,79,224,85,168,92,206,92,206,85,168,93,147,92,206,93,147,103,177,103,177,93,147,101,119,138,41,243,225,194,225,138,41,194,225,126,26,138,41,126,26,136,-34,138,41,136,-34,141,-57,138,41,141,-57,147,1,110,78,6,-104,55,-104,110,78,55,-104,126,26,210,-49,206,-61,209,-90,209,-90,206,-61,201,-68,209,-90,201,-68,198,-104,198,-104,201,-68,195,-72,198,-104,195,-72,188,-74,187,-74,188,-74,177,-71,187,-74,177,-71,182,-109,182,-109,177,-71,168,-105,177,-71,168,-63,168,-105,168,-105,168,-63,160,-48,168,-105,160,-48,157,-94,157,-94,160,-48,153,-27,157,-94,153,-27,148,-78,148,-78,153,-27,147,1,148,-78,147,1,141,-57,216,-71,219,-52,220,-34,216,-71,220,-34,213,-34,216,-71,213,-34,210,-49,216,-71,210,-49,209,-90,187,-74,182,-109,198,-104,187,-74,198,-104,188,-74,34,156,37,171,38,217,38,217,37,171,41,182,38,217,41,182,49,227,49,227,41,182,46,190,49,227,46,190,51,194,34,156,38,217,31,202,34,156,31,202,27,182,34,156,27,182,26,156, 342,228,332,230,316,230,290,224,273,209,262,187,256,162,254,136,253,103,249,69,239,39,223,17,197,9,197,225,155,225,155,9,129,17,112,39,103,69,99,104,98,137,96,163,90,188,78,210,61,224,36,230,31,230,25,229,14,229,10,228,10,220,30,210,42,190,49,164,52,137,52,114,55,72,65,39,84,15,114,0,155,-4,155,-107,197,-107,197,-4,236,0,265,16,285,41,296,74,300,114,300,137,303,164,310,190,322,211,342,221, 239,39,223,17,236,0,236,0,223,17,197,9,197,-107,197,9,155,-4,197,225,155,225,155,-4,197,225,155,-4,197,9,155,225,155,9,155,-4,155,-4,155,9,129,17,155,-4,129,17,114,0,114,0,129,17,112,39,114,0,112,39,103,69,99,104,98,137,96,163,99,104,96,163,90,188,99,104,90,188,84,15,99,104,84,15,103,69,52,114,55,72,61,224,61,224,55,72,65,39,61,224,65,39,78,210,78,210,65,39,84,15,78,210,84,15,90,188,42,190,49,164,61,224,61,224,49,164,52,137,61,224,52,137,52,114,61,224,36,230,42,190,42,190,36,230,31,230,42,190,31,230,30,210,30,210,31,230,25,229,30,210,25,229,19,229,14,229,10,228,30,210,14,229,30,210,19,229,262,187,256,162,265,16,265,16,256,162,254,136,265,16,254,136,253,103,342,221,342,228,337,229,342,221,337,229,332,230,342,221,332,230,327,230,342,221,327,230,322,211,303,164,310,190,316,230,316,230,310,190,322,211,316,230,322,211,321,230,321,230,322,211,327,230,262,187,265,16,273,209,273,209,265,16,285,41,273,209,285,41,290,224,290,224,285,41,296,74,290,224,296,74,300,137,300,137,296,74,300,114,290,224,300,137,303,164,290,224,303,164,316,230,265,16,253,103,249,69,265,16,249,69,239,39,265,16,239,39,236,0,197,9,197,-4,236,0,197,-107,155,-4,155,-107,30,210,10,228,10,220,103,69,84,15,114,0, 180,223,206,218,226,203,240,179,249,146,252,104,252,76,248,51,242,29,229,14,210,9,200,12,190,20,181,33,174,51,170,73,173,85,177,105,178,115,179,127,177,145,174,158,169,168,163,173,156,175,149,173,143,168,138,159,135,145,133,126,134,114,135,103,137,94,139,84,142,73,138,51,132,33,123,20,113,12,100,9,82,15,71,31,64,54,61,81,60,109,63,149,73,180,88,204,108,218,132,223,132,230,94,225,62,211,37,186,20,151,15,104,15,84,18,66,23,50,30,35,39,23,49,13,59,5,70,0,81,-3,93,-4,109,-2,123,3,136,12,147,26,156,43,164,26,175,12,187,3,202,-2,218,-4,230,-3,242,0,253,5,263,13,273,23,282,35,289,49,294,66,296,85,297,105,292,152,275,187,250,211,218,225,180,230, 71,31,64,54,70,0,70,0,64,54,61,81,70,0,61,81,59,5,59,5,61,81,60,109,62,211,60,109,63,149,62,211,63,149,73,180,108,218,132,223,132,230,108,218,132,230,94,225,108,218,94,225,88,204,94,225,62,211,73,180,94,225,73,180,88,204,23,50,30,35,37,186,37,186,30,35,39,23,37,186,39,23,62,211,62,211,39,23,49,13,62,211,49,13,60,109,60,109,49,13,59,5,20,151,15,104,15,84,20,151,15,84,18,66,20,151,18,66,23,50,20,151,23,50,37,186,81,-3,93,-4,82,15,82,15,93,-4,100,9,113,12,100,9,109,-2,113,12,109,-2,123,3,71,31,70,0,81,-3,71,31,81,-3,82,15,174,51,170,73,175,12,174,158,170,73,173,85,174,158,173,85,175,95,177,145,174,158,175,95,177,145,175,95,177,105,177,145,177,105,178,115,177,145,178,115,179,127,156,175,156,43,163,173,163,173,156,43,164,26,163,173,164,26,169,168,169,168,164,26,170,73,169,168,170,73,174,158,174,51,175,12,181,33,181,33,175,12,187,3,181,33,187,3,190,20,190,20,187,3,202,-2,190,20,202,-2,200,12,200,12,202,-2,210,9,229,14,210,9,218,-4,229,14,218,-4,230,-3,282,35,289,49,292,152,292,152,289,49,294,66,292,152,294,66,297,105,297,105,294,66,296,85,275,187,250,211,252,104,275,187,252,104,253,5,275,187,253,5,263,13,275,187,263,13,273,23,275,187,273,23,282,35,275,187,282,35,292,152,240,179,249,146,250,211,250,211,249,146,252,104,253,5,252,104,252,76,240,179,250,211,226,203,226,203,250,211,218,225,226,203,218,225,206,218,206,218,218,225,180,230,206,218,180,230,180,223,229,14,230,-3,242,29,242,29,230,-3,242,0,242,29,242,0,248,51,248,51,242,0,253,5,248,51,253,5,252,76,210,9,202,-2,218,-4,139,84,142,73,143,168,143,168,142,73,147,26,143,168,147,26,149,173,149,173,147,26,156,43,149,173,156,43,156,175,147,26,142,73,138,51,147,26,138,51,136,12,136,12,138,51,132,33,136,12,132,33,123,3,123,3,132,33,123,20,123,3,123,20,113,12,138,159,135,145,135,103,138,159,135,103,137,94,138,159,137,94,139,84,138,159,139,84,143,168,135,145,133,126,134,114,135,145,134,114,135,103,100,9,93,-4,109,-2,170,73,164,26,175,12, 272,145,263,146,255,146,246,147,238,148,230,150,229,176,225,203,220,230,212,257,201,281,191,300,179,316,163,329,144,338,121,342,100,339,80,331,63,316,50,294,46,264,53,226,74,194,104,168,142,149,185,137,186,133,186,116,185,85,180,56,171,32,157,15,137,9,115,14,101,28,91,46,87,66,85,84,85,110,84,131,81,145,76,154,67,159,55,160,43,158,31,151,20,140,9,125,0,105,7,100,15,114,20,123,25,128,29,131,33,132,37,131,39,128,42,123,43,115,44,104,44,93,46,61,55,34,72,13,97,0,133,-4,172,3,200,26,217,58,227,95,230,134,247,134,256,135,272,137,16383,16383,185,161,141,182,112,208,95,235,86,260,84,280,86,295,91,307,99,316,109,321,119,323,135,320,149,310,162,289,173,253,181,200,181,198,182,193,183,184,184,174,185,161, 20,123,25,128,31,151,31,151,25,128,29,131,31,151,29,131,33,132,33,132,37,131,43,158,43,158,37,131,39,128,43,158,39,128,42,123,0,105,7,100,9,125,9,125,7,100,15,114,9,125,15,114,20,140,20,140,15,114,20,123,20,140,20,123,31,151,44,104,46,61,55,160,55,160,46,61,55,34,55,160,55,34,67,159,67,159,55,34,72,13,67,159,72,13,76,154,76,154,72,13,87,66,76,154,87,66,85,84,85,84,85,110,84,131,85,84,84,131,81,145,85,84,81,145,76,154,121,342,119,323,135,320,121,342,135,320,144,338,144,338,135,320,149,310,144,338,149,310,163,329,163,329,149,310,162,289,163,329,162,289,173,253,180,56,171,32,172,3,172,3,171,32,157,15,172,3,157,15,137,9,137,9,115,14,133,-4,133,-4,115,14,101,28,133,-4,101,28,97,0,97,0,101,28,91,46,97,0,91,46,87,66,43,115,44,104,55,160,43,115,55,160,43,158,43,115,43,158,42,123,43,158,31,151,33,132,272,137,272,145,264,136,264,136,272,145,263,146,264,136,263,146,256,135,256,135,263,146,255,146,256,135,255,146,247,134,247,134,255,146,246,147,247,134,246,147,238,134,238,134,246,147,238,148,238,134,238,148,230,150,230,150,229,176,230,134,230,134,229,176,227,95,229,176,225,203,227,95,227,95,225,203,220,230,227,95,220,230,217,58,217,58,220,230,212,257,217,58,212,257,201,281,217,58,201,281,200,26,200,26,201,281,191,300,200,26,191,300,186,116,186,116,185,85,200,26,200,26,185,85,180,56,200,26,180,56,172,3,137,9,133,-4,172,3,238,134,230,150,230,134,91,307,99,316,100,339,100,339,99,316,109,321,100,339,109,321,121,342,121,342,109,321,119,323,80,331,84,280,86,295,80,331,86,295,100,339,100,339,86,295,91,307,191,300,179,316,181,200,191,300,181,200,181,198,191,300,181,198,182,193,191,300,182,193,183,184,191,300,183,184,184,174,191,300,184,174,185,161,191,300,185,161,185,137,191,300,185,137,186,133,191,300,186,133,186,129,191,300,186,129,186,124,191,300,186,124,186,120,191,300,186,120,186,116,185,161,141,182,142,149,185,161,142,149,185,137,112,208,95,235,104,168,112,208,104,168,142,149,112,208,142,149,141,182,86,260,84,280,74,194,86,260,74,194,104,168,86,260,104,168,95,235,84,280,80,331,74,194,74,194,80,331,63,316,74,194,63,316,53,226,53,226,63,316,50,294,53,226,50,294,46,264,173,253,181,200,179,316,173,253,179,316,163,329,46,61,44,104,44,93,87,66,72,13,97,0, 176,342,134,342,134,230,126,230,86,224,55,206,32,180,19,149,15,114,19,79,33,47,55,20,85,2,123,-4,134,-4,134,-107,176,-107,176,-4,223,2,257,21,280,48,292,81,296,116,294,143,286,168,272,190,254,208,230,222,221,225,211,228,189,230,176,230,16383,16383,176,9,176,216,203,210,225,193,240,168,249,137,252,102,249,73,243,48,231,27,214,14,191,9,16383,16383,135,9,125,10,114,13,104,18,95,25,86,34,77,51,69,70,64,91,61,113,60,137,62,164,70,186,82,202,99,212,120,216,135,216, 296,116,294,143,292,81,292,81,294,143,286,168,292,81,286,168,280,48,280,48,286,168,272,190,280,48,272,190,257,21,257,21,272,190,254,208,257,21,254,208,252,102,221,225,225,193,230,222,230,222,225,193,240,168,230,222,240,168,254,208,254,208,240,168,249,137,254,208,249,137,252,102,211,228,200,229,203,210,211,228,203,210,225,193,211,228,225,193,221,225,200,229,189,230,203,210,203,210,189,230,176,230,203,210,176,230,176,216,176,216,176,230,176,342,176,216,176,342,135,216,135,216,176,342,134,342,135,216,134,342,134,230,257,21,252,102,249,73,257,21,249,73,243,48,257,21,243,48,231,27,257,21,231,27,223,2,231,27,214,14,223,2,223,2,214,14,191,9,223,2,191,9,176,-4,176,-4,191,9,176,9,176,-4,176,9,176,-107,176,-107,176,9,135,216,176,-107,135,216,135,9,134,-4,134,-107,176,-107,134,-4,176,-107,135,9,134,-4,135,9,125,10,134,-4,125,10,123,-4,69,70,85,2,77,51,77,51,85,2,86,34,95,25,86,34,85,2,95,25,85,2,123,-4,82,202,86,224,70,186,70,186,86,224,55,206,70,186,55,206,62,164,62,164,55,206,60,137,61,113,60,137,55,20,61,113,55,20,64,91,64,91,55,20,85,2,64,91,85,2,69,70,123,-4,125,10,114,13,123,-4,114,13,104,18,123,-4,104,18,95,25,126,230,86,224,99,212,126,230,99,212,120,216,126,230,120,216,135,216,126,230,135,216,134,230,55,20,60,137,55,206,55,20,55,206,33,47,33,47,55,206,32,180,33,47,32,180,19,79,19,79,32,180,19,149,19,79,19,149,15,114,86,224,82,202,99,212,176,216,135,216,176,9, 363,183,363,225,77,225,53,219,33,204,18,183,8,160,3,137,11,137,18,152,27,164,36,174,48,181,61,183,84,183,76,169,69,153,64,137,61,120,60,103,64,64,76,34,92,12,112,0,134,-4,153,-2,169,3,182,12,193,26,201,43,210,25,221,12,233,2,247,-2,261,-4,286,0,309,12,327,33,339,63,343,102,342,119,340,136,336,153,329,169,320,183,16383,16383,279,183,285,171,291,155,295,138,297,120,298,103,297,76,293,51,286,29,275,15,258,9,246,12,236,20,226,33,219,51,215,74,218,82,220,90,222,99,224,115,223,126,221,138,217,149,211,156,202,159,193,156,186,149,182,139,180,127,179,116,180,107,181,99,185,81,188,74,183,51,176,33,167,19,156,12,143,9,126,15,115,30,108,52,106,76,105,99,106,118,108,137,112,153,118,169,125,183, 11,137,18,152,18,183,18,183,18,152,27,164,18,183,27,164,33,204,33,204,27,164,36,174,33,204,36,174,53,219,53,219,36,174,48,181,53,219,48,181,61,183,77,225,61,183,84,183,77,225,84,183,363,225,363,225,84,183,125,183,363,225,125,183,279,183,8,160,3,137,11,137,8,160,11,137,18,183,108,137,112,153,84,183,84,183,112,153,118,169,84,183,118,169,125,183,108,52,112,0,115,30,115,30,112,0,134,-4,115,30,134,-4,126,15,126,15,134,-4,143,9,156,12,143,9,153,-2,156,12,153,-2,169,3,105,99,92,12,106,76,106,76,92,12,112,0,106,76,112,0,108,52,219,51,215,74,221,12,217,149,215,74,218,82,217,149,218,82,221,138,221,138,218,82,220,90,221,138,220,90,222,99,223,126,221,138,222,99,223,126,222,99,223,107,223,126,223,107,224,115,188,74,193,26,193,156,193,156,193,26,201,43,193,156,201,43,202,159,202,159,201,43,210,25,202,159,210,25,211,156,211,156,210,25,215,74,211,156,215,74,217,149,219,51,221,12,226,33,226,33,221,12,233,2,226,33,233,2,236,20,236,20,233,2,247,-2,236,20,247,-2,246,12,246,12,247,-2,258,9,275,15,258,9,261,-4,275,15,261,-4,286,0,363,225,279,183,285,171,363,225,285,171,291,155,363,225,291,155,320,183,363,225,320,183,363,183,340,136,336,153,339,63,339,63,336,153,329,169,339,63,329,169,327,33,327,33,329,169,320,183,327,33,320,183,309,12,309,12,320,183,298,103,291,155,295,138,320,183,320,183,295,138,297,120,320,183,297,120,298,103,106,118,108,137,84,183,106,118,84,183,92,12,106,118,92,12,105,99,340,136,339,63,343,102,340,136,343,102,342,119,309,12,298,103,297,76,309,12,297,76,293,51,309,12,293,51,286,29,309,12,286,29,286,0,258,9,247,-2,261,-4,186,149,182,139,183,90,186,149,183,90,185,81,186,149,185,81,188,74,186,149,188,74,193,156,179,116,180,107,180,127,180,127,180,107,181,99,180,127,181,99,182,139,182,139,181,99,183,90,193,26,188,74,183,51,193,26,183,51,182,12,182,12,183,51,176,33,182,12,176,33,169,3,169,3,176,33,167,19,169,3,167,19,156,12,143,9,134,-4,153,-2,76,169,69,153,76,34,76,169,76,34,92,12,76,169,92,12,84,183,64,137,61,120,64,64,64,137,64,64,76,34,64,137,76,34,69,153,64,64,61,120,60,103,275,15,286,0,286,29,61,183,77,225,53,219,215,74,210,25,221,12, 257,225,206,225,111,104,110,104,112,114,114,125,115,138,117,150,117,160,115,183,108,202,97,217,82,226,64,230,53,229,43,225,35,219,29,210,27,198,28,193,31,188,35,184,40,181,46,180,54,181,60,184,63,188,67,191,71,192,81,190,89,184,95,174,99,162,100,148,99,136,98,121,96,107,94,94,91,85,21,0,73,0,170,121,171,121,168,111,166,100,164,88,163,76,162,65,164,46,170,27,180,11,194,0,214,-4,225,-3,236,0,244,5,250,14,252,26,251,32,248,37,244,41,239,43,233,44,225,43,219,40,213,34,209,33,199,35,191,40,185,50,181,64,180,85,180,98,181,111,183,122,186,132,189,141, 95,174,97,217,89,184,89,184,97,217,82,226,89,184,82,226,81,190,81,190,82,226,71,192,67,191,71,192,82,226,67,191,82,226,64,230,206,225,111,104,170,121,170,121,111,104,94,94,170,121,94,94,91,85,91,85,21,0,73,0,112,114,114,125,115,183,115,183,114,125,115,138,115,183,115,138,117,160,117,160,115,138,117,150,110,104,112,114,115,183,110,104,115,183,108,202,110,104,108,202,100,148,110,104,100,148,99,136,110,104,99,136,98,121,110,104,98,121,96,107,110,104,96,107,94,94,110,104,94,94,111,104,191,40,185,50,194,0,194,0,185,50,181,64,194,0,181,64,180,11,180,11,181,64,180,85,171,121,180,85,180,98,171,121,180,98,181,111,186,132,189,141,206,225,186,132,206,225,183,122,183,122,206,225,171,121,183,122,171,121,181,111,206,225,189,141,257,225,99,162,100,148,108,202,99,162,108,202,97,217,91,85,73,0,170,121,225,43,219,40,225,-3,225,-3,219,40,216,37,225,-3,216,37,214,-4,214,-4,216,37,213,34,214,-4,213,34,209,33,209,33,199,35,214,-4,214,-4,199,35,194,0,252,26,251,32,250,14,250,14,251,32,248,37,250,14,248,37,244,5,244,5,248,37,244,41,244,5,244,41,239,43,225,43,225,-3,233,44,233,44,225,-3,236,0,233,44,236,0,239,43,239,43,236,0,244,5,171,121,168,111,170,27,171,121,170,27,180,11,171,121,180,11,180,85,166,100,164,88,164,46,166,100,164,46,170,27,166,100,170,27,168,111,163,76,162,65,164,46,163,76,164,46,164,88,64,230,53,229,54,181,64,230,54,181,60,184,64,230,60,184,63,188,64,230,63,188,67,191,35,184,40,181,43,225,43,225,40,181,46,180,43,225,46,180,53,229,53,229,46,180,54,181,27,198,28,193,29,210,29,210,28,193,31,188,29,210,31,188,35,219,35,219,31,188,35,184,35,219,35,184,43,225,97,217,95,174,99,162,191,40,194,0,199,35,206,225,170,121,171,121, 213,-107,214,-103,216,-93,217,-89,217,-86,202,-54,166,-40,119,-30,75,-8,44,40,45,40,55,24,69,11,86,2,106,-2,131,-4,166,1,195,18,217,44,230,75,235,110,230,150,217,183,195,208,166,224,129,230,83,221,50,197,29,163,18,126,15,89,15,69,16,49,18,29,22,10,28,-6,65,-50,110,-71,154,-79,189,-88,205,-107,16383,16383,190,108,188,82,183,55,173,32,157,15,133,9,105,17,85,37,70,66,62,101,60,137,63,166,71,188,83,203,100,213,120,216,141,210,160,195,175,171,186,142,190,108, 28,-6,65,-50,44,40,44,40,65,-50,75,-8,75,-8,65,-50,110,-71,75,-8,110,-71,119,-30,119,-30,110,-71,154,-79,119,-30,154,-79,166,-40,166,-40,154,-79,189,-88,166,-40,189,-88,202,-54,202,-54,189,-88,205,-107,202,-54,205,-107,217,-86,217,-86,205,-107,213,-107,217,-86,213,-107,214,-103,55,24,69,11,60,137,60,137,63,166,50,197,50,197,63,166,71,188,50,197,71,188,83,221,83,221,71,188,83,203,83,221,83,203,129,230,129,230,83,203,100,213,129,230,100,213,120,216,120,216,141,210,129,230,129,230,141,210,166,224,133,9,106,-2,131,-4,133,9,131,-4,166,1,133,9,105,17,106,-2,86,2,106,-2,105,17,86,2,105,17,85,37,86,2,85,37,70,66,86,2,70,66,69,11,62,101,60,137,69,11,62,101,69,11,70,66,188,82,183,55,195,18,195,18,183,55,173,32,195,18,173,32,166,1,166,1,173,32,157,15,166,1,157,15,133,9,175,171,186,142,195,208,195,208,186,142,190,108,195,18,190,108,188,82,166,224,141,210,160,195,166,224,160,195,175,171,166,224,175,171,195,208,195,18,217,44,217,183,217,183,217,44,230,75,217,183,230,75,230,150,230,150,230,75,235,110,195,208,190,108,195,18,195,208,195,18,217,183,217,-86,214,-103,215,-98,217,-86,215,-98,216,-93,217,-86,216,-93,217,-89,16,49,18,29,18,126,18,126,18,29,22,10,18,126,22,10,29,163,29,163,22,10,28,-6,29,163,28,-6,44,40,18,126,15,89,15,69,18,126,15,69,16,49,44,40,45,40,50,197,50,197,45,40,55,24,50,197,55,24,60,137,50,197,29,163,44,40, 196,56,183,41,169,29,155,22,139,17,123,16,100,21,82,35,68,56,60,82,57,112,155,112,155,127,57,127,61,151,69,175,82,196,99,210,119,215,142,212,158,203,169,191,177,177,183,162,191,162,184,230,176,230,174,224,173,222,171,220,167,220,160,221,152,223,144,226,133,229,118,230,82,223,53,205,31,178,17,145,12,108,17,74,30,44,50,18,78,1,112,-4,136,-1,157,5,176,17,191,33,204,52, 155,112,155,127,57,112,57,112,57,127,53,205,53,205,57,127,61,151,53,205,61,151,82,223,82,223,61,151,69,175,82,223,69,175,82,196,68,56,78,1,82,35,82,35,78,1,112,-4,82,35,112,-4,100,21,100,21,112,-4,123,16,139,17,123,16,136,-1,139,17,136,-1,157,5,60,82,57,112,50,18,60,82,50,18,78,1,60,82,78,1,68,56,12,108,17,74,17,145,17,145,17,74,30,44,17,145,30,44,31,178,31,178,30,44,50,18,31,178,50,18,53,205,53,205,50,18,57,112,158,203,169,191,160,221,160,221,169,191,167,220,171,220,167,220,169,191,171,220,169,191,177,177,184,230,176,230,177,177,184,230,177,177,183,162,184,230,183,162,191,162,177,177,176,230,175,227,177,177,175,227,174,224,177,177,174,224,173,222,177,177,173,222,171,220,133,229,119,215,142,212,133,229,142,212,144,226,144,226,142,212,158,203,144,226,158,203,152,223,152,223,158,203,160,221,204,52,196,56,191,33,191,33,196,56,183,41,191,33,183,41,176,17,176,17,183,41,169,29,176,17,169,29,157,5,157,5,169,29,155,22,157,5,155,22,139,17,123,16,112,-4,136,-1,118,230,82,223,82,196,118,230,82,196,99,210,118,230,99,210,119,215,118,230,119,215,133,229,57,127,57,112,155,127, 350,0,350,9,337,12,327,17,319,26,311,38,304,55,180,337,171,337,68,93,52,58,41,34,31,20,19,13,4,9,4,0,104,0,104,9,91,10,81,12,74,16,70,22,69,30,69,34,70,38,71,43,72,47,74,51,97,108,228,108,248,61,254,45,256,38,257,31,257,23,256,21,255,18,251,14,247,12,239,10,232,10,223,9,223,0,16383,16383,220,128,105,128,162,266, 52,58,70,22,69,30,69,30,69,34,68,93,68,93,69,34,70,38,68,93,70,38,71,43,243,11,239,10,350,0,350,0,239,10,232,10,350,0,232,10,223,9,72,47,74,51,171,337,171,337,74,51,97,108,171,337,97,108,105,128,105,128,97,108,228,108,105,128,228,108,220,128,220,128,228,108,304,55,220,128,304,55,180,337,256,21,255,18,350,0,350,0,255,18,253,16,350,0,253,16,251,14,251,14,247,12,350,0,350,0,247,12,243,11,257,26,350,0,327,17,257,26,327,17,319,26,257,26,319,26,311,38,257,26,311,38,304,55,257,26,304,55,257,31,304,55,228,108,248,61,304,55,248,61,251,53,304,55,251,53,254,45,304,55,254,45,256,38,304,55,256,38,257,31,171,337,105,128,162,266,171,337,162,266,220,128,171,337,220,128,180,337,68,93,52,58,69,30,72,47,171,337,68,93,72,47,68,93,71,43,337,12,327,17,350,0,337,12,350,0,350,9,257,23,256,21,350,0,257,23,350,0,257,26,104,0,104,9,91,10,104,0,91,10,81,12,104,0,81,12,41,34,104,0,41,34,31,20,104,0,31,20,19,13,104,0,19,13,4,9,104,0,4,9,4,0,41,34,81,12,74,16,41,34,74,16,70,22,41,34,70,22,52,58,350,0,223,9,223,0, 108,183,108,294,109,301,111,306,114,310,119,311,126,312,188,312,202,311,217,307,230,300,242,287,251,267,252,263,253,258,255,254,256,250,256,247,268,247,266,331,9,331,9,321,30,320,44,315,52,308,56,295,57,275,57,56,56,37,52,24,43,16,29,11,9,9,9,0,169,0,209,4,242,16,267,35,283,60,289,91,280,132,256,159,223,174,185,181,146,183,16383,16383,108,163,138,163,166,161,191,154,212,141,226,120,231,89,226,59,212,39,190,27,162,21,131,19,120,20,113,22,110,26,108,33,108,41, 52,24,43,16,169,0,169,0,43,16,29,11,169,0,29,11,9,9,44,315,52,308,266,331,266,331,52,308,119,311,266,331,119,311,126,312,266,331,126,312,188,312,266,331,188,312,202,311,217,307,230,300,266,331,266,331,230,300,242,287,266,331,242,287,251,267,251,267,252,263,266,331,266,331,252,263,253,258,266,331,253,258,255,254,266,331,255,254,256,250,266,331,256,250,256,247,266,331,256,247,268,247,57,275,108,33,108,41,108,183,108,163,138,163,108,183,138,163,146,183,146,183,138,163,166,161,146,183,166,161,185,181,185,181,166,161,191,154,185,181,191,154,223,174,223,174,191,154,212,141,223,174,212,141,226,120,57,275,108,41,108,294,57,275,108,294,109,301,57,275,109,301,111,306,57,275,111,306,114,310,57,275,114,310,56,295,119,311,52,308,56,295,119,311,56,295,114,310,30,320,44,315,266,331,30,320,266,331,9,331,30,320,9,331,9,321,231,89,226,59,242,16,242,16,226,59,212,39,242,16,212,39,209,4,209,4,212,39,190,27,209,4,190,27,169,0,169,0,190,27,162,21,169,0,162,21,131,19,131,19,120,20,169,0,169,0,120,20,113,22,169,0,113,22,56,37,56,37,113,22,57,56,231,89,242,16,256,159,256,159,242,16,267,35,256,159,267,35,280,132,280,132,267,35,283,60,280,132,283,60,289,91,226,120,231,89,256,159,226,120,256,159,223,174,57,56,113,22,110,26,57,56,110,26,108,33,57,56,108,33,57,275,169,0,9,9,9,0,52,24,169,0,56,37,266,331,202,311,217,307, 212,180,226,183,237,187,245,190,253,195,260,200,267,208,273,218,277,229,280,240,281,252,275,281,259,303,233,318,196,328,150,331,9,331,9,321,30,320,44,316,52,308,56,295,57,275,57,56,56,37,52,24,43,16,30,11,9,9,9,0,178,0,218,4,251,17,276,37,292,63,297,94,296,107,293,120,289,131,282,142,273,151,264,159,255,165,244,171,230,175,212,179,16383,16383,108,188,108,296,109,302,110,307,113,310,116,311,121,312,141,312,173,310,198,302,215,290,226,273,229,250,226,228,217,210,203,198,182,191,155,188,16383,16383,108,168,139,168,163,167,182,164,199,158,217,148,225,141,232,131,237,120,239,108,240,94,239,82,237,69,233,58,228,48,221,41,208,31,195,25,180,21,162,19,140,19,127,20,119,22,113,26,109,33,108,41, 52,24,43,16,178,0,178,0,43,16,30,11,178,0,30,11,9,9,56,295,57,275,113,310,56,295,113,310,150,331,150,331,113,310,116,311,150,331,116,311,121,312,150,331,121,312,141,312,150,331,141,312,173,310,208,31,195,25,218,4,218,4,195,25,180,21,218,4,180,21,178,0,178,0,180,21,162,19,178,0,162,19,140,19,140,19,127,20,178,0,178,0,127,20,119,22,178,0,119,22,56,37,56,37,119,22,57,56,259,303,233,318,237,187,237,187,233,318,229,250,237,187,229,250,226,228,237,187,226,228,226,183,226,183,226,228,217,210,226,183,217,210,212,180,212,180,217,210,203,198,212,180,203,198,212,179,212,179,203,198,217,148,212,179,217,148,230,175,230,175,217,148,225,141,155,188,163,167,182,191,182,191,163,167,182,164,182,191,182,164,203,198,203,198,182,164,199,158,203,198,199,158,217,148,237,69,233,58,251,17,251,17,233,58,228,48,251,17,228,48,221,41,221,41,208,31,218,4,163,167,155,188,139,168,139,168,155,188,108,188,139,168,108,188,108,168,109,33,108,41,57,275,109,33,57,275,57,56,57,56,119,22,113,26,57,56,113,26,109,33,273,151,264,159,276,37,276,37,264,159,255,165,276,37,255,165,251,17,251,17,255,165,244,171,251,17,244,171,240,94,240,94,239,82,251,17,251,17,239,82,237,69,244,171,230,175,232,131,244,171,232,131,237,120,244,171,237,120,239,108,244,171,239,108,240,94,233,318,196,328,198,302,233,318,198,302,215,290,233,318,215,290,226,273,233,318,226,273,229,250,196,328,150,331,173,310,196,328,173,310,198,302,57,275,108,41,108,296,57,275,108,296,109,302,57,275,109,302,110,307,57,275,110,307,113,310,150,331,9,331,30,320,150,331,30,320,44,316,150,331,44,316,52,308,150,331,52,308,56,295,267,208,273,218,275,281,275,281,273,218,277,229,275,281,277,229,281,252,281,252,277,229,280,240,245,190,253,195,259,303,259,303,253,195,260,200,259,303,260,200,275,281,275,281,260,200,267,208,293,120,289,131,292,63,293,120,292,63,297,94,293,120,297,94,296,107,282,142,273,151,276,37,282,142,276,37,292,63,282,142,292,63,289,131,221,41,218,4,251,17,259,303,237,187,245,190,30,320,9,331,9,321,230,175,225,141,232,131,178,0,9,9,9,0,52,24,178,0,56,37, 272,242,270,331,9,331,9,321,28,320,41,315,48,307,52,294,53,275,53,57,52,37,48,24,41,16,28,12,9,9,9,0,150,0,150,9,130,12,117,16,109,24,105,37,104,56,104,302,106,307,109,310,114,312,192,312,206,311,221,307,234,300,246,286,255,267,256,262,258,256,259,250,260,245,260,242, 48,24,41,16,150,0,150,0,41,16,28,12,150,0,28,12,9,9,52,294,53,275,109,310,52,294,109,310,48,307,48,307,109,310,114,312,48,307,114,312,270,331,270,331,114,312,122,312,221,307,234,300,270,331,270,331,234,300,246,286,270,331,246,286,255,267,255,267,256,262,270,331,270,331,256,262,258,256,270,331,258,256,259,250,270,331,259,250,260,245,270,331,260,245,260,242,270,331,260,242,272,242,270,331,122,312,192,312,270,331,192,312,206,311,270,331,206,311,221,307,117,16,109,24,53,57,53,57,109,24,105,37,53,57,105,37,53,275,53,275,105,37,104,56,53,275,104,56,104,294,53,275,104,294,104,302,53,275,104,302,106,307,53,275,106,307,109,310,270,331,9,331,28,320,270,331,28,320,41,315,270,331,41,315,48,307,150,0,150,9,130,12,150,0,130,12,117,16,150,0,117,16,52,37,150,0,52,37,48,24,150,0,9,9,9,0,52,37,117,16,53,57,28,320,9,331,9,321, 323,-75,323,9,303,11,291,17,283,27,279,40,278,57,278,274,280,293,283,307,291,315,304,319,323,321,323,331,47,331,47,321,62,320,75,316,83,308,88,295,90,275,87,172,79,97,65,46,45,18,17,9,7,9,7,-75,19,-75,19,-72,20,-67,21,-60,23,-54,24,-49,32,-29,43,-15,56,-5,71,0,259,0,274,-5,287,-15,298,-29,306,-49,307,-54,308,-60,309,-67,310,-72,311,-75,16383,16383,228,41,227,33,225,27,222,22,217,20,209,19,76,19,91,48,101,88,108,141,112,209,113,294,113,303,115,308,119,311,124,312,210,312,217,311,222,310,225,306,227,301,228,294, 20,-67,21,-60,17,9,17,9,21,-60,23,-54,17,9,23,-54,24,-49,24,-49,32,-29,45,18,45,18,32,-29,43,-15,45,18,43,-15,56,-5,62,320,75,316,323,331,323,331,75,316,124,312,323,331,124,312,131,312,323,331,131,312,210,312,323,331,210,312,217,311,87,172,91,48,90,275,90,275,91,48,113,303,113,303,91,48,113,294,71,0,87,0,76,19,71,0,76,19,79,97,79,97,76,19,91,48,79,97,91,48,87,172,65,46,45,18,56,-5,65,46,56,-5,71,0,65,46,71,0,79,97,45,18,17,9,24,-49,17,9,7,9,19,-75,17,9,19,-75,19,-72,17,9,19,-72,20,-67,323,331,217,311,222,310,323,331,222,310,225,306,323,331,225,306,227,301,323,331,227,301,228,294,323,331,228,294,291,315,323,331,291,315,304,319,323,331,304,319,323,321,291,17,283,27,287,-15,287,-15,283,27,279,40,287,-15,279,40,274,-5,274,-5,279,40,278,57,274,-5,278,57,278,274,228,294,243,0,280,293,280,293,243,0,259,0,280,293,259,0,278,274,278,274,259,0,274,-5,283,307,291,315,228,294,283,307,228,294,280,293,113,294,91,48,101,88,113,294,101,88,108,141,113,294,108,141,112,209,124,312,83,308,119,311,119,311,83,308,88,295,119,311,88,295,115,308,115,308,88,295,90,275,115,308,90,275,113,303,47,331,47,321,62,320,47,331,62,320,323,331,308,-60,323,9,307,-54,307,-54,323,9,306,-49,298,-29,306,-49,303,11,298,-29,303,11,291,17,323,9,308,-60,309,-67,323,9,309,-67,310,-72,323,9,310,-72,311,-75,323,9,311,-75,323,-75,323,9,303,11,306,-49,209,19,76,19,87,0,209,19,87,0,243,0,209,19,243,0,217,20,243,0,228,294,228,41,243,0,228,41,227,33,243,0,227,33,225,27,243,0,225,27,222,22,243,0,222,22,217,20,19,-75,7,9,7,-75,291,17,287,-15,298,-29,124,312,75,316,83,308, 304,84,290,84,276,57,260,38,239,27,211,21,174,19,137,19,122,21,113,25,107,32,105,42,105,164,181,164,203,162,218,158,227,150,234,136,238,115,249,115,249,232,238,232,234,211,227,198,218,189,203,185,181,184,105,184,105,294,106,302,108,307,111,310,116,312,189,312,218,311,239,306,252,297,261,282,266,259,278,259,276,331,11,331,11,321,30,320,43,315,50,307,54,294,55,275,55,57,54,37,50,24,43,16,30,12,11,9,11,0,281,0, 50,24,43,16,281,0,281,0,43,16,30,12,281,0,30,12,11,9,54,294,55,275,111,310,54,294,111,310,50,307,50,307,111,310,116,312,50,307,116,312,276,331,276,331,116,312,123,312,50,24,122,21,54,37,54,37,122,21,113,25,54,37,113,25,55,57,55,57,113,25,107,32,55,57,107,32,55,275,55,275,107,32,105,42,55,275,105,42,105,294,105,184,105,164,181,164,105,184,181,164,181,184,203,185,181,184,203,162,203,185,203,162,218,189,218,189,203,162,218,158,218,189,218,158,227,198,227,198,218,158,227,150,227,198,227,150,234,211,234,211,227,150,234,136,234,211,234,136,238,232,238,232,234,136,238,115,238,232,238,115,249,115,276,331,123,312,189,312,276,331,189,312,218,311,276,331,218,311,239,306,276,331,239,306,252,297,276,331,252,297,261,282,276,331,261,282,266,259,276,331,266,259,278,259,55,275,105,294,106,302,55,275,106,302,108,307,55,275,108,307,111,310,276,331,11,331,30,320,276,331,30,320,43,315,276,331,43,315,50,307,260,38,239,27,281,0,281,0,239,27,211,21,281,0,211,21,174,19,281,0,304,84,290,84,281,0,290,84,276,57,281,0,276,57,260,38,281,0,174,19,156,19,281,0,156,19,137,19,281,0,137,19,122,21,281,0,122,21,50,24,281,0,11,9,11,0,30,320,11,331,11,321,181,184,181,164,203,162,238,232,249,115,249,232, 507,0,507,9,476,18,453,32,435,52,417,79,394,113,382,130,370,144,359,155,345,164,330,172,329,173,342,181,354,193,364,209,373,228,382,251,388,266,394,280,401,293,410,301,419,305,425,302,430,295,435,286,443,279,457,276,466,278,473,283,478,289,481,297,482,305,480,315,475,324,467,331,456,336,442,338,419,335,401,325,388,309,376,290,367,267,356,239,345,216,331,197,310,185,280,181,280,293,283,307,291,315,304,319,325,321,325,331,186,331,186,321,206,320,220,315,227,307,230,294,231,275,231,181,203,185,182,197,167,216,154,239,143,267,134,290,123,309,109,325,91,335,68,338,54,336,43,331,35,324,30,315,28,305,29,297,32,289,37,283,44,278,53,276,67,279,75,286,80,295,85,302,91,305,100,301,109,293,115,280,122,266,128,251,137,228,146,209,156,193,168,181,181,173,180,172,165,164,152,155,140,144,129,130,117,113,94,79,75,52,57,32,35,18,4,9,4,0,99,0,109,10,120,23,131,40,144,60,158,84,177,116,190,138,201,152,213,159,231,161,231,55,230,36,228,23,222,16,210,11,193,9,193,0,323,0,323,9,305,12,292,16,284,23,281,36,280,55,280,161,297,159,309,152,320,138,333,116,352,84,367,60,380,40,391,23,401,10,411,0, 75,52,57,32,99,0,99,0,57,32,35,18,99,0,35,18,4,9,75,286,80,295,91,335,91,335,80,295,85,302,91,335,85,302,91,305,91,305,100,301,109,325,109,325,100,301,109,293,109,325,109,293,115,280,44,278,53,276,54,336,54,336,53,276,67,279,54,336,67,279,68,338,68,338,67,279,75,286,68,338,75,286,91,335,28,305,29,297,30,315,30,315,29,297,32,289,30,315,32,289,35,324,35,324,32,289,37,283,35,324,37,283,43,331,43,331,37,283,44,278,43,331,44,278,54,336,115,280,122,266,123,309,123,309,122,266,128,251,123,309,128,251,134,290,134,290,128,251,137,228,134,290,137,228,143,267,143,267,137,228,146,209,143,267,146,209,154,239,154,239,146,209,156,193,154,239,156,193,167,216,167,216,156,193,168,181,167,216,168,181,182,197,182,197,168,181,181,173,182,197,181,173,190,138,190,138,181,173,180,172,228,23,222,16,323,0,323,0,222,16,210,11,323,0,210,11,193,9,304,319,325,321,325,331,304,319,325,331,291,315,291,315,325,331,230,294,291,315,230,294,231,275,231,161,231,275,231,181,231,161,284,23,281,36,323,0,323,9,305,12,323,0,305,12,292,16,323,0,292,16,230,36,323,0,230,36,228,23,280,55,280,181,231,161,280,55,231,161,281,36,231,55,230,36,292,16,231,55,292,16,284,23,231,55,284,23,231,161,280,161,297,159,280,181,280,181,280,274,231,161,231,161,280,274,280,293,231,161,280,293,283,307,283,307,291,315,231,275,283,307,231,275,231,161,325,331,186,331,206,320,325,331,206,320,220,315,325,331,220,315,227,307,325,331,227,307,230,294,453,32,435,52,411,0,411,0,435,52,417,79,411,0,417,79,401,10,401,10,417,79,394,113,401,10,394,113,391,23,391,23,394,113,382,130,391,23,382,130,380,40,380,40,382,130,370,144,380,40,370,144,367,60,367,60,370,144,359,155,367,60,359,155,352,84,352,84,359,155,345,164,352,84,345,164,333,116,333,116,345,164,330,172,333,116,330,172,329,173,476,18,453,32,411,0,476,18,411,0,507,0,476,18,507,0,507,9,320,138,329,173,331,197,331,197,329,173,342,181,331,197,342,181,345,216,345,216,342,181,354,193,345,216,354,193,356,239,356,239,354,193,364,209,356,239,364,209,367,267,367,267,364,209,373,228,367,267,373,228,376,290,376,290,373,228,382,251,376,290,382,251,388,309,388,309,382,251,388,266,388,309,388,266,401,325,401,325,388,266,394,280,401,325,394,280,401,293,310,185,280,181,297,159,310,185,297,159,309,152,310,185,309,152,320,138,310,185,320,138,331,197,442,338,419,335,425,302,425,302,419,335,419,305,410,301,419,305,419,335,410,301,419,335,401,325,457,276,466,278,467,331,467,331,466,278,473,283,467,331,473,283,475,324,475,324,473,283,478,289,475,324,478,289,480,315,480,315,478,289,481,297,480,315,481,297,482,305,430,295,435,286,442,338,442,338,435,286,443,279,442,338,443,279,456,336,456,336,443,279,457,276,456,336,457,276,467,331,190,138,201,152,203,185,203,185,201,152,213,159,203,185,213,159,231,181,231,181,213,159,231,161,99,0,109,10,117,113,117,113,109,10,120,23,117,113,120,23,129,130,129,130,120,23,131,40,129,130,131,40,140,144,140,144,131,40,144,60,140,144,144,60,152,155,152,155,144,60,158,84,152,155,158,84,165,164,165,164,158,84,177,116,165,164,177,116,180,172,180,172,177,116,190,138,94,79,75,52,99,0,94,79,99,0,117,113,109,325,91,335,91,305,109,325,115,280,123,309,99,0,4,9,4,0,182,197,190,138,203,185,333,116,329,173,320,138,442,338,425,302,430,295,401,325,401,293,410,301,206,320,186,331,186,321,323,0,193,9,193,0, 177,175,201,180,222,192,240,208,251,229,256,253,252,281,239,304,217,322,185,334,142,338,131,338,121,337,111,335,100,333,89,330,83,328,67,324,60,322,54,321,49,322,44,324,40,328,37,332,35,338,25,338,23,220,35,220,43,253,56,280,76,301,101,314,131,319,156,316,176,308,191,294,201,277,204,257,204,245,201,232,196,219,188,207,175,196,165,191,155,187,143,185,127,183,104,183,104,163,128,163,146,161,160,158,172,153,184,146,194,138,202,129,209,118,213,105,215,91,211,64,201,43,183,28,159,18,128,15,105,17,85,23,65,33,44,47,23,65,14,57,32,35,54,17,80,4,109,-3,141,-6,160,-6,177,-3,193,0,208,5,223,13,239,25,253,39,264,55,270,74,272,95,267,121,252,142,230,158,204,169,177,174, 40,328,43,253,44,324,44,324,43,253,56,280,44,324,56,280,49,322,49,322,56,280,54,321,60,322,54,321,56,280,60,322,56,280,76,301,201,232,196,219,201,180,201,180,196,219,188,207,201,180,188,207,177,175,177,175,188,207,175,196,177,175,175,196,177,174,177,174,175,196,172,153,172,153,175,196,165,191,172,153,165,191,160,158,160,158,165,191,155,187,160,158,155,187,146,161,146,161,155,187,143,185,146,161,143,185,128,163,128,163,143,185,127,183,128,163,127,183,104,183,23,65,32,35,44,47,44,47,32,35,54,17,44,47,54,17,65,33,65,33,54,17,80,4,65,33,80,4,85,23,85,23,80,4,109,-3,85,23,109,-3,105,17,105,17,109,-3,128,15,159,18,128,15,141,-6,159,18,141,-6,160,-6,131,319,121,337,111,335,131,319,111,335,101,314,131,319,131,338,121,337,101,314,111,335,100,333,101,314,100,333,89,330,101,314,89,330,83,328,101,314,83,328,76,301,76,301,83,328,75,326,76,301,75,326,67,324,76,301,67,324,60,322,156,316,176,308,185,334,185,334,176,308,191,294,185,334,191,294,217,322,217,322,191,294,201,277,217,322,201,277,204,257,204,257,204,245,222,192,222,192,204,245,201,232,222,192,201,232,201,180,156,316,185,334,142,338,156,316,142,338,131,338,156,316,131,338,131,319,217,322,222,192,239,304,239,304,222,192,240,208,239,304,240,208,252,281,252,281,240,208,251,229,252,281,251,229,256,253,204,257,222,192,217,322,177,174,172,153,184,146,184,146,194,138,204,169,204,169,194,138,202,129,204,169,202,129,209,118,267,121,252,142,253,39,267,121,253,39,264,55,267,121,264,55,270,74,267,121,270,74,272,95,160,-6,177,-3,183,28,183,28,177,-3,193,0,183,28,193,0,201,43,201,43,193,0,208,5,201,43,208,5,211,64,211,64,208,5,223,13,211,64,223,13,215,91,215,91,223,13,230,158,230,158,223,13,239,25,230,158,239,25,252,142,252,142,239,25,253,39,204,169,209,118,230,158,230,158,209,118,213,105,230,158,213,105,215,91,204,169,177,174,184,146,128,15,109,-3,141,-6,40,328,37,332,43,253,43,253,37,332,35,338,43,253,35,338,35,220,35,220,35,338,25,338,35,220,25,338,23,220,32,35,23,65,14,57,159,18,160,-6,183,28,128,163,104,183,104,163, 352,0,352,9,333,12,320,17,312,25,309,37,307,55,307,274,309,293,312,307,320,315,333,319,352,321,352,331,212,331,212,321,230,319,242,315,251,309,255,299,257,285,105,82,105,274,106,294,110,307,118,315,131,319,150,321,150,331,9,331,9,321,29,319,42,315,50,307,53,294,54,274,54,61,53,39,50,25,42,16,29,12,9,9,9,0,149,0,148,9,131,11,118,16,110,23,106,33,105,48,257,252,257,62,256,41,252,26,245,17,232,12,213,9,213,0, 50,25,42,16,149,0,149,0,42,16,29,12,149,0,29,12,9,9,257,285,105,82,105,48,105,48,105,274,54,274,54,274,105,274,106,294,54,274,106,294,110,307,150,331,9,331,29,319,150,331,29,319,42,315,150,331,42,315,50,307,150,331,50,307,53,294,150,331,53,294,118,315,150,331,118,315,131,319,150,331,131,319,150,321,54,274,110,307,118,315,54,274,118,315,53,294,252,26,245,17,352,0,352,0,245,17,232,12,352,0,232,12,213,9,242,315,251,309,352,331,352,331,251,309,255,299,352,331,255,299,257,285,257,285,257,252,309,37,309,37,257,252,257,62,309,37,257,62,312,25,312,25,257,62,320,17,333,319,352,321,352,331,333,319,352,331,320,315,320,315,352,331,257,285,320,315,257,285,312,307,312,307,257,285,309,293,307,55,307,274,257,285,307,55,257,285,309,37,230,319,242,315,352,331,230,319,352,331,212,331,230,319,212,331,212,321,352,0,352,9,333,12,352,0,333,12,320,17,352,0,320,17,256,41,352,0,256,41,252,26,149,0,148,9,131,11,149,0,131,11,118,16,149,0,118,16,53,39,149,0,53,39,50,25,106,33,105,48,54,274,106,33,54,274,54,61,106,33,54,61,110,23,54,61,53,39,118,16,54,61,118,16,110,23,149,0,9,9,9,0,352,0,213,9,213,0,256,41,320,17,257,62,309,293,257,285,307,274,257,285,105,48,257,252,29,319,9,331,9,321, 248,424,246,436,242,445,235,452,227,456,219,458,211,456,208,453,206,450,205,445,207,438,213,434,225,430,227,425,226,418,221,413,212,408,199,406,180,405,162,406,149,408,140,413,135,418,134,425,136,430,148,434,154,438,156,445,156,450,154,453,151,456,148,457,144,458,135,456,127,452,120,445,115,436,113,424,117,408,129,395,145,386,163,380,180,378,198,380,216,385,232,395,243,407,248,424,16383,16383,352,0,352,9,333,12,320,17,312,25,309,37,307,55,307,274,309,293,312,307,320,315,333,319,352,321,352,331,212,331,212,321,230,319,242,316,250,310,254,300,256,285,105,82,105,274,106,294,110,307,118,315,131,319,150,321,150,331,9,331,9,321,29,319,42,315,50,307,53,294,54,274,54,61,53,39,50,25,42,16,29,12,9,9,9,0,149,0,148,9,131,11,119,15,111,22,107,33,105,48,257,252,257,62,256,41,252,26,245,17,232,12,213,9,213,0, 149,408,140,413,145,386,145,386,140,413,135,418,145,386,135,418,129,395,129,395,135,418,134,425,135,456,134,425,136,430,135,456,136,430,144,458,144,458,136,430,142,432,144,458,142,432,148,434,148,457,148,434,151,456,151,456,148,434,154,438,151,456,154,438,154,453,154,453,154,438,156,445,154,453,156,445,156,450,129,395,134,425,135,456,129,395,135,456,127,452,129,395,127,452,120,445,129,395,120,445,117,408,115,436,113,424,117,408,115,436,117,408,120,445,149,408,163,380,162,406,162,406,163,380,180,405,199,406,180,405,180,378,199,406,180,378,198,380,246,436,242,445,243,407,243,407,242,445,235,452,243,407,235,452,232,395,232,395,235,452,227,456,232,395,227,456,227,425,227,456,219,458,219,432,227,456,219,432,225,430,227,456,225,430,227,425,215,457,211,456,213,434,215,457,213,434,219,432,215,457,219,432,219,458,208,453,206,450,207,438,208,453,207,438,213,434,208,453,213,434,211,456,227,425,226,418,232,395,232,395,226,418,221,413,232,395,221,413,216,385,216,385,221,413,212,408,216,385,212,408,199,406,180,405,163,380,180,378,50,25,42,16,149,0,149,0,42,16,29,12,149,0,29,12,9,9,119,15,111,22,54,61,54,61,111,22,107,33,54,61,107,33,54,274,54,274,107,33,105,48,105,82,105,48,256,285,150,331,9,331,29,319,150,331,29,319,42,315,150,331,42,315,50,307,150,331,50,307,53,294,150,331,53,294,118,315,150,331,118,315,131,319,150,331,131,319,150,321,105,274,106,294,54,274,105,274,54,274,105,48,105,274,105,48,105,82,54,274,106,294,110,307,54,274,110,307,118,315,54,274,118,315,53,294,252,26,245,17,352,0,352,0,245,17,232,12,352,0,232,12,213,9,352,331,212,331,230,319,352,331,230,319,242,316,352,331,242,316,250,310,352,331,250,310,254,300,352,331,254,300,256,285,352,331,256,285,320,315,352,331,320,315,333,319,352,331,333,319,352,321,320,17,312,25,257,62,257,62,312,25,309,37,257,62,309,37,257,252,257,252,309,37,307,55,257,252,307,55,307,274,257,252,307,274,309,293,257,252,309,293,312,307,257,252,312,307,320,315,257,252,320,315,256,285,257,252,256,285,105,48,352,0,352,9,333,12,352,0,333,12,320,17,352,0,320,17,256,41,352,0,256,41,252,26,149,0,148,9,131,11,149,0,131,11,119,15,149,0,119,15,53,39,149,0,53,39,50,25,149,0,9,9,9,0,53,39,119,15,54,61,352,0,213,9,213,0,256,41,320,17,257,62,230,319,212,331,212,321,29,319,9,331,9,321,199,406,198,380,216,385,246,436,243,407,248,424,207,438,206,450,205,445,149,408,145,386,163,380,144,458,148,434,148,457, 343,0,343,9,321,13,312,17,302,23,292,30,282,40,271,54,259,71,246,92,230,114,218,131,206,145,193,155,180,164,164,171,164,172,178,181,190,193,201,208,211,227,220,251,225,266,232,281,239,294,247,303,257,306,263,303,267,296,272,287,281,280,294,277,303,279,310,284,315,291,318,299,319,306,317,317,313,325,305,332,295,337,281,338,257,335,239,325,224,309,213,290,204,267,196,245,187,226,176,209,162,195,142,185,137,183,131,182,124,181,106,181,106,274,107,293,110,307,117,315,130,319,151,321,151,331,10,331,10,321,30,319,43,315,51,306,54,293,55,275,55,65,54,42,51,27,43,17,29,12,9,9,9,0,151,0,151,9,132,12,119,16,111,23,107,36,106,55,106,161,113,161,119,160,125,158,130,156,134,154,140,149,149,140,160,126,174,108,189,85,203,61,216,40,227,24,238,10,248,0, 151,0,151,9,132,12,151,0,132,12,119,16,151,0,119,16,54,42,151,0,54,42,51,27,151,0,51,27,43,17,151,0,43,17,29,12,151,0,29,12,9,9,151,0,9,9,9,0,55,275,107,36,106,55,106,181,106,161,113,161,55,275,106,55,106,181,106,181,113,161,116,181,116,181,113,161,119,160,116,181,119,160,124,181,124,181,119,160,125,158,124,181,125,158,131,182,131,182,125,158,130,156,131,182,130,156,134,154,134,154,140,149,137,183,137,183,140,149,142,185,162,195,142,185,149,140,162,195,149,140,160,126,55,65,54,42,119,16,55,65,119,16,111,23,55,65,111,23,107,36,55,65,107,36,55,275,151,331,10,331,30,319,151,331,30,319,43,315,151,331,43,315,51,306,151,331,51,306,54,293,151,331,54,293,117,315,151,331,117,315,130,319,151,331,130,319,151,321,106,274,107,293,55,275,106,274,55,275,106,181,55,275,107,293,110,307,55,275,110,307,117,315,55,275,117,315,54,293,137,183,131,182,134,154,196,245,187,226,190,193,196,245,190,193,201,208,196,245,201,208,204,267,190,193,187,226,178,181,178,181,187,226,176,209,178,181,176,209,164,172,164,172,176,209,162,195,164,172,162,195,164,171,164,171,162,195,160,126,164,171,160,126,174,108,225,266,232,281,239,325,239,325,232,281,239,294,239,325,239,294,257,335,257,335,239,294,247,303,257,335,247,303,257,306,257,306,263,303,257,335,257,335,263,303,281,338,204,267,211,227,213,290,213,290,211,227,220,251,213,290,220,251,224,309,224,309,220,251,225,266,224,309,225,266,239,325,332,11,321,13,343,0,343,0,321,13,312,17,343,0,312,17,248,0,248,0,312,17,302,23,248,0,302,23,292,30,292,30,282,40,248,0,248,0,282,40,271,54,248,0,271,54,259,71,193,155,189,85,203,61,193,155,203,61,206,145,206,145,203,61,216,40,206,145,216,40,218,131,218,131,216,40,227,24,218,131,227,24,230,114,230,114,227,24,238,10,230,114,238,10,246,92,246,92,238,10,248,0,246,92,248,0,259,71,272,287,281,280,281,338,281,338,281,280,294,277,281,338,294,277,295,337,295,337,294,277,303,279,295,337,303,279,305,332,305,332,303,279,310,284,305,332,310,284,313,325,313,325,310,284,315,291,313,325,315,291,317,317,317,317,315,291,318,299,317,317,318,299,319,306,281,338,263,303,267,296,281,338,267,296,272,287,180,164,164,171,174,108,180,164,174,108,189,85,180,164,189,85,193,155,142,185,140,149,149,140,332,11,343,0,343,9,211,227,204,267,201,208,30,319,10,331,10,321, 332,0,332,9,313,12,300,17,292,25,288,37,287,55,287,274,288,293,292,307,300,315,313,319,332,321,332,331,65,331,65,321,80,320,93,316,101,308,107,295,108,275,108,112,105,78,100,47,89,26,73,17,65,21,54,43,46,53,32,57,25,56,18,53,11,48,6,40,4,30,7,14,14,4,25,-2,39,-5,55,-6,92,2,114,27,126,60,130,97,131,131,131,292,132,300,133,305,136,309,141,311,148,312,219,312,226,311,231,309,234,305,236,300,237,292,237,63,236,41,232,26,225,17,212,12,193,9,193,0, 108,112,105,78,114,27,114,27,105,78,100,47,114,27,100,47,92,2,92,2,100,47,89,26,92,2,89,26,73,17,73,17,65,21,92,2,92,2,65,21,55,-6,107,295,108,275,136,309,107,295,136,309,101,308,101,308,136,309,141,311,101,308,141,311,332,331,332,331,141,311,148,312,232,26,225,17,332,0,332,0,225,17,212,12,332,0,212,12,193,9,332,331,148,312,219,312,332,331,219,312,226,311,332,331,226,311,231,309,332,331,231,309,234,305,332,331,234,305,236,300,332,331,236,300,237,292,332,331,237,292,300,315,332,331,300,315,313,319,332,331,313,319,332,321,287,55,287,274,237,292,237,292,287,274,288,293,237,292,288,293,292,307,300,17,292,25,237,63,237,63,292,25,288,37,237,63,288,37,237,292,131,292,132,300,114,27,131,292,114,27,126,60,131,292,126,60,130,97,131,292,130,97,131,131,108,275,108,145,114,27,108,275,114,27,132,300,108,275,132,300,133,305,108,275,133,305,136,309,332,331,65,331,80,320,332,331,80,320,93,316,332,331,93,316,101,308,332,0,332,9,313,12,332,0,313,12,300,17,332,0,300,17,236,41,332,0,236,41,232,26,55,-6,65,21,60,31,55,-6,60,31,54,43,55,-6,54,43,46,53,55,-6,46,53,39,-5,46,53,32,57,39,-5,39,-5,32,57,25,56,39,-5,25,56,25,-2,25,-2,25,56,18,53,25,-2,18,53,14,4,14,4,18,53,11,48,14,4,11,48,7,14,7,14,11,48,6,40,7,14,6,40,4,30,108,112,114,27,108,145,332,0,193,9,193,0,236,41,300,17,237,63,237,292,288,37,287,55,80,320,65,331,65,321,300,315,237,292,292,307, 435,0,435,9,417,12,404,17,397,25,393,38,392,56,392,275,393,294,397,307,404,316,417,320,435,321,435,331,335,331,225,80,109,331,11,331,11,321,31,319,45,315,53,307,57,294,58,275,58,75,57,47,53,29,44,18,30,12,9,9,9,0,127,0,127,9,107,12,94,18,85,29,81,48,80,75,80,275,206,0,213,0,340,286,340,40,336,26,328,17,315,12,296,9,296,0, 53,29,44,18,127,0,127,0,44,18,30,12,127,0,30,12,9,9,336,26,328,17,435,0,435,0,328,17,315,12,435,0,315,12,296,9,417,320,435,321,435,331,417,320,435,331,404,316,404,316,435,331,340,286,404,316,340,286,397,307,397,307,340,286,393,294,404,17,397,25,340,61,340,61,397,25,393,38,340,61,393,38,340,286,340,286,393,38,392,56,340,286,392,56,392,275,206,0,213,0,225,80,225,80,213,0,340,286,225,80,340,286,335,331,335,331,340,286,435,331,109,331,11,331,31,319,109,331,31,319,45,315,109,331,45,315,53,307,109,331,53,307,57,294,109,331,57,294,58,275,109,331,58,275,80,275,109,331,80,275,206,0,109,331,206,0,225,80,80,75,80,275,58,275,80,75,58,275,81,48,81,48,58,275,58,75,81,48,58,75,85,29,85,29,58,75,57,47,85,29,57,47,94,18,94,18,57,47,53,29,94,18,53,29,127,0,435,0,435,9,417,12,435,0,417,12,404,17,435,0,404,17,340,40,435,0,340,40,336,26,107,12,94,18,127,0,107,12,127,0,127,9,127,0,9,9,9,0,435,0,296,9,296,0,340,40,404,17,340,61,31,319,11,331,11,321,393,294,340,286,392,275, 352,0,352,9,333,12,320,17,312,25,309,37,307,55,307,274,309,293,312,307,320,315,333,319,352,321,352,331,213,331,213,321,232,319,245,315,252,307,256,294,257,274,257,180,105,180,105,274,106,294,110,307,118,315,130,319,149,321,149,331,9,331,9,321,29,319,42,315,50,307,53,294,54,274,54,61,53,39,50,25,42,16,29,12,9,9,9,0,149,0,149,9,130,12,118,17,110,25,106,38,105,56,105,157,257,157,257,62,256,41,252,26,245,17,232,12,213,9,213,0, 50,25,42,16,149,0,149,0,42,16,29,12,149,0,29,12,9,9,149,331,9,331,29,319,149,331,29,319,42,315,149,331,42,315,50,307,149,331,50,307,53,294,149,331,53,294,118,315,149,331,118,315,130,319,149,331,130,319,149,321,54,274,106,38,105,56,105,180,105,157,257,157,105,180,257,157,257,180,257,180,257,157,312,25,257,180,312,25,309,37,54,274,105,56,105,274,54,274,105,274,106,294,54,274,106,294,110,307,54,274,110,307,118,315,54,274,118,315,53,294,252,26,245,17,352,0,352,0,245,17,232,12,352,0,232,12,213,9,333,319,352,321,352,331,333,319,352,331,320,315,320,315,352,331,256,294,320,315,256,294,257,274,309,37,257,274,257,180,307,55,307,274,257,274,257,274,307,274,309,293,257,274,309,293,312,307,352,331,213,331,232,319,352,331,232,319,245,315,352,331,245,315,252,307,352,331,252,307,256,294,352,0,352,9,333,12,352,0,333,12,320,17,352,0,320,17,256,41,352,0,256,41,252,26,257,62,256,41,320,17,257,62,320,17,312,25,257,62,312,25,257,157,149,0,149,9,130,12,149,0,130,12,118,17,149,0,118,17,53,39,149,0,53,39,50,25,54,61,53,39,118,17,54,61,118,17,110,25,54,61,110,25,106,38,54,61,106,38,54,274,149,0,9,9,9,0,352,0,213,9,213,0,257,274,309,37,307,55,232,319,213,331,213,321,320,315,257,274,312,307,29,319,9,331,9,321, 345,166,337,222,316,269,281,306,236,330,181,338,127,330,82,307,47,271,26,224,18,167,26,109,47,61,82,24,127,1,181,-6,235,1,280,24,315,60,337,108,345,166,16383,16383,288,169,286,134,281,103,273,76,261,53,247,35,235,26,223,19,210,15,197,12,182,11,168,12,155,15,143,19,131,25,120,33,103,52,91,75,82,102,77,132,75,166,76,194,81,222,88,247,98,269,109,286,122,298,135,308,150,314,165,318,181,320,194,319,207,316,220,311,231,305,243,296,258,279,271,257,280,231,286,201,288,169, 150,314,181,338,135,308,135,308,181,338,127,330,135,308,127,330,122,298,122,298,127,330,109,286,98,269,109,286,127,330,98,269,127,330,82,307,82,102,82,24,91,75,91,75,82,24,127,1,91,75,127,1,103,52,103,52,127,1,120,33,131,25,120,33,127,1,131,25,127,1,181,-6,236,330,181,338,194,319,194,319,181,338,181,320,165,318,181,320,181,338,165,318,181,338,150,314,223,19,210,15,235,1,235,1,210,15,197,12,235,1,197,12,182,11,182,11,168,12,181,-6,181,-6,168,12,155,15,181,-6,155,15,143,19,207,316,220,311,236,330,236,330,220,311,231,305,236,330,231,305,243,296,243,296,258,279,281,306,281,306,258,279,271,257,281,306,271,257,280,231,281,103,273,76,280,24,280,24,273,76,261,53,280,24,261,53,247,35,247,35,235,26,280,24,280,24,235,26,235,1,345,166,337,222,337,108,337,108,337,222,316,269,337,108,316,269,315,60,315,60,316,269,288,169,286,201,288,169,316,269,286,201,316,269,281,306,286,201,281,306,280,231,281,306,236,330,243,296,315,60,288,169,286,134,315,60,286,134,281,103,315,60,281,103,280,24,182,11,181,-6,235,1,82,307,47,271,47,61,82,307,47,61,75,166,82,307,75,166,76,194,82,307,76,194,81,222,82,307,81,222,88,247,82,307,88,247,98,269,82,102,77,132,82,24,82,24,77,132,75,166,26,109,47,61,47,271,26,109,47,271,26,224,26,109,26,224,18,167,82,24,75,166,47,61,223,19,235,1,235,26,236,330,194,319,207,316,131,25,181,-6,143,19, 353,0,353,9,333,12,321,17,313,25,309,37,308,55,308,274,309,293,313,307,321,315,334,319,353,321,353,331,9,331,9,321,29,319,42,315,50,307,53,294,54,274,54,61,53,39,50,25,42,16,29,12,9,9,9,0,149,0,149,9,130,12,118,17,110,25,106,38,105,56,105,300,107,306,111,309,116,311,124,312,238,312,246,311,251,309,255,306,257,300,257,62,256,41,253,26,246,17,233,12,213,9,213,0, 50,25,42,16,149,0,149,0,42,16,29,12,149,0,29,12,9,9,42,315,50,307,353,331,353,331,50,307,116,311,353,331,116,311,124,312,353,331,124,312,238,312,353,331,238,312,246,311,253,26,246,17,353,0,353,0,246,17,233,12,353,0,233,12,213,9,353,331,246,311,251,309,353,331,251,309,255,306,353,331,255,306,257,300,353,331,257,300,257,292,353,331,257,292,321,315,353,331,321,315,334,319,353,331,334,319,353,321,308,55,308,274,257,292,257,292,308,274,309,293,257,292,309,293,313,307,321,17,313,25,257,62,257,62,313,25,309,37,257,62,309,37,257,292,118,17,110,25,54,61,54,61,110,25,106,38,54,61,106,38,54,274,54,274,106,38,105,56,54,274,105,56,105,291,54,274,105,291,105,300,54,274,105,300,107,306,54,274,107,306,111,309,54,274,111,309,53,294,116,311,50,307,53,294,116,311,53,294,111,309,29,319,42,315,353,331,29,319,353,331,9,331,29,319,9,331,9,321,353,0,353,9,333,12,353,0,333,12,321,17,353,0,321,17,256,41,353,0,256,41,253,26,149,0,149,9,130,12,149,0,130,12,118,17,149,0,118,17,53,39,149,0,53,39,50,25,149,0,9,9,9,0,53,39,118,17,54,61,353,0,213,9,213,0,256,41,321,17,257,62,257,292,309,37,308,55,321,315,257,292,313,307, 9,331,9,321,28,319,40,315,47,307,51,294,51,39,48,25,41,16,29,12,9,9,9,0,150,0,150,9,129,12,115,16,107,24,104,37,103,56,103,146,110,145,115,145,120,144,132,144,161,145,184,147,204,153,221,161,239,175,249,185,257,197,263,210,266,225,267,240,266,254,263,268,258,280,252,291,243,300,227,310,209,319,187,325,162,329,134,331,16383,16383,103,294,103,301,105,306,108,310,113,311,120,312,156,309,182,302,200,287,210,266,213,238,210,213,199,192,182,177,158,167,128,164,118,164,113,165,109,165,103,166, 113,311,120,312,120,312,134,331,120,312,156,309,134,331,156,309,162,329,162,329,156,309,182,302,162,329,182,302,187,325,187,325,182,302,200,287,187,325,200,287,209,319,209,319,200,287,210,266,209,319,210,266,227,310,227,310,210,266,213,238,227,310,213,238,221,161,221,161,210,213,204,153,204,153,210,213,199,192,204,153,199,192,184,147,184,147,199,192,182,177,184,147,182,177,161,145,161,145,182,177,158,167,161,145,158,167,132,144,132,144,158,167,128,164,132,144,128,164,125,144,125,144,128,164,122,164,125,144,122,164,120,144,120,144,122,164,118,164,120,144,118,164,115,145,115,145,118,164,113,165,115,145,113,165,110,145,110,145,113,165,109,165,110,145,109,165,103,146,103,146,109,165,103,166,103,146,103,166,103,56,103,56,103,166,51,276,103,56,51,276,104,37,104,37,51,276,51,61,267,240,266,254,266,225,266,225,266,254,263,268,266,225,263,268,263,210,263,210,263,268,258,280,263,210,258,280,257,197,257,197,258,280,252,291,257,197,252,291,249,185,249,185,252,291,243,300,249,185,243,300,239,175,239,175,243,300,227,310,239,175,227,310,221,161,134,331,9,331,28,319,134,331,28,319,40,315,134,331,40,315,47,307,134,331,47,307,51,294,134,331,51,294,51,276,134,331,51,276,108,310,134,331,108,310,113,311,134,331,113,311,120,312,103,294,103,301,51,276,103,294,51,276,103,166,105,306,108,310,51,276,105,306,51,276,103,301,150,0,150,9,129,12,150,0,129,12,115,16,150,0,115,16,51,39,150,0,51,39,48,25,150,0,48,25,41,16,150,0,41,16,29,12,150,0,29,12,9,9,150,0,9,9,9,0,51,61,51,39,115,16,51,61,115,16,107,24,51,61,107,24,104,37,28,319,9,331,9,321,210,213,221,161,213,238, 311,65,289,47,269,32,248,23,226,17,201,15,180,17,161,21,143,28,126,38,112,51,99,68,89,88,82,112,77,140,76,171,81,219,96,260,121,291,154,311,196,318,215,316,232,311,248,304,263,293,276,280,283,272,289,263,294,252,299,240,302,224,314,224,310,338,300,338,297,332,289,324,284,322,278,321,273,322,266,324,258,326,244,330,232,333,208,337,196,338,185,338,157,336,131,330,106,320,83,305,63,286,47,266,35,243,26,218,20,191,18,162,20,133,26,106,36,80,49,57,66,37,85,22,107,9,131,0,157,-4,184,-6,218,-4,249,3,277,16,301,34,320,56, 66,37,77,140,76,171,76,171,83,305,66,37,66,37,83,305,63,286,66,37,63,286,49,57,49,57,63,286,47,266,49,57,47,266,36,80,36,80,47,266,35,243,36,80,35,243,26,106,26,106,35,243,26,218,26,106,26,218,20,133,20,133,26,218,20,191,20,133,20,191,18,162,82,112,85,22,89,88,89,88,85,22,107,9,89,88,107,9,99,68,99,68,107,9,112,51,126,38,112,51,131,0,126,38,131,0,143,28,143,28,131,0,157,-4,143,28,157,-4,161,21,161,21,157,-4,184,-6,161,21,184,-6,180,17,180,17,184,-6,201,15,226,17,201,15,218,-4,226,17,218,-4,249,3,77,140,66,37,85,22,77,140,85,22,82,112,112,51,107,9,131,0,258,326,263,293,266,324,266,324,263,293,276,280,266,324,276,280,273,322,273,322,276,280,278,321,284,322,278,321,283,272,284,322,283,272,289,263,278,321,276,280,283,272,232,333,232,311,244,330,244,330,232,311,248,304,244,330,248,304,251,328,251,328,248,304,263,293,251,328,263,293,258,326,220,335,208,337,215,316,220,335,215,316,232,311,220,335,232,311,232,333,208,337,196,338,215,316,215,316,196,338,196,318,154,311,196,318,157,336,154,311,157,336,131,330,314,224,310,338,302,224,302,224,310,338,300,338,302,224,300,338,299,240,299,240,300,338,297,332,299,240,297,332,294,252,294,252,297,332,293,328,294,252,293,328,289,263,289,263,293,328,289,324,289,263,289,324,284,322,320,56,311,65,301,34,301,34,311,65,289,47,301,34,289,47,277,16,277,16,289,47,269,32,277,16,269,32,249,3,249,3,269,32,248,23,249,3,248,23,226,17,201,15,184,-6,218,-4,196,318,196,338,185,338,196,318,185,338,157,336,76,171,81,219,83,305,83,305,81,219,96,260,83,305,96,260,106,320,106,320,96,260,121,291,106,320,121,291,131,330,131,330,121,291,154,311, 296,246,292,331,18,331,15,246,27,246,33,274,42,292,54,303,73,309,100,310,130,310,130,61,129,39,125,25,117,16,104,12,83,9,83,0,229,0,229,9,208,11,194,16,186,23,182,36,181,55,181,310,210,310,237,309,256,303,269,292,277,274,284,246, 292,331,18,331,73,309,292,331,73,309,100,310,292,331,100,310,130,310,292,331,130,310,181,310,292,331,181,310,210,310,292,331,210,310,237,309,292,331,237,309,256,303,292,331,256,303,269,292,292,331,269,292,277,274,292,331,277,274,284,246,292,331,284,246,296,246,194,16,186,23,130,61,130,61,186,23,182,36,130,61,182,36,130,310,130,310,182,36,181,55,130,310,181,55,181,310,18,331,15,246,27,246,18,331,27,246,33,274,18,331,33,274,42,292,18,331,42,292,54,303,18,331,54,303,73,309,229,0,229,9,208,11,229,0,208,11,194,16,229,0,194,16,129,39,229,0,129,39,125,25,229,0,125,25,117,16,229,0,117,16,104,12,229,0,104,12,83,9,229,0,83,9,83,0,129,39,194,16,130,61, 347,331,243,331,243,322,254,320,263,316,269,312,273,306,274,299,273,292,271,284,268,273,263,260,257,245,204,118,132,245,123,262,110,288,107,297,106,303,107,309,112,314,119,318,129,321,142,322,142,331,7,331,7,322,15,320,27,316,37,310,42,305,46,300,51,294,61,278,181,67,172,53,163,41,154,33,146,28,138,27,136,27,133,28,131,29,127,30,124,32,118,35,108,39,104,40,99,41,92,40,85,37,80,32,77,26,76,20,78,10,84,3,93,-2,104,-5,117,-6,132,-4,147,0,161,9,175,22,188,40,194,51,202,65,210,81,219,100,228,122,291,272,300,289,310,302,321,312,333,319,347,322, 21,318,27,316,142,331,142,331,27,316,32,313,142,331,32,313,37,310,37,310,42,305,142,331,142,331,42,305,46,300,142,331,46,300,51,294,61,278,181,67,107,297,61,278,107,297,106,303,106,303,107,309,61,278,61,278,107,309,112,314,61,278,112,314,56,286,142,331,51,294,56,286,142,331,56,286,112,314,142,331,112,314,119,318,142,331,119,318,129,321,142,331,129,321,142,322,15,320,21,318,142,331,15,320,142,331,7,331,15,320,7,331,7,322,133,28,131,29,132,-4,132,-4,131,29,127,30,132,-4,127,30,124,32,124,32,118,35,132,-4,132,-4,118,35,117,-6,181,67,172,53,175,22,175,22,172,53,163,41,175,22,163,41,161,9,161,9,163,41,154,33,161,9,154,33,147,0,147,0,154,33,146,28,147,0,146,28,138,27,138,27,136,27,147,0,147,0,136,27,133,28,147,0,133,28,132,-4,257,245,204,118,210,81,257,245,210,81,219,100,257,245,219,100,228,122,257,245,228,122,291,272,347,331,243,331,254,320,347,331,254,320,263,316,347,331,263,316,269,312,347,331,269,312,273,306,347,331,273,306,274,299,347,331,274,299,321,312,347,331,321,312,333,319,347,331,333,319,347,322,291,272,300,289,274,299,291,272,274,299,273,292,291,272,273,292,271,284,291,272,271,284,268,273,291,272,268,273,263,260,291,272,263,260,257,245,310,302,321,312,274,299,310,302,274,299,300,289,204,118,132,245,181,67,204,118,181,67,188,40,204,118,188,40,194,51,204,118,194,51,202,65,204,118,202,65,210,81,181,67,132,245,123,262,181,67,123,262,116,276,181,67,116,276,110,288,181,67,110,288,107,297,118,35,113,37,117,-6,117,-6,113,37,108,39,117,-6,108,39,104,-5,104,-5,108,39,104,40,104,-5,104,40,99,41,93,-2,104,-5,99,41,93,-2,99,41,92,40,93,-2,92,40,85,37,93,-2,85,37,84,3,80,32,77,26,78,10,80,32,78,10,84,3,80,32,84,3,85,37,78,10,77,26,76,20,181,67,175,22,188,40,254,320,243,331,243,322, 218,290,219,301,223,310,232,316,247,320,269,321,269,331,116,331,116,321,138,320,152,317,161,311,165,302,166,290,166,280,124,276,84,263,50,241,27,209,19,165,24,128,41,97,69,72,107,57,158,51,166,51,166,37,164,27,158,19,148,14,134,10,116,9,116,0,269,0,269,9,248,11,233,14,224,19,219,27,218,38,218,51,230,51,265,56,302,69,334,91,357,123,366,165,357,209,333,241,300,263,260,276,218,280,16383,16383,217,262,251,256,278,240,296,216,307,188,311,159,305,128,291,103,270,85,244,74,217,70,16383,16383,167,70,135,75,108,88,89,107,78,132,74,159,78,189,91,216,111,240,136,256,167,262, 269,321,269,321,247,320,247,320,269,321,269,331,247,320,269,331,232,316,232,316,269,331,166,290,232,316,166,290,223,310,223,310,166,290,167,262,219,27,167,262,167,70,219,27,167,70,224,19,224,19,167,70,166,51,224,19,166,51,166,37,218,38,217,70,167,262,167,262,217,70,217,262,167,262,217,262,218,290,218,290,217,262,218,280,219,301,223,310,167,262,219,301,167,262,218,290,166,290,269,331,165,302,269,331,116,331,138,320,269,331,138,320,152,317,269,331,152,317,161,311,269,331,161,311,165,302,91,216,111,240,124,276,124,276,111,240,136,256,124,276,136,256,166,280,166,280,136,256,167,262,166,280,167,262,166,290,84,263,50,241,74,159,84,263,74,159,78,189,84,263,78,189,91,216,84,263,91,216,124,276,19,165,24,128,27,209,27,209,24,128,41,97,27,209,41,97,50,241,50,241,41,97,69,72,50,241,69,72,74,159,334,91,311,159,305,128,334,91,305,128,302,69,302,69,305,128,291,103,302,69,291,103,270,85,307,188,311,159,333,241,333,241,311,159,334,91,333,241,334,91,357,209,357,209,334,91,357,123,357,209,357,123,366,165,300,263,260,276,278,240,300,263,278,240,296,216,300,263,296,216,307,188,300,263,307,188,333,241,251,256,278,240,260,276,251,256,260,276,218,280,251,256,218,280,217,262,218,51,230,51,244,74,244,74,230,51,265,56,244,74,265,56,270,85,270,85,265,56,302,69,218,38,167,262,219,27,218,38,218,51,217,70,269,0,269,9,248,11,269,0,248,11,233,14,269,0,233,14,166,37,269,0,166,37,164,27,269,0,164,27,158,19,269,0,158,19,148,14,269,0,148,14,134,10,269,0,134,10,116,9,269,0,116,9,116,0,158,51,166,51,167,70,158,51,167,70,135,75,158,51,135,75,108,88,158,51,108,88,107,57,74,159,69,72,78,132,78,132,69,72,107,57,78,132,107,57,89,107,89,107,107,57,108,88,166,37,233,14,224,19,217,70,218,51,244,74,138,320,116,331,116,321, 352,0,352,9,337,12,326,16,316,22,306,32,296,46,200,184,272,272,289,292,303,305,316,314,330,319,348,321,348,331,229,331,229,321,243,320,253,319,259,316,262,311,263,305,262,301,260,296,256,290,250,282,243,272,187,202,165,234,151,255,139,272,130,286,125,297,123,306,124,312,127,316,132,319,139,320,147,320,161,321,161,331,11,331,11,321,28,319,43,312,58,299,77,276,102,242,155,164,77,66,57,42,42,26,30,17,18,12,4,9,4,0,121,0,121,9,105,11,95,13,88,17,84,21,83,26,84,31,87,38,92,46,99,57,109,70,169,145,216,74,225,60,232,48,238,38,241,31,242,25,241,20,237,16,232,14,225,12,217,11,204,9,204,0, 30,17,121,0,42,26,42,26,121,0,88,17,42,26,88,17,57,42,57,42,88,17,84,21,57,42,84,21,83,26,83,26,84,31,77,66,77,66,84,31,87,38,77,66,87,38,155,164,155,164,87,38,92,46,155,164,92,46,99,57,102,242,155,164,125,297,102,242,125,297,123,306,123,306,124,312,102,242,155,164,99,57,109,70,109,70,169,145,155,164,155,164,169,145,165,234,155,164,165,234,151,255,77,66,57,42,83,26,161,331,11,331,28,319,161,331,28,319,43,312,161,331,43,312,58,299,161,331,58,299,132,319,161,331,132,319,139,320,161,331,139,320,147,320,161,331,147,320,161,321,132,319,58,299,127,316,127,316,58,299,77,276,127,316,77,276,124,312,124,312,77,276,102,242,260,296,256,290,272,272,272,272,256,290,250,282,272,272,250,282,243,272,243,272,187,202,200,184,200,184,187,202,216,74,200,184,216,74,296,46,296,46,216,74,225,60,296,46,225,60,232,48,348,331,229,331,243,320,348,331,243,320,253,319,348,331,253,319,259,316,348,331,259,316,262,311,348,331,262,311,263,305,348,331,263,305,316,314,348,331,316,314,330,319,348,331,330,319,348,321,263,305,272,272,289,292,263,305,289,292,303,305,263,305,303,305,316,314,262,301,260,296,272,272,262,301,272,272,263,305,243,272,200,184,272,272,237,16,232,14,352,0,352,0,232,14,225,12,352,0,225,12,217,11,242,25,352,0,326,16,242,25,326,16,316,22,242,25,316,22,306,32,242,25,306,32,296,46,242,25,296,46,241,31,296,46,232,48,238,38,296,46,238,38,241,31,187,202,165,234,169,145,187,202,169,145,216,74,337,12,326,16,352,0,337,12,352,0,352,9,241,20,237,16,352,0,241,20,352,0,242,25,204,9,204,0,352,0,204,9,352,0,217,11,155,164,151,255,139,272,155,164,139,272,130,286,155,164,130,286,125,297,121,0,121,9,105,11,121,0,105,11,95,13,121,0,95,13,88,17,18,12,4,9,121,0,18,12,121,0,30,17,121,0,4,9,4,0,243,320,229,331,229,321,28,319,11,331,11,321, 348,-75,348,9,329,12,316,16,308,24,305,37,304,57,304,292,308,306,316,315,329,319,348,321,348,331,209,331,209,321,228,319,240,315,248,306,251,293,252,275,252,28,250,23,247,21,242,19,115,19,110,21,107,23,105,28,105,269,106,290,109,305,117,314,129,319,149,321,149,331,9,331,9,321,28,319,41,314,49,306,53,294,54,276,54,57,53,37,49,24,41,16,28,12,9,9,9,0,284,0,299,-5,312,-15,323,-29,331,-49,332,-54,333,-60,335,-67,335,-72,336,-75, 49,24,41,16,268,0,268,0,41,16,28,12,268,0,28,12,9,9,149,331,9,331,28,319,149,331,28,319,41,314,149,331,41,314,49,306,149,331,49,306,53,294,149,331,53,294,117,314,149,331,117,314,129,319,149,331,129,319,149,321,110,21,107,23,54,57,54,57,107,23,105,28,54,57,105,28,54,276,54,276,105,28,105,34,54,276,105,34,105,269,54,276,105,269,106,290,54,276,106,290,109,305,54,276,109,305,117,314,54,276,117,314,53,294,329,319,348,321,348,331,329,319,348,331,316,315,316,315,348,331,251,293,316,315,251,293,252,275,268,0,252,275,252,35,268,0,252,35,252,28,316,16,308,24,312,-15,312,-15,308,24,305,37,312,-15,305,37,299,-5,299,-5,305,37,304,57,299,-5,304,57,304,270,252,275,268,0,304,292,304,292,268,0,284,0,304,292,284,0,304,270,304,270,284,0,299,-5,308,306,316,315,252,275,308,306,252,275,304,292,348,331,209,331,228,319,348,331,228,319,240,315,348,331,240,315,248,306,348,331,248,306,251,293,333,-60,348,9,332,-54,332,-54,348,9,331,-49,323,-29,331,-49,329,12,323,-29,329,12,316,16,348,9,333,-60,335,-67,348,9,335,-67,335,-72,348,9,335,-72,336,-75,348,9,336,-75,348,-75,348,9,329,12,331,-49,268,0,252,28,250,23,268,0,250,23,247,21,268,0,247,21,242,19,268,0,242,19,235,19,268,0,235,19,123,19,268,0,123,19,115,19,268,0,115,19,49,24,110,21,54,57,53,37,110,21,53,37,49,24,110,21,49,24,115,19,268,0,9,9,9,0,316,16,312,-15,323,-29,228,319,209,331,209,321,28,319,9,331,9,321, 320,0,320,9,301,12,288,16,280,24,276,37,275,57,275,269,276,291,280,306,288,315,301,319,320,321,320,331,186,331,186,321,204,319,214,316,221,309,223,299,224,283,224,174,216,170,204,166,190,161,173,158,155,156,132,158,116,165,105,176,99,193,97,216,97,273,98,294,101,307,109,315,121,319,139,321,139,331,2,331,2,321,21,319,34,315,41,307,45,293,46,273,46,211,50,178,62,155,80,142,104,136,133,134,157,136,178,140,197,145,212,152,224,157,224,57,223,37,219,24,211,16,199,12,180,9,180,0, 139,321,139,321,121,319,121,319,139,321,139,331,121,319,139,331,109,315,109,315,139,331,45,293,109,315,45,293,46,273,50,178,46,273,46,211,132,158,116,165,133,134,133,134,116,165,105,176,133,134,105,176,104,136,104,136,105,176,99,193,104,136,99,193,80,142,80,142,99,193,97,216,80,142,97,216,97,273,46,273,50,178,101,307,101,307,50,178,62,155,101,307,62,155,98,294,98,294,62,155,80,142,98,294,80,142,97,273,139,331,2,331,21,319,139,331,21,319,34,315,139,331,34,315,41,307,139,331,41,307,45,293,224,283,224,174,224,157,224,157,224,174,216,170,224,157,216,170,212,152,212,152,216,170,204,166,212,152,204,166,197,145,197,145,204,166,190,161,197,145,190,161,178,140,178,140,190,161,173,158,178,140,173,158,157,136,157,136,173,158,155,156,133,134,157,136,155,156,133,134,155,156,132,158,320,331,186,331,204,319,320,331,204,319,214,316,320,331,214,316,221,309,320,331,221,309,223,299,320,331,223,299,224,283,320,331,224,283,288,315,320,331,288,315,301,319,320,331,301,319,320,321,275,57,275,269,224,157,224,157,275,269,276,291,224,157,276,291,280,306,224,283,224,157,280,306,224,283,280,306,288,315,320,0,320,9,301,12,320,0,301,12,288,16,320,0,288,16,223,37,320,0,223,37,219,24,320,0,219,24,211,16,320,0,211,16,199,12,320,0,199,12,180,9,320,0,180,9,180,0,224,157,280,24,276,37,224,157,276,37,275,57,224,57,223,37,288,16,224,57,288,16,280,24,224,57,280,24,224,157,204,319,186,331,186,321,21,319,2,331,2,321,109,315,46,273,101,307, 483,0,483,9,463,12,450,16,443,24,439,37,438,57,438,270,439,292,443,306,450,315,463,319,483,321,483,331,343,331,344,321,362,319,375,315,383,306,386,293,387,275,387,28,385,23,382,21,377,19,282,19,277,21,274,23,272,27,272,269,273,290,276,305,283,314,296,319,315,321,315,331,183,331,183,321,200,319,210,314,217,306,220,294,220,28,218,23,215,21,210,19,120,19,115,21,112,23,110,28,110,269,111,291,114,306,120,315,131,320,147,321,147,331,15,331,15,321,34,319,46,314,54,306,58,294,59,276,59,57,58,37,54,24,46,16,33,12,15,9,15,0, 59,57,58,37,115,21,115,21,58,37,54,24,115,21,54,24,120,19,120,19,54,24,46,16,120,19,46,16,483,0,483,0,46,16,33,12,483,0,33,12,15,9,147,331,15,331,34,319,147,331,34,319,46,314,147,331,46,314,54,306,147,331,54,306,58,294,147,331,58,294,120,315,147,331,120,315,131,320,147,331,131,320,147,321,115,21,112,23,59,57,59,57,112,23,110,28,59,57,110,28,59,276,59,276,110,28,110,34,59,276,110,34,110,269,59,276,110,269,111,291,59,276,111,291,114,306,59,276,114,306,120,315,59,276,120,315,58,294,296,319,315,321,315,331,296,319,315,331,283,314,283,314,315,331,220,294,283,314,220,294,220,276,272,27,220,276,220,35,272,27,220,35,274,23,274,23,220,35,277,21,272,33,272,269,220,276,220,276,272,269,273,290,220,276,273,290,276,305,315,331,183,331,200,319,315,331,200,319,210,314,315,331,210,314,217,306,315,331,217,306,220,294,463,319,483,321,483,331,463,319,483,331,450,315,450,315,483,331,386,293,450,315,386,293,387,275,439,37,387,275,387,35,439,37,387,35,443,24,443,24,387,35,450,16,438,57,438,270,387,275,387,275,438,270,439,292,387,275,439,292,443,306,483,331,343,331,344,321,483,331,344,321,362,319,483,331,362,319,375,315,483,331,375,315,383,306,483,331,383,306,386,293,483,0,483,9,463,12,483,0,463,12,450,16,483,0,450,16,387,35,483,0,387,35,387,28,483,0,387,28,385,23,483,0,385,23,382,21,483,0,382,21,377,19,483,0,377,19,371,19,483,0,371,19,289,19,483,0,289,19,282,19,483,0,282,19,218,23,483,0,218,23,215,21,483,0,215,21,210,19,483,0,210,19,203,19,483,0,203,19,127,19,483,0,127,19,120,19,282,19,277,21,220,35,282,19,220,35,220,28,282,19,220,28,218,23,483,0,15,9,15,0,220,276,272,27,272,33,387,275,439,37,438,57,450,315,387,275,443,306,200,319,183,331,183,321,283,314,220,276,276,305,34,319,15,331,15,321, 483,-75,483,9,463,12,450,16,443,24,439,37,438,57,438,270,439,292,443,306,450,315,463,319,483,321,483,331,343,331,344,321,362,319,375,315,383,306,386,293,387,275,387,28,385,23,382,21,377,19,282,19,277,21,274,23,272,27,272,269,273,290,276,305,283,314,296,319,315,321,315,331,183,331,183,321,200,319,210,314,217,306,220,294,220,28,218,23,215,21,210,19,120,19,115,21,112,23,110,28,110,269,111,291,114,306,120,315,131,320,147,321,147,331,15,331,15,321,34,319,46,314,54,306,58,294,59,276,59,57,58,37,54,24,46,16,33,12,15,9,15,0,419,0,433,-5,446,-15,457,-29,465,-49,467,-55,468,-61,469,-68,470,-73,470,-75, 59,57,58,37,115,21,115,21,58,37,54,24,115,21,54,24,120,19,120,19,54,24,46,16,120,19,46,16,402,0,402,0,46,16,33,12,402,0,33,12,15,9,147,331,15,331,34,319,147,331,34,319,46,314,147,331,46,314,54,306,147,331,54,306,58,294,147,331,58,294,120,315,147,331,120,315,131,320,147,331,131,320,147,321,115,21,112,23,59,57,59,57,112,23,110,28,59,57,110,28,59,276,59,276,110,28,110,34,59,276,110,34,110,269,59,276,110,269,111,291,59,276,111,291,114,306,59,276,114,306,120,315,59,276,120,315,58,294,296,319,315,321,315,331,296,319,315,331,283,314,283,314,315,331,220,294,283,314,220,294,220,276,272,27,220,276,220,35,272,27,220,35,274,23,274,23,220,35,277,21,272,33,272,269,220,276,220,276,272,269,273,290,220,276,273,290,276,305,315,331,183,331,200,319,315,331,200,319,210,314,315,331,210,314,217,306,315,331,217,306,220,294,463,319,483,321,483,331,463,319,483,331,450,315,450,315,483,331,386,293,450,315,386,293,387,275,402,0,387,275,387,35,402,0,387,35,387,28,450,16,443,24,446,-15,446,-15,443,24,439,37,446,-15,439,37,433,-5,433,-5,439,37,438,57,433,-5,438,57,438,270,387,275,402,0,439,292,439,292,402,0,419,0,439,292,419,0,438,270,438,270,419,0,433,-5,443,306,450,315,387,275,443,306,387,275,439,292,483,331,343,331,344,321,483,331,344,321,362,319,483,331,362,319,375,315,483,331,375,315,383,306,483,331,383,306,386,293,468,-61,483,9,467,-55,467,-55,483,9,465,-49,457,-29,465,-49,463,12,457,-29,463,12,450,16,483,9,468,-61,469,-68,483,9,469,-68,470,-73,483,9,470,-73,470,-75,483,9,470,-75,483,-75,483,9,463,12,465,-49,402,0,387,28,385,23,402,0,385,23,382,21,402,0,382,21,377,19,402,0,377,19,371,19,402,0,371,19,289,19,402,0,289,19,282,19,402,0,282,19,220,28,402,0,220,28,218,23,402,0,218,23,215,21,402,0,215,21,210,19,402,0,210,19,203,19,402,0,203,19,127,19,402,0,127,19,120,19,220,35,220,28,282,19,220,35,282,19,277,21,402,0,15,9,15,0,220,276,272,27,272,33,450,16,446,-15,457,-29,200,319,183,331,183,321,283,314,220,276,276,305,34,319,15,331,15,321, 171,183,171,274,172,293,177,307,186,315,200,319,219,321,219,331,10,331,7,246,18,246,25,274,33,293,45,304,63,309,90,310,120,310,120,56,119,37,114,24,106,16,92,11,72,9,72,0,231,0,271,4,305,15,330,34,346,59,352,91,345,126,327,153,299,170,262,180,219,183,16383,16383,171,163,204,163,231,161,256,154,276,141,289,120,294,89,289,59,275,39,253,27,226,21,195,19,185,20,178,22,174,26,171,33,171,41, 114,24,106,16,231,0,231,0,106,16,92,11,231,0,92,11,72,9,177,307,186,315,120,310,120,310,186,315,219,331,120,310,219,331,90,310,63,309,90,310,219,331,63,309,219,331,10,331,200,319,219,321,219,331,200,319,219,331,186,315,120,310,171,33,171,41,171,183,171,163,204,163,171,183,204,163,219,183,219,183,204,163,231,161,219,183,231,161,262,180,262,180,231,161,256,154,262,180,256,154,276,141,120,310,171,41,171,274,120,310,171,274,172,293,120,310,172,293,177,307,10,331,7,246,18,246,10,331,18,246,25,274,10,331,25,274,33,293,10,331,33,293,45,304,10,331,45,304,63,309,294,89,289,59,305,15,305,15,289,59,275,39,305,15,275,39,271,4,271,4,275,39,253,27,271,4,253,27,231,0,231,0,253,27,226,21,231,0,226,21,195,19,195,19,185,20,231,0,231,0,185,20,178,22,231,0,178,22,119,37,119,37,178,22,120,56,299,170,294,89,305,15,299,170,305,15,327,153,327,153,305,15,330,34,327,153,330,34,345,126,345,126,330,34,346,59,345,126,346,59,352,91,299,170,262,180,276,141,299,170,276,141,289,120,299,170,289,120,294,89,120,56,178,22,174,26,120,56,174,26,171,33,120,56,171,33,120,310,231,0,72,9,72,0,114,24,231,0,119,37, 432,0,432,9,414,12,401,17,393,25,389,38,388,57,388,274,389,294,393,307,401,315,414,319,432,321,432,331,292,331,292,321,312,319,325,315,332,307,336,294,337,274,337,61,336,39,333,25,325,16,312,12,292,9,292,0,16383,16383,108,183,108,274,110,293,115,307,123,315,137,319,156,321,156,331,9,331,9,321,30,320,44,316,52,308,56,295,57,275,57,56,56,37,52,24,43,16,30,11,9,9,9,0,170,0,210,4,244,15,268,34,284,59,290,91,283,126,265,153,238,170,201,180,158,183,16383,16383,108,163,142,163,170,161,194,154,214,141,227,120,232,89,227,59,214,39,193,27,166,21,134,19,123,20,115,22,111,26,109,33,108,41, 432,321,432,321,414,319,414,319,432,321,432,331,414,319,432,331,401,315,401,315,432,331,336,294,401,315,336,294,337,274,389,38,337,274,337,61,389,38,337,61,393,25,393,25,337,61,401,17,388,57,388,274,337,274,337,274,388,274,389,294,337,274,389,294,393,307,432,331,292,331,312,319,432,331,312,319,325,315,432,331,325,315,332,307,432,331,332,307,336,294,432,0,432,9,414,12,432,0,414,12,401,17,432,0,401,17,336,39,432,0,336,39,333,25,432,0,333,25,325,16,432,0,325,16,312,12,432,0,312,12,292,9,432,0,292,9,292,0,52,24,43,16,170,0,170,0,43,16,30,11,170,0,30,11,9,9,156,331,9,331,30,320,156,331,30,320,44,316,156,331,44,316,52,308,156,331,52,308,56,295,156,331,56,295,123,315,156,331,123,315,137,319,156,331,137,319,156,321,57,275,109,33,108,41,108,183,108,163,142,163,108,183,142,163,158,183,158,183,142,163,170,161,158,183,170,161,201,180,201,180,170,161,194,154,201,180,194,154,214,141,57,275,108,41,108,274,57,275,108,274,110,293,57,275,110,293,115,307,57,275,115,307,123,315,57,275,123,315,56,295,232,89,227,59,244,15,244,15,227,59,214,39,244,15,214,39,210,4,210,4,214,39,193,27,210,4,193,27,170,0,170,0,193,27,166,21,170,0,166,21,134,19,134,19,123,20,170,0,170,0,123,20,115,22,170,0,115,22,56,37,56,37,115,22,57,56,238,170,232,89,244,15,238,170,244,15,265,153,265,153,244,15,268,34,265,153,268,34,283,126,283,126,268,34,284,59,283,126,284,59,290,91,238,170,201,180,214,141,238,170,214,141,227,120,238,170,227,120,232,89,57,56,115,22,111,26,57,56,111,26,109,33,57,56,109,33,57,275,170,0,9,9,9,0,52,24,170,0,56,37,30,320,9,331,9,321,336,39,401,17,337,61,337,274,389,38,388,57,312,319,292,331,292,321,401,315,337,274,393,307, 108,183,108,274,110,293,115,307,123,315,137,319,156,321,156,331,9,331,9,321,30,320,44,316,52,308,56,295,57,275,57,56,56,37,52,24,43,16,30,11,9,9,9,0,170,0,210,4,243,15,268,34,284,59,289,91,283,126,265,153,237,170,201,180,158,183,16383,16383,108,163,142,163,170,161,194,154,214,141,227,120,232,89,227,59,213,39,193,27,166,21,134,19,123,20,115,22,111,26,109,33,108,41, 52,24,43,16,170,0,170,0,43,16,30,11,170,0,30,11,9,9,156,331,9,331,30,320,156,331,30,320,44,316,156,331,44,316,52,308,156,331,52,308,56,295,156,331,56,295,123,315,156,331,123,315,137,319,156,331,137,319,156,321,57,275,109,33,108,41,108,183,108,163,142,163,108,183,142,163,158,183,158,183,142,163,170,161,158,183,170,161,201,180,201,180,170,161,194,154,201,180,194,154,214,141,57,275,108,41,108,274,57,275,108,274,110,293,57,275,110,293,115,307,57,275,115,307,123,315,57,275,123,315,56,295,57,56,56,37,115,22,115,22,56,37,170,0,115,22,170,0,123,20,123,20,170,0,134,19,166,21,134,19,170,0,166,21,170,0,193,27,193,27,170,0,210,4,193,27,210,4,213,39,213,39,210,4,243,15,213,39,243,15,227,59,227,59,243,15,232,89,237,170,232,89,243,15,237,170,243,15,265,153,265,153,243,15,268,34,265,153,268,34,283,126,283,126,268,34,284,59,283,126,284,59,289,91,237,170,201,180,214,141,237,170,214,141,227,120,237,170,227,120,232,89,57,56,115,22,111,26,57,56,111,26,109,33,57,56,109,33,57,275,170,0,9,9,9,0,52,24,170,0,56,37,30,320,9,331,9,321, 26,338,23,224,36,224,39,239,42,252,46,263,51,272,57,280,71,293,85,304,101,311,118,316,136,318,173,312,203,293,226,265,241,228,248,184,103,184,103,161,248,161,248,142,246,124,242,108,237,92,231,78,218,57,201,39,181,26,158,18,131,15,107,17,86,23,65,32,45,46,25,65,15,55,33,33,55,16,80,3,109,-4,141,-6,168,-4,194,0,218,9,240,22,258,37,275,57,288,79,298,104,304,131,306,160,305,188,299,215,290,240,278,263,263,284,244,304,222,319,198,330,173,336,147,338,136,338,124,337,113,336,101,333,90,330,83,328,75,326,61,322,55,321,50,322,45,324,41,328,38,332,36,338, 36,338,36,338,38,332,38,332,36,338,39,239,38,332,39,239,41,328,41,328,39,239,42,252,41,328,42,252,45,324,45,324,42,252,46,263,45,324,46,263,50,322,50,322,46,263,51,272,50,322,51,272,55,321,55,321,51,272,57,280,55,321,57,280,61,322,36,224,39,239,36,338,36,224,36,338,26,338,36,224,26,338,23,224,75,326,68,324,71,293,71,293,68,324,61,322,71,293,61,322,57,280,90,330,83,328,85,304,90,330,85,304,101,311,90,330,101,311,101,333,75,326,71,293,85,304,75,326,85,304,83,328,248,142,246,124,258,37,258,37,246,124,242,108,258,37,242,108,240,22,240,22,242,108,237,92,240,22,237,92,231,78,231,78,218,57,218,9,218,9,218,57,201,39,218,9,201,39,194,0,194,0,201,39,181,26,194,0,181,26,168,-4,168,-4,181,26,158,18,168,-4,158,18,141,-6,141,-6,158,18,131,15,131,15,107,17,109,-4,109,-4,107,17,86,23,109,-4,86,23,80,3,80,3,86,23,65,32,80,3,65,32,55,16,55,16,65,32,45,46,55,16,45,46,33,33,33,33,45,46,25,65,33,33,25,65,15,55,136,318,136,338,124,337,136,318,124,337,118,316,136,318,147,338,136,338,118,316,124,337,113,336,118,316,113,336,101,333,118,316,101,333,101,311,306,160,305,188,304,131,304,131,305,188,299,215,304,131,299,215,298,104,298,104,299,215,290,240,298,104,290,240,288,79,288,79,290,240,278,263,288,79,278,263,275,57,275,57,278,263,263,284,275,57,263,284,258,37,258,37,263,284,248,161,258,37,248,161,248,142,263,284,248,184,248,161,248,161,248,184,103,184,244,304,222,319,226,265,244,304,226,265,241,228,244,304,241,228,248,184,244,304,248,184,263,284,203,293,226,265,222,319,203,293,222,319,198,330,203,293,198,330,173,336,203,293,173,336,173,312,173,312,173,336,147,338,173,312,147,338,136,318,231,78,218,9,240,22,141,-6,131,15,109,-4,248,161,103,184,103,161, 105,180,105,274,106,294,110,307,118,315,130,319,149,321,149,331,9,331,9,321,29,319,42,315,50,307,53,294,54,274,54,61,53,39,50,25,42,16,29,12,9,9,9,0,149,0,149,9,130,12,118,17,110,25,106,38,105,56,105,157,149,157,157,102,177,57,207,22,245,0,291,-6,337,1,376,24,405,60,425,108,431,166,425,222,406,269,377,306,338,330,291,338,245,331,207,310,178,276,158,232,149,180,16383,16383,377,169,376,134,373,103,367,76,359,53,347,35,337,26,327,19,315,15,303,12,291,11,279,12,268,15,257,19,247,25,237,33,224,52,214,75,208,102,204,132,203,166,204,194,207,222,211,247,219,269,228,286,239,299,251,308,263,315,276,318,290,320,302,319,313,316,324,311,334,305,343,296,356,279,366,257,372,231,376,201,377,169, 50,25,42,16,149,0,149,0,42,16,29,12,149,0,29,12,9,9,149,331,9,331,29,319,149,331,29,319,42,315,149,331,42,315,50,307,149,331,50,307,53,294,149,331,53,294,118,315,149,331,118,315,130,319,149,331,130,319,149,321,158,232,149,180,149,157,149,157,149,180,105,180,149,157,105,180,105,157,106,38,105,56,54,274,106,38,54,274,54,61,54,274,105,56,105,274,54,274,105,274,106,294,54,274,106,294,110,307,54,274,110,307,118,315,54,274,118,315,53,294,149,0,149,9,130,12,149,0,130,12,118,17,149,0,118,17,53,39,149,0,53,39,50,25,54,61,53,39,118,17,54,61,118,17,110,25,54,61,110,25,106,38,263,315,291,338,251,308,251,308,291,338,245,331,251,308,245,331,239,299,239,299,245,331,228,286,219,269,228,286,245,331,219,269,245,331,207,310,208,102,207,22,214,75,214,75,207,22,245,0,214,75,245,0,224,52,224,52,245,0,237,33,247,25,237,33,245,0,247,25,245,0,291,-6,338,330,291,338,302,319,302,319,291,338,290,320,276,318,290,320,291,338,276,318,291,338,263,315,207,310,178,276,203,166,207,310,203,166,204,194,207,310,204,194,207,222,207,310,207,222,211,247,207,310,211,247,219,269,208,102,204,132,207,22,207,22,204,132,203,166,268,15,291,-6,279,12,279,12,291,-6,291,11,303,12,291,11,291,-6,303,12,291,-6,337,1,313,316,324,311,338,330,338,330,324,311,334,305,338,330,334,305,343,296,343,296,356,279,377,306,377,306,356,279,366,257,377,306,366,257,372,231,373,103,367,76,376,24,376,24,367,76,359,53,376,24,359,53,347,35,347,35,337,26,376,24,376,24,337,26,337,1,431,166,425,222,425,108,425,108,425,222,406,269,425,108,406,269,405,60,405,60,406,269,377,169,377,306,372,231,376,201,377,306,376,201,377,169,377,306,377,169,406,269,377,306,338,330,343,296,376,134,373,103,376,24,376,134,376,24,405,60,376,134,405,60,377,169,337,1,337,26,327,19,337,1,327,19,315,15,337,1,315,15,303,12,257,19,247,25,291,-6,257,19,291,-6,268,15,149,157,157,102,158,232,158,232,157,102,177,57,158,232,177,57,178,276,178,276,177,57,207,22,178,276,207,22,203,166,338,330,302,319,313,316,149,0,9,9,9,0,29,319,9,331,9,321, 309,0,309,9,290,12,277,16,270,25,267,39,267,276,268,294,271,307,278,315,290,319,309,321,309,331,180,331,136,329,98,321,69,306,49,282,42,246,47,216,60,193,81,176,108,164,141,157,49,35,41,26,31,19,22,14,12,11,2,9,2,0,83,0,198,155,216,155,216,56,215,37,211,24,203,16,189,12,169,9,169,0,16383,16383,216,174,186,174,156,177,131,186,113,200,101,219,97,244,99,261,103,276,111,288,121,298,133,305,143,308,153,310,164,311,177,312,190,312,200,311,207,309,212,304,215,296,216,286, 31,19,22,14,83,0,83,0,22,14,12,11,83,0,12,11,2,9,99,261,103,276,98,321,98,321,103,276,111,288,98,321,111,288,136,329,136,329,111,288,121,298,136,329,121,298,133,305,133,305,143,308,136,329,136,329,143,308,180,331,101,219,97,244,108,164,108,164,97,244,81,176,81,176,97,244,98,321,98,321,97,244,99,261,42,246,47,216,49,282,49,282,47,216,60,193,49,282,60,193,69,306,69,306,60,193,81,176,69,306,81,176,98,321,141,157,83,0,198,155,141,157,198,155,156,177,141,157,156,177,131,186,141,157,131,186,113,200,141,157,113,200,108,164,211,24,203,16,309,0,309,0,203,16,189,12,309,0,189,12,169,9,153,310,164,311,180,331,180,331,164,311,177,312,180,331,177,312,190,312,190,312,200,311,309,331,309,331,200,311,207,309,309,331,207,309,212,304,211,24,309,0,215,37,215,37,309,0,277,16,215,37,277,16,216,56,216,56,277,16,270,25,216,56,270,25,216,155,216,155,270,25,216,174,216,155,216,174,198,155,198,155,216,174,186,174,198,155,186,174,156,177,83,0,141,157,49,35,83,0,49,35,41,26,83,0,41,26,31,19,290,319,309,321,309,331,290,319,309,331,278,315,278,315,309,331,216,286,278,315,216,286,271,307,271,307,216,286,268,294,216,286,267,39,267,61,267,276,268,294,216,286,267,276,216,286,267,61,309,331,212,304,215,296,309,331,215,296,216,286,309,331,180,331,190,312,290,12,277,16,309,0,290,12,309,0,309,9,216,174,270,25,267,39,216,174,267,39,216,286,309,0,169,9,169,0,83,0,2,9,2,0,180,331,143,308,153,310,101,219,108,164,113,200, 223,33,218,29,210,25,206,24,201,23,196,25,192,28,189,35,187,44,186,56,186,152,185,168,184,181,181,191,176,199,170,208,162,215,152,222,140,226,127,229,111,230,98,229,85,227,73,224,63,220,54,215,44,208,37,200,32,192,29,183,28,175,29,167,33,161,37,156,43,153,50,152,57,153,63,156,68,161,71,167,73,172,72,178,72,182,71,185,70,189,70,194,71,201,76,207,83,212,93,215,104,217,117,215,129,210,138,202,144,190,146,173,146,146,116,135,93,126,76,118,63,112,54,105,42,97,33,87,25,75,20,62,18,47,21,29,28,14,39,4,54,-2,71,-4,84,-3,99,0,114,6,130,16,146,31,149,17,153,7,160,0,168,-3,178,-4,188,-3,197,-1,206,2,214,9,223,19,16383,16383,146,65,145,57,144,50,140,44,135,38,128,32,122,29,110,25,103,24,97,24,86,25,76,30,69,38,64,48,63,63,63,71,65,78,68,84,73,91,79,97,88,104,99,111,112,118,128,125,146,132, 37,156,43,153,44,208,44,208,43,153,50,152,44,208,50,152,54,215,54,215,50,152,57,153,54,215,57,153,63,220,63,220,57,153,63,156,63,220,63,156,73,224,73,224,63,156,70,194,71,167,70,194,68,161,111,230,104,217,117,215,111,230,117,215,127,229,127,229,117,215,129,210,127,229,129,210,140,226,140,226,129,210,138,202,140,226,138,202,144,190,76,207,83,212,85,227,85,227,83,212,93,215,85,227,93,215,98,229,98,229,93,215,104,217,98,229,104,217,111,230,73,224,70,194,71,201,73,224,71,201,76,207,73,224,76,207,85,227,70,194,63,156,68,161,29,183,29,167,32,192,32,192,29,167,33,161,32,192,33,161,37,200,37,200,33,161,37,156,37,200,37,156,44,208,186,56,186,152,185,168,186,56,185,168,184,181,186,56,184,181,181,191,186,56,181,191,188,-3,192,28,197,-1,196,25,196,25,197,-1,201,23,206,24,201,23,206,2,206,24,206,2,214,9,189,35,187,44,188,-3,189,35,188,-3,197,-1,189,35,197,-1,192,28,178,-4,188,-3,181,191,178,-4,181,191,176,199,178,-4,176,199,170,208,178,-4,170,208,168,-3,162,215,152,222,153,7,162,215,153,7,160,0,162,215,160,0,168,-3,162,215,168,-3,170,208,152,222,140,226,144,190,152,222,144,190,146,173,152,222,146,173,146,132,152,222,146,132,146,31,152,222,146,31,149,17,152,222,149,17,153,7,146,146,146,132,146,173,218,29,214,27,214,9,218,29,214,9,223,19,218,29,223,19,223,33,210,25,206,24,214,9,210,25,214,9,214,27,201,23,197,-1,206,2,146,31,146,132,146,65,146,31,146,65,145,57,146,31,145,57,144,50,146,31,144,50,140,44,146,31,140,44,135,38,146,31,135,38,130,16,130,16,135,38,128,32,128,32,122,29,130,16,130,16,122,29,116,27,130,16,116,27,114,6,114,6,116,27,110,25,114,6,110,25,103,24,99,111,112,118,116,135,116,135,112,118,128,125,116,135,128,125,146,146,146,146,128,125,146,132,65,78,68,84,76,118,76,118,68,84,73,91,76,118,73,91,79,97,79,97,88,104,93,126,93,126,88,104,99,111,93,126,99,111,116,135,93,126,76,118,79,97,72,182,71,185,71,167,72,182,71,167,73,172,72,182,73,172,72,178,70,189,70,194,71,167,70,189,71,167,71,185,63,112,54,105,54,-2,63,112,54,-2,63,63,63,112,63,63,63,71,63,112,63,71,65,78,63,112,65,78,76,118,63,63,54,-2,64,48,64,48,54,-2,71,-4,64,48,71,-4,69,38,69,38,71,-4,76,30,20,62,21,29,25,75,25,75,21,29,28,14,25,75,28,14,33,87,33,87,28,14,39,4,33,87,39,4,42,97,42,97,39,4,54,-2,42,97,54,-2,54,105,84,-3,99,0,86,25,86,25,99,0,97,24,103,24,97,24,99,0,103,24,99,0,114,6,76,30,71,-4,84,-3,76,30,84,-3,86,25,21,29,20,62,18,47,186,56,188,-3,187,44,29,167,29,183,28,175, 42,174,47,203,59,230,77,253,100,270,129,278,142,279,169,279,182,280,194,283,210,293,220,306,226,320,229,333,230,343,220,343,217,332,212,325,205,320,195,318,183,317,150,317,94,304,57,269,34,223,23,172,20,127,24,87,36,52,57,22,87,2,127,-4,164,1,195,17,219,43,234,76,239,116,233,154,218,186,195,210,166,225,131,230,111,228,92,223,74,213,57,196,43,173,16383,16383,194,102,192,70,184,44,172,25,155,13,135,9,125,10,115,13,106,18,98,25,91,34,81,51,74,70,69,91,66,113,65,137,67,164,75,186,87,202,102,212,122,216,134,215,144,211,153,206,161,199,169,191,178,177,185,161,190,142,193,122,194,102, 169,279,183,317,156,279,156,279,183,317,150,317,156,279,150,317,142,279,142,279,150,317,129,278,100,270,129,278,150,317,100,270,150,317,94,304,229,333,230,343,226,320,226,320,230,343,220,343,226,320,220,343,220,306,220,306,220,343,217,332,220,306,217,332,212,325,210,293,220,306,212,325,210,293,212,325,205,320,210,293,205,320,195,318,210,293,195,318,194,283,169,279,182,280,183,317,183,317,182,280,194,283,183,317,194,283,195,318,42,174,47,203,57,269,57,269,47,203,59,230,57,269,59,230,94,304,94,304,59,230,77,253,94,304,77,253,100,270,42,174,57,269,34,223,42,174,34,223,36,52,42,174,36,52,57,22,42,174,57,22,43,173,24,87,36,52,34,223,24,87,34,223,23,172,24,87,23,172,20,127,74,70,87,2,81,51,81,51,87,2,91,34,98,25,91,34,87,2,98,25,87,2,127,-4,65,137,57,196,66,113,66,113,57,196,57,22,66,113,57,22,69,91,69,91,57,22,87,2,69,91,87,2,74,70,131,230,122,216,134,215,131,230,134,215,166,225,166,225,134,215,144,211,166,225,144,211,153,206,75,186,87,202,92,223,92,223,87,202,102,212,92,223,102,212,111,228,111,228,102,212,122,216,111,228,122,216,131,230,74,213,57,196,67,164,74,213,67,164,75,186,74,213,75,186,92,223,67,164,57,196,65,137,192,70,184,44,195,17,195,17,184,44,172,25,195,17,172,25,164,1,164,1,172,25,155,13,164,1,155,13,135,9,135,9,125,10,127,-4,127,-4,125,10,115,13,127,-4,115,13,106,18,185,161,195,210,178,177,178,177,195,210,169,191,161,199,169,191,166,225,161,199,166,225,153,206,195,210,194,102,195,17,195,210,195,17,218,186,218,186,195,17,219,43,218,186,219,43,233,154,233,154,219,43,234,76,233,154,234,76,239,116,195,210,185,161,190,142,195,210,190,142,193,122,195,210,193,122,194,102,195,210,166,225,169,191,135,9,127,-4,164,1,192,70,195,17,194,102,98,25,127,-4,106,18,43,173,57,22,57,196, 153,118,169,121,183,128,194,137,202,151,205,168,201,188,191,204,174,215,149,222,118,225,12,225,12,218,26,216,35,214,40,209,42,200,43,187,43,39,42,25,40,16,35,11,26,8,12,7,12,0,149,0,161,2,171,4,181,8,190,12,200,19,208,28,214,39,218,51,219,63,215,82,206,96,191,107,174,114,153,118,16383,16383,85,195,86,202,88,207,92,209,97,211,103,211,127,209,145,203,156,194,162,182,164,166,161,151,154,139,143,130,128,125,110,123,99,124,92,125,87,128,85,132,85,139,16383,16383,85,97,85,102,87,105,91,108,98,109,127,109,144,105,159,98,170,84,174,62,174,63,170,42,160,28,146,19,127,15,106,14,98,15,92,17,88,20,85,26,85,34, 40,16,35,11,137,0,137,0,35,11,26,8,137,0,26,8,12,7,86,202,88,207,43,187,43,187,88,207,92,209,43,187,92,209,118,225,118,225,92,209,97,211,118,225,97,211,103,211,103,211,127,209,118,225,118,225,127,209,149,222,159,98,170,84,174,114,174,114,170,84,174,62,174,114,174,62,174,63,174,63,174,62,181,8,181,8,174,62,171,4,171,4,174,62,170,42,171,4,170,42,161,2,161,2,170,42,160,28,161,2,160,28,149,0,149,0,160,28,146,19,149,0,146,19,137,0,137,0,146,19,127,15,137,0,127,15,106,14,106,14,98,15,137,0,137,0,98,15,92,17,137,0,92,17,42,25,42,25,92,17,43,39,127,109,110,123,109,109,98,109,109,109,99,124,98,109,99,124,92,125,85,139,85,102,85,132,85,132,85,102,87,105,85,132,87,105,87,128,87,128,87,105,91,108,87,128,91,108,92,125,92,125,91,108,98,109,110,123,99,124,109,109,161,151,169,121,164,166,164,166,169,121,174,215,174,215,169,121,183,128,174,215,183,128,191,204,191,204,183,128,194,137,191,204,194,137,201,188,201,188,194,137,202,151,201,188,202,151,205,168,127,209,145,203,149,222,149,222,145,203,156,194,149,222,156,194,174,215,174,215,156,194,162,182,174,215,162,182,164,166,159,98,153,118,144,105,144,105,153,118,154,139,154,139,153,118,169,121,154,139,169,121,161,151,110,123,127,109,128,125,128,125,127,109,144,105,128,125,144,105,143,130,143,130,144,105,154,139,215,82,206,96,208,28,215,82,208,28,214,39,215,82,214,39,218,51,215,82,218,51,219,63,181,8,190,12,191,107,191,107,190,12,200,19,191,107,200,19,206,96,206,96,200,19,208,28,191,107,174,114,174,63,191,107,174,63,181,8,85,26,85,34,43,187,85,26,43,187,43,39,85,26,43,39,88,20,85,195,86,202,43,187,85,195,43,187,85,34,35,214,40,209,118,225,118,225,40,209,42,200,118,225,42,200,43,187,26,216,35,214,118,225,26,216,118,225,12,225,26,216,12,225,12,218,137,0,12,7,12,0,40,16,137,0,42,25,43,39,92,17,88,20,153,118,159,98,174,114,85,102,85,139,85,97, 194,155,191,225,8,225,8,218,22,217,31,215,36,211,39,204,40,194,40,40,39,25,36,16,30,11,21,9,8,7,8,0,113,0,113,7,100,9,91,13,85,18,82,26,81,36,81,194,82,200,83,205,86,208,91,209,98,210,130,208,154,201,170,190,180,175,185,155, 36,211,39,204,191,225,191,225,39,204,91,209,191,225,91,209,98,210,98,210,130,208,191,225,191,225,130,208,154,201,191,225,154,201,170,190,191,225,170,190,180,175,191,225,180,175,185,155,191,225,185,155,194,155,81,36,81,194,40,194,40,194,81,194,82,200,40,194,82,200,83,205,40,194,83,205,86,208,40,194,86,208,91,209,40,194,91,209,39,204,40,194,82,26,81,36,191,225,8,225,22,217,191,225,22,217,31,215,191,225,31,215,36,211,113,0,113,7,100,9,113,0,100,9,91,13,113,0,91,13,40,40,113,0,40,40,39,25,113,0,39,25,36,16,113,0,36,16,30,11,113,0,30,11,21,9,113,0,21,9,8,7,113,0,8,7,8,0,40,40,91,13,85,18,40,40,85,18,82,26,40,40,82,26,40,194,22,217,8,225,8,218, 219,225,21,225,21,218,34,216,44,212,51,206,55,197,56,183,56,99,55,66,51,40,42,22,28,11,7,7,7,-68,16,-68,26,-37,37,-17,47,-5,58,0,172,0,182,-5,191,-17,200,-37,210,-68,219,-68,219,7,206,9,197,11,192,16,189,25,189,198,192,207,198,213,206,216,219,218,16383,16383,147,41,146,30,143,23,139,18,133,15,126,14,58,14,64,28,68,43,71,59,73,75,73,190,74,199,76,205,80,209,85,210,92,211,135,211,141,209,145,205,146,199,147,190, 34,216,44,212,219,225,219,225,44,212,85,210,219,225,85,210,92,211,219,225,92,211,127,211,219,225,127,211,135,211,126,14,58,14,68,0,126,14,68,0,161,0,126,14,161,0,133,15,147,190,161,0,189,198,189,198,161,0,172,0,189,198,172,0,189,183,189,183,172,0,182,-5,189,183,182,-5,189,41,189,41,182,-5,191,-17,189,41,191,-17,189,25,161,0,147,190,147,41,161,0,147,41,146,30,161,0,146,30,143,23,161,0,143,23,139,18,161,0,139,18,133,15,219,225,135,211,141,209,219,225,141,209,145,205,219,225,145,205,146,199,219,225,146,199,147,190,219,225,147,190,198,213,219,225,198,213,206,216,219,225,206,216,219,218,192,207,198,213,147,190,192,207,147,190,189,198,73,190,74,199,58,14,73,190,58,14,64,28,73,190,64,28,68,43,73,190,68,43,71,59,73,190,71,59,73,75,73,190,73,75,73,89,58,0,68,0,58,14,58,0,58,14,56,183,58,0,56,183,56,99,58,0,56,99,55,66,58,0,55,66,51,40,58,0,51,40,47,-5,58,14,74,199,56,183,56,183,74,199,76,205,56,183,76,205,55,197,55,197,76,205,80,209,55,197,80,209,51,206,51,206,80,209,85,210,51,206,85,210,44,212,21,225,21,218,34,216,21,225,34,216,219,225,219,-68,219,7,210,-68,210,-68,219,7,206,9,210,-68,206,9,200,-37,200,-37,206,9,197,11,200,-37,197,11,192,16,192,16,189,25,191,-17,192,16,191,-17,200,-37,16,-68,26,-37,28,11,28,11,26,-37,37,-17,28,11,37,-17,42,22,42,22,37,-17,47,-5,42,22,47,-5,51,40,7,7,7,-68,16,-68,7,7,16,-68,28,11, 210,82,196,63,182,48,167,39,150,33,132,31,102,37,80,53,66,77,58,106,55,137,209,137,208,152,205,165,202,176,197,186,192,195,181,207,169,217,156,224,140,228,123,230,88,224,59,207,37,182,24,148,19,108,23,70,35,39,55,15,81,0,114,-4,142,-1,167,9,188,26,205,49,219,79,16383,16383,56,151,61,172,69,190,80,203,93,211,109,214,126,211,139,203,148,191,154,173,158,151, 80,53,66,77,81,0,81,0,66,77,58,106,81,0,58,106,55,15,55,15,58,106,55,137,56,151,55,137,209,137,56,151,209,137,158,151,158,151,209,137,169,217,140,228,123,230,126,211,126,211,123,230,109,214,93,211,109,214,123,230,93,211,123,230,88,224,156,224,140,228,148,191,156,224,148,191,154,173,156,224,154,173,158,151,156,224,158,151,169,217,140,228,126,211,139,203,140,228,139,203,148,191,56,151,61,172,59,207,59,207,61,172,69,190,59,207,69,190,88,224,88,224,69,190,80,203,88,224,80,203,93,211,37,182,24,148,35,39,37,182,35,39,55,15,37,182,55,15,55,137,37,182,55,137,56,151,37,182,56,151,59,207,24,148,19,108,23,70,24,148,23,70,35,39,81,0,114,-4,102,37,102,37,114,-4,132,31,150,33,132,31,142,-1,150,33,142,-1,167,9,209,137,208,152,205,165,209,137,205,165,202,176,209,137,202,176,197,186,209,137,197,186,192,195,209,137,192,195,181,207,209,137,181,207,169,217,219,79,210,82,205,49,205,49,210,82,196,63,205,49,196,63,188,26,188,26,196,63,182,48,188,26,182,48,167,9,167,9,182,48,167,39,167,9,167,39,150,33,132,31,114,-4,142,-1,80,53,81,0,102,37, 353,0,353,7,347,8,341,10,331,14,327,17,323,21,317,28,311,37,304,47,298,58,286,79,275,94,264,105,253,113,240,120,240,121,258,137,269,156,278,172,286,185,297,190,301,189,306,187,318,183,324,182,332,183,338,186,343,191,346,197,347,204,346,211,342,218,336,223,327,227,316,228,306,227,297,224,289,218,282,211,275,201,267,187,259,171,251,156,242,143,233,135,228,132,222,130,215,128,208,127,200,127,200,190,201,199,204,207,210,212,219,216,232,218,232,225,128,225,128,218,140,216,149,214,154,209,158,201,158,127,151,127,144,128,138,129,132,132,127,135,117,145,108,157,101,170,88,196,82,207,75,216,67,223,56,227,44,228,34,227,26,224,20,219,15,212,14,204,15,197,18,191,23,186,29,183,36,182,43,183,50,185,60,189,65,190,74,185,80,172,87,155,100,137,121,121,121,120,107,114,95,107,85,95,74,79,62,57,63,57,56,46,50,36,44,28,38,21,33,17,29,14,25,12,19,10,14,8,7,7,7,0,73,0,124,83,133,96,139,104,145,109,151,112,158,113,158,25,155,18,151,13,145,10,137,8,126,7,126,0,234,0,234,7,214,9,207,12,203,17,201,24,200,33,200,113,209,111,216,108,222,104,228,95,237,82,287,0, 25,12,19,10,73,0,73,0,19,10,14,8,73,0,14,8,7,7,50,36,44,28,73,0,73,0,44,28,38,21,73,0,38,21,33,17,33,17,29,14,73,0,73,0,29,14,25,12,95,107,85,95,124,83,124,83,85,95,74,79,124,83,74,79,73,0,73,0,74,79,62,57,73,0,62,57,56,46,56,46,62,57,63,57,67,223,65,190,74,185,67,223,74,185,75,216,75,216,74,185,80,172,75,216,80,172,82,207,82,207,80,172,87,155,82,207,87,155,88,196,88,196,87,155,100,137,88,196,100,137,94,184,94,184,100,137,101,170,50,185,55,187,56,227,56,227,55,187,60,189,56,227,60,189,67,223,67,223,60,189,65,190,44,228,34,227,36,182,44,228,36,182,43,183,44,228,43,183,50,185,44,228,50,185,56,227,14,204,15,197,15,212,15,212,15,197,18,191,15,212,18,191,20,219,20,219,18,191,23,186,20,219,23,186,26,224,26,224,23,186,29,183,26,224,29,183,34,227,34,227,29,183,36,182,127,135,121,121,124,83,127,135,124,83,133,96,127,135,117,145,121,121,121,121,117,145,108,157,121,121,108,157,101,170,121,121,101,170,100,137,155,18,151,13,234,0,234,0,151,13,145,10,234,0,145,10,137,8,137,8,126,7,234,0,234,0,126,7,126,0,234,0,234,7,224,8,234,0,224,8,214,9,234,0,214,9,207,12,234,0,207,12,158,33,234,0,158,33,158,25,234,0,158,25,155,18,201,24,200,33,158,113,201,24,158,113,203,17,203,17,158,113,158,33,158,113,200,33,200,127,158,113,200,127,200,190,158,113,200,190,201,199,158,113,201,199,204,207,158,113,204,207,158,189,158,113,158,189,158,127,215,128,208,127,209,111,209,111,208,127,200,127,232,225,128,225,140,216,232,225,140,216,149,214,232,225,149,214,154,209,232,225,154,209,158,201,232,225,158,201,158,189,232,225,158,189,210,212,232,225,210,212,219,216,232,225,219,216,232,218,264,105,253,113,287,0,287,0,253,113,240,120,287,0,240,120,237,82,237,82,240,120,240,121,237,82,240,121,233,135,237,82,233,135,228,95,228,95,233,135,228,132,228,95,228,132,222,104,222,104,228,132,222,130,222,104,222,130,216,108,216,108,222,130,215,128,216,108,215,128,209,111,317,28,311,37,287,0,287,0,311,37,304,47,287,0,304,47,298,58,297,224,297,190,301,189,297,224,301,189,306,227,306,227,301,189,306,187,306,227,306,187,316,228,316,228,306,187,312,185,316,228,312,185,318,183,297,190,289,218,286,185,286,185,289,218,282,211,286,185,282,211,278,172,278,172,282,211,275,201,278,172,275,201,269,156,269,156,275,201,267,187,269,156,267,187,259,171,258,137,269,156,259,171,258,137,259,171,251,156,258,137,251,156,242,143,258,137,242,143,240,121,242,143,233,135,240,121,318,183,324,182,327,227,327,227,324,182,332,183,327,227,332,183,336,223,336,223,332,183,338,186,336,223,338,186,342,218,342,218,338,186,343,191,342,218,343,191,346,211,346,211,343,191,346,197,346,211,346,197,347,204,317,28,287,0,323,21,323,21,287,0,327,17,331,14,327,17,287,0,331,14,287,0,353,0,353,0,353,7,347,8,353,0,347,8,341,10,353,0,341,10,336,12,353,0,336,12,331,14,287,0,298,58,286,79,287,0,286,79,275,94,287,0,275,94,264,105,145,109,151,112,151,127,151,127,151,112,158,113,151,127,158,113,158,127,132,132,127,135,133,96,132,132,133,96,138,129,138,129,133,96,139,104,138,129,139,104,144,128,144,128,139,104,145,109,144,128,145,109,151,127,124,83,121,121,121,120,124,83,121,120,107,114,124,83,107,114,95,107,73,0,7,7,7,0,50,36,73,0,56,46,316,228,318,183,327,227,297,190,297,224,289,218,200,127,200,113,209,111,140,216,128,225,128,218,210,212,158,189,204,207,158,33,207,12,203,17, 114,121,130,126,146,134,158,146,167,160,170,177,168,188,164,198,158,207,149,215,139,221,121,227,111,229,99,230,80,230,75,229,69,228,64,226,57,224,49,222,46,220,42,219,35,219,29,223,27,226,26,230,20,230,16,150,25,150,30,172,38,190,50,204,65,213,85,216,98,214,110,209,119,200,125,188,127,172,126,163,123,155,118,147,112,140,104,135,97,132,89,129,81,128,72,127,60,127,60,113,86,111,106,106,120,96,129,82,132,62,130,47,124,34,114,23,99,15,79,13,65,14,52,18,40,24,28,33,14,46,7,39,19,23,32,11,46,2,64,-2,85,-4,113,-2,125,1,137,5,147,12,157,20,166,29,173,40,177,52,179,65,175,84,165,99,151,110,133,117,114,121, 26,230,20,230,25,150,26,230,25,150,30,172,26,230,30,172,27,226,49,222,46,220,50,204,50,204,46,220,42,219,50,204,42,219,39,219,39,219,35,219,38,190,38,190,35,219,32,221,38,190,32,221,30,172,30,172,32,221,29,223,30,172,29,223,27,226,64,-2,85,-4,65,14,65,14,85,-4,79,13,99,15,79,13,85,-4,99,15,85,-4,99,-3,85,216,80,230,75,229,85,216,75,229,69,228,85,216,69,228,65,213,85,216,86,230,80,230,65,213,69,228,64,226,65,213,64,226,57,224,65,213,57,224,53,223,65,213,53,223,50,204,39,219,38,190,50,204,81,128,86,111,89,129,89,129,86,111,106,106,89,129,106,106,97,132,97,132,106,106,104,135,112,140,104,135,106,106,112,140,106,106,114,121,114,121,106,106,120,96,114,121,120,96,133,117,133,117,120,96,129,82,133,117,129,82,132,62,86,230,98,214,99,230,99,230,98,214,110,209,99,230,110,209,111,229,111,229,110,209,119,200,111,229,119,200,121,227,121,227,119,200,125,188,121,227,125,188,130,224,130,224,125,188,127,172,130,126,127,172,126,163,126,163,123,155,130,126,130,126,123,155,118,147,130,126,118,147,114,121,114,121,118,147,112,140,170,177,168,188,167,160,167,160,168,188,164,198,167,160,164,198,158,146,158,146,164,198,158,207,158,146,158,207,149,215,146,134,158,146,149,215,146,134,149,215,139,221,146,134,139,221,130,224,146,134,130,224,130,126,85,216,98,214,86,230,133,117,132,62,137,5,133,117,137,5,151,110,151,110,137,5,147,12,151,110,147,12,157,20,175,84,165,99,166,29,175,84,166,29,173,40,175,84,173,40,177,52,175,84,177,52,179,65,165,99,151,110,157,20,165,99,157,20,166,29,130,47,124,34,125,1,130,47,125,1,137,5,130,47,137,5,132,62,114,23,99,15,99,-3,114,23,99,-3,113,-2,114,23,113,-2,125,1,114,23,125,1,124,34,72,127,60,127,86,111,72,127,86,111,81,128,14,46,19,23,28,33,28,33,19,23,32,11,28,33,32,11,40,24,40,24,32,11,46,2,40,24,46,2,52,18,52,18,46,2,64,-2,52,18,64,-2,65,14,19,23,14,46,7,39,86,111,60,127,60,113,130,224,127,172,130,126,49,222,50,204,53,223,25,150,20,230,16,150, 251,225,147,225,147,218,160,216,169,213,174,207,177,200,178,189,84,60,84,189,85,199,88,207,93,212,102,216,116,218,116,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,116,0,116,7,102,9,93,13,88,18,85,26,84,36,178,165,178,37,177,26,174,18,169,12,160,9,147,7,147,0,251,0,251,7,238,9,229,12,224,17,221,26,220,40,220,183,221,198,223,207,229,213,238,216,251,218, 39,16,33,11,116,0,116,0,33,11,25,9,116,0,25,9,12,7,178,189,84,60,84,36,84,36,84,189,42,183,42,183,84,189,85,199,42,183,85,199,88,207,116,225,12,225,25,216,116,225,25,216,33,212,116,225,33,212,39,206,116,225,39,206,42,197,116,225,42,197,93,212,116,225,93,212,102,216,116,225,102,216,116,218,42,183,88,207,93,212,42,183,93,212,42,197,174,18,169,12,251,0,251,0,169,12,160,9,251,0,160,9,147,7,169,213,174,207,251,225,251,225,174,207,177,200,251,225,177,200,178,189,178,189,178,165,221,26,221,26,178,165,178,37,221,26,178,37,224,17,224,17,178,37,229,12,238,216,251,218,251,225,238,216,251,225,229,213,229,213,251,225,178,189,229,213,178,189,223,207,223,207,178,189,221,198,220,40,220,183,178,189,220,40,178,189,221,26,160,216,169,213,251,225,160,216,251,225,147,225,160,216,147,225,147,218,251,0,251,7,238,9,251,0,238,9,229,12,251,0,229,12,178,37,251,0,178,37,177,26,251,0,177,26,174,18,116,0,116,7,102,9,116,0,102,9,93,13,116,0,93,13,42,40,116,0,42,40,42,25,116,0,42,25,39,16,85,26,84,36,42,183,85,26,42,183,42,40,85,26,42,40,88,18,116,0,12,7,12,0,42,40,93,13,88,18,251,0,147,7,147,0,221,198,178,189,220,183,178,189,84,36,178,165,25,216,12,225,12,218, 201,319,199,330,195,340,188,347,180,351,171,352,167,352,161,348,159,344,158,339,160,332,166,329,172,327,178,324,180,319,179,313,174,307,166,303,152,300,133,299,115,300,102,303,93,307,88,313,87,319,89,324,95,327,101,329,107,332,109,339,108,344,107,348,101,352,97,352,88,351,80,347,73,340,68,330,66,319,70,302,82,289,98,280,116,275,133,273,151,275,169,280,185,289,196,302,201,319,16383,16383,251,225,147,225,147,218,160,216,169,213,174,207,177,200,178,189,84,60,84,189,85,199,88,207,93,212,102,216,116,218,116,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,116,0,116,7,102,9,93,13,88,18,85,26,84,36,178,165,178,37,177,26,174,18,169,12,160,9,147,7,147,0,251,0,251,7,238,9,229,12,224,17,221,26,220,40,220,183,221,198,223,207,229,213,238,216,251,218, 102,303,93,307,98,280,98,280,93,307,88,313,98,280,88,313,82,289,82,289,88,313,87,319,88,351,87,319,89,324,88,351,89,324,97,352,97,352,89,324,95,327,97,352,95,327,101,329,101,352,101,329,104,350,104,350,101,329,107,332,104,350,107,332,107,348,107,348,107,332,109,339,107,348,109,339,108,344,82,289,87,319,88,351,82,289,88,351,80,347,82,289,80,347,73,340,82,289,73,340,70,302,68,330,66,319,70,302,68,330,70,302,73,340,102,303,116,275,115,300,115,300,116,275,133,299,152,300,133,299,133,273,152,300,133,273,151,275,196,302,201,319,199,330,196,302,199,330,195,340,196,302,195,340,188,347,196,302,188,347,185,289,185,289,188,347,180,319,185,289,180,319,179,313,185,289,179,313,174,307,185,289,174,307,169,280,180,351,171,352,172,327,180,351,172,327,178,324,180,351,178,324,180,319,180,351,180,319,188,347,167,352,164,350,166,329,167,352,166,329,172,327,167,352,172,327,171,352,161,348,159,344,160,332,161,348,160,332,166,329,161,348,166,329,164,350,169,280,174,307,166,303,169,280,166,303,152,300,169,280,152,300,151,275,133,299,116,275,133,273,39,16,33,11,116,0,116,0,33,11,25,9,116,0,25,9,12,7,178,189,84,60,84,36,84,36,84,189,42,183,42,183,84,189,85,199,42,183,85,199,88,207,116,225,12,225,25,216,116,225,25,216,33,212,116,225,33,212,39,206,116,225,39,206,42,197,116,225,42,197,93,212,116,225,93,212,102,216,116,225,102,216,116,218,42,183,88,207,93,212,42,183,93,212,42,197,174,18,169,12,251,0,251,0,169,12,160,9,251,0,160,9,147,7,169,213,174,207,251,225,251,225,174,207,177,200,251,225,177,200,178,189,178,189,178,165,221,26,221,26,178,165,178,37,221,26,178,37,224,17,224,17,178,37,229,12,238,216,251,218,251,225,238,216,251,225,229,213,229,213,251,225,178,189,229,213,178,189,223,207,223,207,178,189,221,198,220,40,220,183,178,189,220,40,178,189,221,26,160,216,169,213,251,225,160,216,251,225,147,225,160,216,147,225,147,218,251,0,251,7,238,9,251,0,238,9,229,12,251,0,229,12,178,37,251,0,178,37,177,26,251,0,177,26,174,18,116,0,116,7,102,9,116,0,102,9,93,13,116,0,93,13,42,40,116,0,42,40,42,25,116,0,42,25,39,16,85,26,84,36,42,183,85,26,42,183,42,40,85,26,42,40,88,18,116,0,12,7,12,0,42,40,93,13,88,18,251,0,147,7,147,0,221,198,178,189,220,183,178,189,84,36,178,165,25,216,12,225,12,218,160,332,159,344,158,339,102,303,98,280,116,275,97,352,101,329,101,352, 248,0,248,7,241,8,235,10,225,14,221,17,217,21,211,28,205,37,198,47,192,58,180,79,168,94,156,105,144,113,131,120,131,121,148,137,160,156,168,172,176,185,188,190,192,189,202,185,208,183,214,182,222,183,228,186,233,191,237,197,238,204,236,211,233,218,226,223,218,227,207,228,196,227,185,223,176,216,168,207,161,196,140,154,132,143,124,135,118,132,112,130,105,128,98,127,91,127,91,190,92,199,95,207,100,212,109,216,122,218,122,225,18,225,18,218,31,216,39,214,45,209,48,201,49,189,49,25,46,18,42,13,36,10,26,8,12,7,12,0,128,0,128,7,117,8,107,9,99,12,94,17,92,24,91,33,91,113,99,111,106,108,112,103,118,95,127,82,181,0, 46,18,42,13,128,0,128,0,42,13,36,10,128,0,36,10,26,8,26,8,12,7,128,0,128,0,12,7,12,0,128,0,128,7,117,8,128,0,117,8,107,9,128,0,107,9,99,12,128,0,99,12,49,33,128,0,49,33,49,25,128,0,49,25,46,18,91,33,91,127,49,189,91,33,49,189,92,24,49,33,99,12,94,17,49,33,94,17,92,24,49,33,92,24,49,189,91,113,99,111,91,127,91,127,91,190,49,189,49,189,91,190,92,199,49,189,92,199,95,207,122,225,18,225,31,216,122,225,31,216,39,214,122,225,39,214,45,209,122,225,45,209,48,201,122,225,48,201,49,189,122,225,49,189,100,212,122,225,100,212,109,216,122,225,109,216,122,218,106,108,112,103,112,130,112,130,112,103,118,95,112,130,118,95,118,132,118,132,118,95,124,135,132,143,124,135,127,82,105,128,98,127,99,111,105,128,99,111,106,108,105,128,106,108,112,130,127,82,124,135,118,95,202,185,207,228,197,187,197,187,207,228,196,227,197,187,196,227,192,189,192,189,196,227,188,190,176,185,188,190,185,223,176,185,185,223,176,216,147,168,148,137,154,182,154,182,148,137,160,156,154,182,160,156,161,196,161,196,160,156,168,172,161,196,168,172,168,207,168,207,168,172,176,185,168,207,176,185,176,216,156,105,144,113,181,0,181,0,144,113,131,120,181,0,131,120,127,82,127,82,131,120,131,121,127,82,131,121,132,143,132,143,131,121,148,137,132,143,148,137,140,154,140,154,148,137,147,168,208,183,214,182,218,227,218,227,214,182,222,183,218,227,222,183,226,223,226,223,222,183,228,186,226,223,228,186,233,218,233,218,228,186,233,191,233,218,233,191,236,211,236,211,233,191,237,197,236,211,237,197,238,204,207,228,202,185,208,183,207,228,208,183,218,227,196,227,185,223,188,190,211,28,181,0,217,21,217,21,181,0,221,17,225,14,221,17,181,0,225,14,181,0,248,0,248,0,248,7,241,8,248,0,241,8,235,10,248,0,235,10,230,12,248,0,230,12,225,14,181,0,211,28,205,37,181,0,205,37,198,47,181,0,198,47,192,58,181,0,192,58,180,79,181,0,180,79,168,94,181,0,168,94,156,105,91,127,99,111,98,127,31,216,18,225,18,218,100,212,49,189,95,207, 238,225,45,225,45,218,57,216,66,212,71,206,74,197,75,183,75,99,74,77,73,53,69,33,62,18,50,12,46,15,42,22,38,30,32,36,23,39,18,38,13,36,8,33,5,27,4,20,6,10,10,3,18,-1,28,-3,39,-4,64,2,79,18,88,41,91,66,92,89,92,198,94,204,98,208,103,210,110,211,154,211,159,209,163,205,165,199,165,37,164,26,161,18,156,12,147,9,134,7,134,0,238,0,238,7,225,9,216,12,211,17,208,26,207,40,207,183,208,198,211,207,216,213,225,216,238,218, 74,77,73,53,79,18,79,18,73,53,69,33,79,18,69,33,64,2,64,2,69,33,62,18,64,2,62,18,50,12,50,12,46,15,64,2,64,2,46,15,39,-4,57,216,66,212,238,225,238,225,66,212,103,210,238,225,103,210,110,211,238,225,110,211,145,211,238,225,145,211,154,211,161,18,156,12,238,0,238,0,156,12,147,9,238,0,147,9,134,7,238,225,154,211,159,209,238,225,159,209,163,205,238,225,163,205,165,199,238,225,165,199,165,190,238,225,165,190,216,213,238,225,216,213,225,216,238,225,225,216,238,218,207,40,207,183,165,190,165,190,207,183,208,198,165,190,208,198,211,207,216,12,211,17,165,37,165,37,211,17,208,26,165,37,208,26,165,190,92,189,92,198,75,183,92,189,75,183,79,18,92,189,79,18,88,41,92,189,88,41,91,66,92,189,91,66,92,89,75,183,92,198,94,204,75,183,94,204,98,208,75,183,98,208,74,197,71,206,74,197,98,208,71,206,98,208,103,210,71,206,103,210,66,212,45,225,45,218,57,216,45,225,57,216,238,225,238,0,238,7,225,9,238,0,225,9,216,12,238,0,216,12,165,37,238,0,165,37,164,26,238,0,164,26,161,18,75,99,74,77,79,18,75,99,79,18,75,183,39,-4,46,15,42,22,39,-4,42,22,38,30,39,-4,38,30,32,36,39,-4,32,36,28,-3,32,36,23,39,28,-3,28,-3,23,39,18,38,28,-3,18,38,18,-1,18,-1,18,38,13,36,18,-1,13,36,10,3,10,3,13,36,8,33,10,3,8,33,6,10,6,10,8,33,5,27,6,10,5,27,4,20,238,0,134,7,134,0,165,190,208,26,207,40,216,213,165,190,211,207, 297,225,229,225,157,62,79,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,92,0,92,7,78,9,69,12,63,18,60,26,59,36,59,172,60,172,143,0,147,0,224,174,224,37,223,26,220,18,214,12,204,9,190,7,190,0,296,0,296,7,284,9,275,12,270,17,267,26,266,40,266,183,267,198,270,207,275,213,284,216,297,218, 39,16,33,11,92,0,92,0,33,11,25,9,92,0,25,9,12,7,220,18,214,12,296,0,296,0,214,12,204,9,296,0,204,9,190,7,229,225,157,62,224,174,229,225,224,174,267,26,229,225,267,26,266,40,229,225,266,40,266,183,229,225,266,183,267,198,229,225,267,198,270,207,229,225,270,207,275,213,229,225,275,213,297,225,59,172,60,172,79,225,79,225,60,172,143,0,79,225,143,0,157,62,157,62,143,0,147,0,157,62,147,0,224,174,92,7,78,9,92,0,92,0,78,9,69,12,92,0,69,12,42,25,42,25,69,12,63,18,42,25,63,18,42,40,42,40,63,18,60,26,42,40,60,26,42,183,42,183,60,26,59,36,42,183,59,36,59,172,79,225,12,225,25,216,79,225,25,216,33,212,79,225,33,212,39,206,79,225,39,206,42,197,79,225,42,197,42,183,79,225,42,183,59,172,284,216,297,218,297,225,284,216,297,225,275,213,296,0,296,7,284,9,296,0,284,9,275,12,296,0,275,12,224,37,296,0,224,37,223,26,296,0,223,26,220,18,224,37,275,12,270,17,224,37,270,17,267,26,224,37,267,26,224,174,92,0,12,7,12,0,39,16,92,0,42,25,296,0,190,7,190,0,25,216,12,225,12,218, 251,225,147,225,147,218,160,216,169,213,174,207,177,200,178,189,178,124,84,124,84,189,85,199,88,207,93,212,102,216,116,218,116,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,116,0,116,7,102,9,93,13,88,18,85,26,84,36,84,108,178,108,178,37,177,26,174,18,169,12,160,9,147,7,147,0,251,0,251,7,238,9,229,12,224,17,221,26,220,40,220,183,221,198,223,207,229,213,238,216,251,218, 39,16,33,11,116,0,116,0,33,11,25,9,116,0,25,9,12,7,116,225,12,225,25,216,116,225,25,216,33,212,116,225,33,212,39,206,116,225,39,206,42,197,116,225,42,197,93,212,116,225,93,212,102,216,116,225,102,216,116,218,42,183,85,26,84,36,84,124,84,108,178,108,84,124,178,108,178,124,178,124,178,108,224,17,178,124,224,17,221,26,42,183,84,36,84,189,42,183,84,189,85,199,42,183,85,199,88,207,42,183,88,207,93,212,42,183,93,212,42,197,174,18,169,12,251,0,251,0,169,12,160,9,251,0,160,9,147,7,251,225,147,225,160,216,251,225,160,216,169,213,251,225,169,213,174,207,251,225,174,207,177,200,251,225,177,200,178,189,251,225,178,189,229,213,251,225,229,213,238,216,251,225,238,216,251,218,220,40,220,183,178,189,178,189,220,183,221,198,178,189,221,198,223,207,178,189,221,26,220,40,251,0,251,7,238,9,251,0,238,9,229,12,251,0,229,12,178,37,251,0,178,37,177,26,251,0,177,26,174,18,178,37,229,12,224,17,178,37,224,17,178,108,116,0,116,7,102,9,116,0,102,9,93,13,116,0,93,13,42,40,116,0,42,40,42,25,116,0,42,25,39,16,42,40,93,13,88,18,42,40,88,18,85,26,42,40,85,26,42,183,116,0,12,7,12,0,251,0,147,7,147,0,178,124,221,26,178,189,160,216,147,225,147,218,229,213,178,189,223,207,25,216,12,225,12,218, 238,116,232,154,217,186,194,210,165,225,130,230,92,225,61,209,38,185,23,153,17,114,23,75,38,42,61,17,91,1,126,-4,163,1,194,17,218,43,233,76,238,116,16383,16383,193,102,190,70,183,44,171,25,154,13,134,9,123,10,114,13,104,18,96,25,89,34,79,51,72,70,66,91,63,113,63,137,65,164,73,186,85,202,101,212,121,216,132,215,143,211,152,206,161,199,168,191,177,177,184,161,189,142,192,122,193,102, 66,91,61,17,72,70,72,70,61,17,91,1,72,70,91,1,79,51,79,51,91,1,89,34,96,25,89,34,91,1,96,25,91,1,126,-4,165,225,130,230,132,215,132,215,130,230,121,216,101,212,121,216,130,230,101,212,130,230,92,225,190,70,183,44,194,17,194,17,183,44,171,25,194,17,171,25,163,1,163,1,171,25,154,13,163,1,154,13,134,9,134,9,123,10,126,-4,126,-4,123,10,114,13,126,-4,114,13,104,18,143,211,152,206,165,225,165,225,152,206,161,199,165,225,161,199,168,191,168,191,177,177,194,210,194,210,177,177,184,161,194,210,184,161,189,142,194,210,193,102,194,17,194,210,194,17,217,186,217,186,194,17,218,43,217,186,218,43,232,154,232,154,218,43,233,76,232,154,233,76,238,116,194,210,189,142,192,122,194,210,192,122,193,102,194,210,165,225,168,191,134,9,126,-4,163,1,61,17,63,113,63,137,63,137,65,164,61,209,61,209,65,164,73,186,61,209,73,186,92,225,92,225,73,186,85,202,92,225,85,202,101,212,61,17,63,137,61,209,61,17,61,209,38,42,38,42,61,209,38,185,38,42,38,185,23,75,23,75,38,185,23,153,23,75,23,153,17,114,63,113,61,17,66,91,190,70,194,17,193,102,165,225,132,215,143,211,96,25,126,-4,104,18, 251,225,12,225,12,218,25,217,33,214,39,209,42,200,42,26,39,17,33,12,25,9,12,7,12,0,116,0,116,7,102,9,93,13,88,18,85,26,84,36,84,186,85,196,88,203,92,208,98,210,105,211,156,211,163,210,169,208,174,203,177,196,178,186,178,37,177,26,175,18,170,12,161,9,148,7,148,0,251,0,251,7,238,9,229,11,224,16,221,24,220,37,220,184,221,199,224,209,230,214,238,217,251,218, 39,17,33,12,116,0,116,0,33,12,25,9,116,0,25,9,12,7,156,211,251,225,105,211,98,210,105,211,39,209,98,210,39,209,42,200,175,18,170,12,251,0,251,0,170,12,161,9,251,0,161,9,148,7,238,217,251,218,251,225,238,217,251,225,230,214,230,214,251,225,177,196,230,214,177,196,178,186,221,24,178,186,178,37,221,24,178,37,224,16,224,16,178,37,229,11,220,37,220,184,178,186,178,186,220,184,221,199,178,186,221,199,224,209,251,225,156,211,163,210,251,225,163,210,169,208,251,225,169,208,174,203,251,225,174,203,177,196,93,13,88,18,42,39,42,39,88,18,85,26,42,39,85,26,42,185,42,185,85,26,84,36,42,185,84,36,84,186,42,185,84,186,85,196,42,185,85,196,88,203,42,185,88,203,92,208,42,185,92,208,42,200,251,225,12,225,25,217,251,225,25,217,33,214,251,225,33,214,39,209,251,225,39,209,105,211,251,0,251,7,238,9,251,0,238,9,229,11,251,0,229,11,178,37,251,0,178,37,177,26,251,0,177,26,175,18,116,0,116,7,102,9,116,0,102,9,93,13,116,0,93,13,42,39,116,0,42,39,42,26,116,0,42,26,39,17,116,0,12,7,12,0,251,0,148,7,148,0,178,186,221,24,220,37,25,217,12,225,12,218,98,210,42,200,92,208,230,214,178,186,224,209, 76,229,73,230,58,224,44,219,31,214,17,209,1,204,1,196,4,197,13,197,22,196,28,194,32,189,34,180,34,-65,33,-79,30,-88,24,-94,14,-98,0,-100,0,-107,120,-107,120,-100,101,-99,88,-95,81,-89,77,-78,76,-62,76,17,86,8,96,2,107,-1,117,-3,129,-4,163,1,191,19,213,47,227,82,232,123,228,158,216,188,198,210,175,225,148,230,132,228,117,224,103,216,89,205,76,190,16383,16383,76,167,79,176,87,185,99,193,113,198,127,200,148,195,165,183,178,163,186,136,189,103,186,73,178,47,165,27,148,14,128,10,113,12,99,18,87,26,79,35,76,44, 30,-88,24,-94,120,-107,120,-107,24,-94,14,-98,120,-107,14,-98,0,-100,6,197,8,197,17,209,17,209,8,197,11,197,17,209,11,197,13,197,13,197,22,196,17,209,17,209,22,196,31,214,17,209,1,204,4,197,17,209,4,197,6,197,79,35,76,44,86,8,86,8,76,44,76,17,77,-78,76,-62,44,219,77,-78,44,219,34,169,34,169,44,219,34,180,22,196,28,194,31,214,31,214,28,194,32,189,31,214,32,189,44,219,44,219,32,189,34,180,76,190,76,229,73,230,76,190,73,230,76,-62,76,190,76,-62,76,167,76,190,76,167,79,176,76,190,79,176,89,205,232,123,228,158,227,82,227,82,228,158,216,188,227,82,216,188,213,47,213,47,216,188,198,210,213,47,198,210,191,19,191,19,198,210,189,103,191,19,189,103,186,73,191,19,186,73,178,47,198,210,175,225,178,163,198,210,178,163,186,136,198,210,186,136,189,103,132,228,127,200,148,195,132,228,148,195,148,230,148,230,148,195,165,183,148,230,165,183,175,225,175,225,165,183,178,163,128,10,129,-4,148,14,148,14,129,-4,163,1,148,14,163,1,165,27,165,27,163,1,191,19,165,27,191,19,178,47,120,-107,120,-100,101,-99,120,-107,101,-99,88,-95,120,-107,88,-95,33,-79,120,-107,33,-79,30,-88,58,224,44,219,76,-62,58,224,76,-62,73,230,34,-65,33,-79,88,-95,34,-65,88,-95,81,-89,34,-65,81,-89,77,-78,34,-65,77,-78,34,169,79,176,87,185,89,205,89,205,87,185,99,193,89,205,99,193,103,216,103,216,99,193,113,198,103,216,113,198,117,224,117,224,113,198,127,200,117,224,127,200,132,228,113,12,99,18,107,-1,113,12,107,-1,117,-3,113,12,117,-3,128,10,79,35,86,8,87,26,87,26,86,8,96,2,87,26,96,2,99,18,99,18,96,2,107,-1,129,-4,128,10,117,-3,4,197,1,204,1,196,120,-107,0,-100,0,-107, 207,78,193,60,180,46,167,38,153,33,137,31,111,36,89,49,73,69,63,96,59,128,62,157,71,182,86,200,105,212,127,216,137,215,144,212,149,208,153,201,156,191,160,180,163,172,167,166,171,161,177,158,184,157,191,158,197,161,202,166,206,172,207,179,203,195,192,209,175,220,154,227,130,230,116,229,102,226,88,221,75,213,62,204,63,204,48,189,36,172,28,152,22,130,21,106,25,70,38,39,58,15,84,0,116,-4,128,-3,140,-1,152,3,163,9,173,16,182,24,189,32,197,43,205,57,214,74, 89,49,73,69,84,0,84,0,73,69,63,96,84,0,63,96,58,15,58,15,63,96,59,128,63,204,59,128,62,157,63,204,62,157,71,182,137,31,116,-4,128,-3,137,31,128,-3,140,-1,137,31,111,36,116,-4,89,49,84,0,116,-4,89,49,116,-4,111,36,203,195,192,209,197,161,203,195,197,161,202,166,203,195,202,166,206,172,203,195,206,172,207,179,192,209,175,220,177,158,192,209,177,158,184,157,192,209,184,157,191,158,192,209,191,158,197,161,175,220,154,227,156,191,175,220,156,191,160,180,175,220,160,180,163,172,175,220,163,172,167,166,175,220,167,166,171,161,175,220,171,161,177,158,144,212,149,208,154,227,154,227,149,208,153,201,154,227,153,201,156,191,130,230,127,216,137,215,130,230,137,215,154,227,154,227,137,215,144,212,182,24,189,32,193,60,193,60,189,32,197,43,193,60,197,43,207,78,207,78,197,43,205,57,207,78,205,57,214,74,140,-1,152,3,153,33,153,33,152,3,163,9,153,33,163,9,167,38,167,38,163,9,173,16,167,38,173,16,180,46,180,46,173,16,182,24,180,46,182,24,193,60,153,33,137,31,140,-1,105,212,127,216,116,229,105,212,116,229,102,226,105,212,102,226,88,221,105,212,88,221,86,200,75,213,63,204,71,182,75,213,71,182,86,200,75,213,86,200,88,221,48,189,36,172,38,39,48,189,38,39,58,15,48,189,58,15,59,128,48,189,59,128,63,204,28,152,22,130,25,70,28,152,25,70,38,39,28,152,38,39,36,172,127,216,130,230,116,229,25,70,22,130,21,106, 213,155,210,225,7,225,4,155,12,155,17,175,24,191,35,202,50,209,70,211,77,211,82,209,85,207,87,202,88,195,88,40,87,25,84,16,78,11,69,9,56,7,56,0,161,0,161,7,148,9,139,13,133,18,130,26,129,36,129,195,130,201,131,206,134,209,139,210,146,211,166,209,182,202,192,191,200,175,204,155, 84,16,78,11,161,0,161,0,78,11,69,9,161,0,69,9,56,7,24,191,35,202,7,225,7,225,35,202,50,209,7,225,50,209,70,211,70,211,77,211,210,225,210,225,77,211,82,209,210,225,82,209,85,207,85,207,87,202,210,225,210,225,87,202,139,210,210,225,139,210,146,211,146,211,166,209,210,225,210,225,166,209,182,202,210,225,182,202,192,191,210,225,192,191,200,175,210,225,200,175,204,155,210,225,204,155,213,155,129,36,129,195,88,195,88,195,129,195,130,201,88,195,130,201,131,206,88,195,131,206,134,209,88,195,134,209,139,210,88,195,139,210,87,202,88,195,130,26,129,36,210,225,7,225,70,211,7,225,4,155,12,155,7,225,12,155,17,175,7,225,17,175,24,191,161,0,161,7,148,9,161,0,148,9,139,13,161,0,139,13,88,40,161,0,88,40,87,25,161,0,87,25,84,16,88,40,139,13,133,18,88,40,133,18,130,26,88,40,130,26,88,195,161,0,56,7,56,0, 242,225,175,225,175,218,184,217,190,216,195,213,198,210,199,205,199,201,198,198,198,195,197,193,145,55,84,184,83,188,79,196,78,201,78,204,79,209,82,212,87,215,95,217,107,218,107,225,4,225,4,218,11,217,23,211,27,206,31,200,99,59,105,47,111,34,116,22,120,13,122,6,119,-5,111,-24,100,-44,88,-60,75,-66,70,-66,64,-64,60,-63,55,-60,49,-58,39,-56,33,-56,27,-57,21,-60,16,-65,13,-72,12,-79,14,-88,18,-96,26,-102,35,-106,47,-108,68,-105,86,-94,102,-76,118,-48,134,-11,217,192,221,202,225,208,230,213,235,216,242,218, 67,-65,68,-105,70,-66,70,-66,68,-105,86,-94,70,-66,86,-94,73,-66,73,-66,86,-94,75,-66,88,-60,75,-66,86,-94,88,-60,86,-94,102,-76,31,200,78,201,78,204,78,204,79,209,31,200,31,200,79,209,82,212,31,200,82,212,107,225,107,225,82,212,87,215,107,225,87,215,95,217,95,217,107,218,107,225,107,225,4,225,11,217,107,225,11,217,17,214,107,225,17,214,23,211,107,225,23,211,27,206,107,225,27,206,31,200,122,6,134,-11,145,55,145,55,134,-11,217,192,145,55,217,192,197,193,197,193,217,192,198,195,242,225,175,225,184,217,242,225,184,217,190,216,242,225,190,216,195,213,242,225,195,213,198,210,242,225,198,210,199,205,242,225,199,205,230,213,242,225,230,213,235,216,242,225,235,216,242,218,199,205,217,192,221,202,199,205,221,202,225,208,199,205,225,208,230,213,199,204,199,201,217,192,199,204,217,192,199,205,198,198,198,195,217,192,198,198,217,192,199,201,111,34,116,22,145,55,145,55,116,22,120,13,145,55,120,13,122,6,145,55,84,184,99,59,145,55,99,59,105,47,145,55,105,47,111,34,99,59,84,184,83,188,99,59,83,188,81,192,99,59,81,192,79,196,99,59,79,196,78,201,99,59,78,201,31,200,119,-5,111,-24,118,-48,119,-5,118,-48,134,-11,119,-5,134,-11,122,6,102,-76,118,-48,111,-24,102,-76,111,-24,100,-44,102,-76,100,-44,88,-60,68,-105,67,-65,64,-64,68,-105,64,-64,60,-63,68,-105,60,-63,55,-60,68,-105,55,-60,49,-58,68,-105,49,-58,47,-108,49,-58,44,-57,47,-108,47,-108,44,-57,39,-56,47,-108,39,-56,35,-106,35,-106,39,-56,33,-56,35,-106,33,-56,27,-57,35,-106,27,-57,26,-102,26,-102,27,-57,21,-60,26,-102,21,-60,18,-96,18,-96,21,-60,16,-65,18,-96,16,-65,14,-88,14,-88,16,-65,13,-72,14,-88,13,-72,12,-79,184,217,175,225,175,218,11,217,4,225,4,218, 190,330,186,331,172,325,146,315,132,310,117,305,117,297,119,298,129,298,138,297,144,295,147,290,149,281,150,270,150,204,144,212,136,219,127,225,116,229,104,230,76,225,53,209,36,185,25,153,22,113,23,89,27,66,32,46,41,29,51,15,60,8,69,2,79,-1,91,-3,103,-4,115,-3,126,0,136,6,144,13,150,22,150,-65,149,-79,146,-88,140,-94,129,-98,114,-100,114,-107,233,-107,233,-100,214,-99,202,-95,194,-89,191,-78,190,-62,190,22,195,13,203,6,213,0,224,-3,236,-4,249,-3,260,-1,270,2,279,8,287,15,298,29,306,46,313,66,316,89,318,113,314,153,303,185,286,209,263,225,235,230,223,229,212,225,203,219,195,212,190,204,16383,16383,190,179,192,188,198,197,207,206,219,212,233,215,248,209,260,194,268,172,273,146,275,117,274,99,273,82,271,66,267,51,263,38,258,29,253,21,247,15,240,11,233,10,219,13,207,19,198,28,192,38,190,47,16383,16383,150,47,147,38,141,28,132,19,120,13,105,10,99,11,92,15,86,21,81,29,76,38,72,51,68,66,66,82,65,99,65,117,66,146,71,172,80,194,91,209,105,215,120,212,132,206,141,197,147,187,150,177, 69,2,79,-1,72,51,72,51,79,-1,76,38,81,29,76,38,79,-1,81,29,79,-1,91,-3,150,177,150,47,150,22,150,22,150,47,147,38,150,22,147,38,144,13,144,13,147,38,141,28,144,13,141,28,136,6,136,6,141,28,132,19,136,6,132,19,126,0,126,0,132,19,120,13,126,0,120,13,115,-3,115,-3,120,13,105,10,105,10,99,11,103,-4,103,-4,99,11,92,15,103,-4,92,15,91,-3,91,-3,92,15,86,21,91,-3,86,21,81,29,150,270,150,204,150,22,150,22,150,204,150,177,150,177,150,204,147,187,147,187,150,204,144,212,147,187,144,212,141,197,141,197,144,212,136,219,141,197,136,219,132,206,132,206,136,219,127,225,132,206,127,225,120,212,120,212,127,225,116,229,120,212,116,229,105,215,66,146,71,172,76,225,76,225,71,172,80,194,76,225,80,194,104,230,104,230,80,194,91,209,104,230,91,209,105,215,76,225,53,209,66,146,66,146,53,209,65,117,65,99,65,117,60,8,65,99,60,8,69,2,41,29,51,15,53,209,53,209,51,15,60,8,53,209,60,8,65,117,36,185,25,153,27,66,36,185,27,66,32,46,36,185,32,46,41,29,36,185,41,29,53,209,25,153,22,113,23,89,25,153,23,89,27,66,146,-88,140,-94,233,-107,233,-107,140,-94,129,-98,233,-107,129,-98,114,-100,122,298,124,298,132,310,132,310,124,298,126,298,132,310,126,298,129,298,129,298,138,297,132,310,132,310,138,297,146,315,132,310,117,305,119,298,132,310,119,298,122,298,192,38,190,47,195,13,195,13,190,47,190,22,191,-78,190,-62,159,320,191,-78,159,320,150,22,150,22,159,320,150,270,138,297,144,295,146,315,146,315,144,295,147,290,146,315,147,290,159,320,159,320,147,290,149,281,159,320,149,281,150,270,190,204,190,330,186,331,190,204,186,331,190,-62,190,204,190,-62,190,179,190,204,190,179,195,212,274,99,273,82,279,8,279,8,273,82,271,66,279,8,271,66,270,2,270,2,271,66,267,51,270,2,267,51,263,38,263,38,258,29,260,-1,260,-1,258,29,253,21,260,-1,253,21,249,-3,249,-3,253,21,247,15,249,-3,247,15,240,11,213,0,224,-3,219,13,219,13,224,-3,233,10,240,11,233,10,236,-4,240,11,236,-4,249,-3,314,153,303,185,306,46,314,153,306,46,313,66,314,153,313,66,316,89,314,153,316,89,318,113,274,99,279,8,275,117,275,117,279,8,286,209,286,209,279,8,287,15,286,209,287,15,303,185,303,185,287,15,298,29,303,185,298,29,306,46,248,209,260,194,263,225,263,225,260,194,268,172,263,225,268,172,286,209,286,209,268,172,273,146,286,209,273,146,275,117,263,225,235,230,248,209,248,209,235,230,233,215,219,212,233,215,223,229,219,212,223,229,212,225,263,38,260,-1,270,2,233,-107,233,-100,214,-99,233,-107,214,-99,202,-95,233,-107,202,-95,149,-79,233,-107,149,-79,146,-88,172,325,159,320,190,-62,172,325,190,-62,186,331,194,-89,191,-78,150,22,194,-89,150,22,150,-65,194,-89,150,-65,202,-95,69,2,72,51,68,66,69,2,68,66,66,82,69,2,66,82,65,99,192,38,195,13,198,28,198,28,195,13,203,6,198,28,203,6,207,19,207,19,203,6,213,0,207,19,213,0,219,13,190,179,192,188,195,212,195,212,192,188,198,197,195,212,198,197,203,219,203,219,198,197,207,206,203,219,207,206,212,225,212,225,207,206,219,212,235,230,223,229,233,215,233,10,224,-3,236,-4,115,-3,105,10,103,-4,119,298,117,305,117,297,233,-107,114,-100,114,-107,149,-79,202,-95,150,-65,105,215,116,229,104,230, 238,0,238,7,229,8,221,12,213,18,205,26,197,37,133,136,175,195,181,203,188,209,197,214,215,218,215,225,136,225,136,218,144,217,150,215,154,213,156,210,156,201,154,195,150,187,145,178,138,169,124,149,116,162,108,174,101,185,97,194,94,201,93,206,93,210,96,213,100,216,106,217,114,218,114,225,11,225,11,218,15,218,23,217,31,214,38,208,45,200,54,187,54,188,100,115,45,32,37,22,30,15,23,11,16,9,7,7,7,0,79,0,79,7,72,8,66,9,62,11,60,13,60,19,61,23,63,27,65,33,69,39,108,100,155,28,156,27,156,25,157,23,157,15,155,12,152,9,146,8,137,7,137,0, 30,15,23,11,79,0,79,0,23,11,16,9,79,0,16,9,7,7,31,214,38,208,114,225,114,225,38,208,45,200,114,225,45,200,54,188,54,188,45,200,54,187,54,187,100,115,93,206,93,206,93,210,54,187,54,187,93,210,96,213,54,187,96,213,114,225,114,225,96,213,100,216,114,225,100,216,106,217,30,15,79,0,37,22,37,22,79,0,62,11,37,22,62,11,45,32,45,32,62,11,60,13,45,32,60,13,60,17,60,17,60,19,45,32,45,32,60,19,61,23,45,32,61,23,63,27,106,217,114,218,114,225,114,225,11,225,15,218,114,225,15,218,23,217,114,225,23,217,31,214,138,169,124,149,133,136,138,169,133,136,175,195,138,169,175,195,145,178,215,225,136,225,144,217,215,225,144,217,150,215,215,225,150,215,154,213,215,225,154,213,156,210,215,225,156,210,156,206,215,225,156,206,188,209,215,225,188,209,197,214,215,225,197,214,206,216,215,225,206,216,215,218,175,195,181,203,156,206,175,195,156,206,156,201,175,195,156,201,154,195,175,195,154,195,150,187,175,195,150,187,145,178,155,12,152,9,238,0,238,0,152,9,146,8,238,0,146,8,137,7,157,20,238,0,221,12,157,20,221,12,213,18,157,20,213,18,205,26,157,20,205,26,197,37,157,20,197,37,157,21,197,37,133,136,155,28,197,37,155,28,156,27,197,37,156,27,156,25,197,37,156,25,157,23,197,37,157,23,157,21,133,136,124,149,155,28,155,28,124,149,116,162,155,28,116,162,108,100,108,100,116,162,108,174,108,100,108,174,101,185,100,115,45,32,63,27,100,115,63,27,65,33,100,115,65,33,69,39,100,115,69,39,108,100,100,115,108,100,101,185,100,115,101,185,97,194,100,115,97,194,94,201,100,115,94,201,93,206,229,8,221,12,238,0,229,8,238,0,238,7,157,15,155,12,238,0,157,15,238,0,157,20,79,0,79,7,72,8,79,0,72,8,66,9,79,0,66,9,62,11,79,0,7,7,7,0,238,0,137,7,137,0,144,217,136,225,136,218,188,209,156,206,181,203,15,218,11,225,11,218,114,225,54,188,54,187, 251,225,146,225,146,218,159,216,168,212,174,207,177,199,178,189,178,39,177,29,174,22,170,17,164,15,157,14,104,14,97,15,92,17,88,22,85,29,84,39,84,188,85,199,88,207,94,213,103,216,116,218,116,225,12,225,12,218,25,216,33,214,39,209,42,201,42,26,39,16,33,11,24,8,12,7,12,0,199,0,210,-3,221,-14,232,-34,243,-68,251,-68,251,7,238,8,229,11,224,16,221,25,220,40,220,186,221,199,223,208,229,213,238,216,251,218, 39,16,33,11,187,0,187,0,33,11,24,8,187,0,24,8,12,7,116,225,12,225,25,216,116,225,25,216,33,214,116,225,33,214,39,209,116,225,39,209,42,201,116,225,42,201,42,188,116,225,42,188,94,213,116,225,94,213,103,216,116,225,103,216,116,218,92,17,88,22,42,41,42,41,88,22,85,29,42,41,85,29,42,188,42,188,85,29,84,39,42,188,84,39,84,188,42,188,84,188,85,199,42,188,85,199,88,207,42,188,88,207,94,213,251,225,146,225,159,216,251,225,159,216,168,212,251,225,168,212,174,207,251,225,174,207,177,199,251,225,177,199,178,189,251,225,178,189,229,213,251,225,229,213,238,216,251,225,238,216,251,218,224,16,221,25,221,-14,221,-14,221,25,220,40,220,40,220,186,210,-3,210,-3,220,186,199,0,178,189,187,0,221,199,221,199,187,0,199,0,221,199,199,0,220,186,223,208,229,213,178,189,223,208,178,189,221,199,251,-68,251,7,243,-68,243,-68,251,7,238,8,243,-68,238,8,232,-34,232,-34,238,8,229,11,232,-34,229,11,224,16,174,22,170,17,187,0,187,0,170,17,164,15,187,0,164,15,157,14,187,0,178,189,178,39,187,0,178,39,177,29,187,0,177,29,174,22,42,26,39,16,97,15,97,15,39,16,187,0,97,15,187,0,104,14,104,14,187,0,157,14,42,26,97,15,92,17,42,26,92,17,42,41,187,0,12,7,12,0,221,-14,220,40,210,-3,224,16,221,-14,232,-34,159,216,146,225,146,218,25,216,12,225,12,218,42,188,42,201,42,187, 244,225,139,225,139,218,152,216,161,212,167,207,170,200,171,190,171,118,166,116,158,113,148,110,136,108,123,107,106,108,94,112,87,120,83,131,81,147,81,186,82,199,86,208,91,213,100,216,113,218,113,225,9,225,9,218,22,216,30,213,36,209,39,200,40,186,40,144,43,121,52,105,66,97,85,93,107,92,124,93,139,96,152,100,162,104,171,108,171,27,168,18,162,13,153,9,141,7,141,0,244,0,244,7,231,9,223,12,217,17,215,25,214,39,214,199,217,208,223,213,231,216,244,218, 113,218,113,218,100,216,100,216,113,218,113,225,100,216,113,225,91,213,91,213,113,225,40,186,91,213,40,186,86,208,86,208,40,186,43,121,86,208,43,121,82,199,82,199,43,121,52,105,82,199,52,105,66,97,87,120,83,131,85,93,85,93,83,131,81,147,81,147,81,186,66,97,66,97,81,186,82,199,30,213,36,209,113,225,113,225,36,209,39,200,113,225,39,200,40,186,22,216,30,213,113,225,22,216,113,225,9,225,22,216,9,225,9,218,244,7,231,9,244,0,244,0,231,9,223,12,244,0,223,12,171,39,171,39,223,12,217,17,171,39,217,17,171,108,171,108,171,118,166,116,171,108,166,116,162,104,162,104,166,116,158,113,162,104,158,113,152,100,152,100,158,113,148,110,152,100,148,110,139,96,139,96,148,110,136,108,139,96,136,108,124,93,124,93,136,108,123,107,107,92,124,93,123,107,107,92,123,107,106,108,107,92,106,108,94,112,107,92,94,112,87,120,107,92,87,120,85,93,244,225,139,225,152,216,244,225,152,216,161,212,244,225,161,212,167,207,244,225,167,207,170,200,244,225,170,200,171,190,244,225,171,190,223,213,244,225,223,213,231,216,244,225,231,216,244,218,214,39,214,186,171,108,171,108,214,186,214,199,171,108,214,199,217,208,171,190,171,108,217,208,171,190,217,208,223,213,171,108,217,17,215,25,171,108,215,25,214,39,244,0,171,39,171,27,244,0,171,27,168,18,244,0,168,18,162,13,244,0,162,13,153,9,244,0,153,9,141,7,244,0,141,7,141,0,43,121,40,186,40,144,171,118,171,108,171,190,152,216,139,225,139,218,85,93,81,147,66,97, 373,225,270,225,270,218,282,216,291,213,296,207,299,200,300,189,300,39,299,29,297,22,293,17,287,15,278,14,235,14,228,15,221,17,217,22,214,29,213,39,213,189,214,199,218,207,224,213,232,216,243,218,243,225,141,225,141,218,152,216,160,213,166,207,170,199,171,189,171,39,170,29,168,22,164,17,158,15,150,14,107,14,99,15,93,17,88,22,85,29,84,39,84,189,85,199,88,207,93,212,102,216,114,218,114,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,372,0,372,7,360,8,351,11,345,16,342,25,342,198,345,207,351,213,360,216,373,218, 39,16,33,11,372,0,372,0,33,11,25,9,372,0,25,9,12,7,114,225,12,225,25,216,114,225,25,216,33,212,114,225,33,212,39,206,114,225,39,206,42,197,114,225,42,197,42,183,114,225,42,183,93,212,114,225,93,212,102,216,114,225,102,216,114,218,93,17,88,22,42,40,42,40,88,22,85,29,42,40,85,29,42,183,42,183,85,29,84,39,42,183,84,39,84,189,42,183,84,189,85,199,42,183,85,199,88,207,42,183,88,207,93,212,93,17,42,25,99,15,99,15,42,25,39,16,99,15,39,16,107,14,107,14,39,16,372,0,107,14,372,0,150,14,150,14,372,0,158,15,243,225,141,225,152,216,243,225,152,216,160,213,243,225,160,213,166,207,243,225,166,207,170,199,243,225,170,199,171,189,243,225,171,189,224,213,243,225,224,213,232,216,243,225,232,216,243,218,213,39,213,189,171,189,171,189,213,189,214,199,171,189,214,199,218,207,221,17,217,22,171,39,171,39,217,22,214,29,171,39,214,29,171,189,297,22,293,17,372,0,372,0,293,17,287,15,372,0,287,15,278,14,373,225,270,225,282,216,373,225,282,216,291,213,373,225,291,213,296,207,373,225,296,207,299,200,373,225,299,200,300,189,373,225,300,189,351,213,373,225,351,213,360,216,373,225,360,216,373,218,342,40,342,183,300,189,300,189,342,183,342,198,300,189,342,198,345,207,351,11,345,16,300,39,300,39,345,16,342,25,300,39,342,25,300,189,372,0,372,7,360,8,372,0,360,8,351,11,372,0,351,11,299,29,372,0,299,29,297,22,372,0,278,14,235,14,372,0,235,14,228,15,372,0,228,15,164,17,372,0,164,17,158,15,170,29,168,22,228,15,170,29,228,15,221,17,170,29,221,17,171,39,372,0,12,7,12,0,42,25,93,17,42,40,164,17,228,15,168,22,171,189,214,29,213,39,299,29,351,11,300,39,300,189,342,25,342,40,282,216,270,225,270,218,351,213,300,189,345,207,152,216,141,225,141,218,224,213,171,189,218,207,25,216,12,225,12,218, 373,225,270,225,270,218,282,216,291,213,296,207,299,200,300,189,300,39,299,29,297,22,293,17,287,15,278,14,235,14,228,15,221,17,217,22,214,29,213,39,213,189,214,199,218,207,224,212,232,216,243,218,243,225,141,225,141,218,142,218,152,216,160,212,166,207,170,199,171,189,171,39,170,29,168,22,164,17,158,15,150,14,107,14,99,15,93,17,88,22,85,29,84,39,84,189,85,199,87,207,93,212,101,216,114,218,114,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,325,0,335,-5,345,-17,354,-37,364,-68,372,-68,372,7,360,8,351,11,345,15,342,25,342,198,345,207,351,213,360,216,373,218, 39,16,33,11,315,0,315,0,33,11,25,9,315,0,25,9,12,7,114,225,12,225,25,216,114,225,25,216,33,212,114,225,33,212,39,206,114,225,39,206,42,197,114,225,42,197,42,183,114,225,42,183,93,212,114,225,93,212,101,216,114,225,101,216,114,218,93,17,88,22,42,40,42,40,88,22,85,29,42,40,85,29,42,183,42,183,85,29,84,39,42,183,84,39,84,189,42,183,84,189,85,199,42,183,85,199,87,207,42,183,87,207,93,212,93,17,42,25,99,15,99,15,42,25,39,16,99,15,39,16,107,14,107,14,39,16,315,0,107,14,315,0,150,14,150,14,315,0,158,15,243,225,141,225,142,218,243,225,142,218,152,216,243,225,152,216,160,212,243,225,160,212,166,207,243,225,166,207,170,199,243,225,170,199,171,189,243,225,171,189,224,212,243,225,224,212,232,216,243,225,232,216,243,218,213,39,213,189,171,189,171,189,213,189,214,199,171,189,214,199,218,207,221,17,217,22,171,39,171,39,217,22,214,29,171,39,214,29,171,189,373,225,270,225,282,216,373,225,282,216,291,213,373,225,291,213,296,207,373,225,296,207,299,200,373,225,299,200,300,189,373,225,300,189,351,213,373,225,351,213,360,216,373,225,360,216,373,218,345,15,342,25,345,-17,345,-17,342,25,342,40,342,40,342,183,335,-5,335,-5,342,183,325,0,300,189,315,0,342,198,342,198,315,0,325,0,342,198,325,0,342,183,345,207,351,213,300,189,345,207,300,189,342,198,372,-68,372,7,364,-68,364,-68,372,7,360,8,364,-68,360,8,354,-37,354,-37,360,8,351,11,354,-37,351,11,345,15,297,22,293,17,315,0,315,0,293,17,287,15,315,0,287,15,278,14,315,0,300,189,300,39,315,0,300,39,299,29,315,0,299,29,297,22,315,0,278,14,235,14,315,0,235,14,228,15,315,0,228,15,168,22,315,0,168,22,164,17,315,0,164,17,158,15,170,29,168,22,228,15,170,29,228,15,221,17,170,29,221,17,171,39,315,0,12,7,12,0,42,25,93,17,42,40,171,189,214,29,213,39,345,-17,342,40,335,-5,345,15,345,-17,354,-37,282,216,270,225,270,218,142,218,141,225,141,218,224,212,171,189,218,207,25,216,12,225,12,218, 126,126,126,199,129,207,134,212,143,216,156,218,156,225,8,225,4,161,12,161,18,181,25,195,35,205,46,209,61,211,68,211,74,209,79,207,83,202,84,195,84,40,83,25,80,16,75,11,66,9,52,7,52,0,169,0,196,3,220,10,238,23,249,40,253,62,249,86,235,105,215,117,188,124,158,126,16383,16383,126,112,148,112,167,111,183,107,196,98,205,84,208,64,205,43,196,29,182,20,164,15,142,14,135,14,130,16,127,19,126,23,126,30, 80,16,75,11,169,0,169,0,75,11,66,9,169,0,66,9,52,7,74,209,156,225,68,211,68,211,156,225,61,211,46,209,61,211,156,225,46,209,156,225,8,225,156,225,74,209,79,207,156,225,79,207,83,202,156,225,83,202,84,195,156,225,84,195,134,212,156,225,134,212,143,216,156,225,143,216,156,218,84,195,126,23,126,30,126,126,126,112,148,112,126,126,148,112,158,126,158,126,148,112,167,111,158,126,167,111,188,124,188,124,167,111,183,107,188,124,183,107,196,98,84,195,126,30,126,189,84,195,126,189,126,199,84,195,126,199,129,207,84,195,129,207,134,212,8,225,4,161,12,161,8,225,12,161,18,181,8,225,18,181,25,195,8,225,25,195,35,205,8,225,35,205,46,209,205,43,196,29,196,3,196,3,196,29,182,20,196,3,182,20,169,0,169,0,182,20,164,15,169,0,164,15,142,14,142,14,135,14,169,0,169,0,135,14,130,16,169,0,130,16,83,25,83,25,130,16,84,40,196,3,220,10,205,43,205,43,220,10,208,64,215,117,208,64,220,10,215,117,220,10,235,105,235,105,220,10,238,23,235,105,238,23,249,86,249,86,238,23,249,40,249,86,249,40,253,62,215,117,188,124,196,98,215,117,196,98,205,84,215,117,205,84,208,64,84,40,130,16,127,19,84,40,127,19,126,23,84,40,126,23,84,195,169,0,52,7,52,0,80,16,169,0,83,25, 323,0,323,8,310,10,301,13,295,18,293,26,292,36,292,199,295,207,300,212,309,216,323,218,323,225,219,225,219,218,232,216,241,212,246,206,249,197,250,183,250,40,249,25,246,16,241,11,232,9,219,7,219,0,16383,16383,84,126,84,189,85,199,88,207,93,212,102,216,116,218,116,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,127,0,155,3,179,10,197,23,209,40,213,62,208,86,194,105,174,117,148,124,118,126,16383,16383,84,112,107,112,126,111,142,107,155,98,164,84,167,64,164,43,155,29,141,20,123,15,102,14,94,14,89,16,86,19,85,23,84,30, 323,218,323,218,309,216,309,216,323,218,323,225,309,216,323,225,300,212,300,212,323,225,249,197,300,212,249,197,250,183,293,26,250,183,250,40,293,26,250,40,295,18,295,18,250,40,301,13,292,36,292,189,250,183,250,183,292,189,292,199,250,183,292,199,295,207,323,225,219,225,232,216,323,225,232,216,241,212,323,225,241,212,246,206,323,225,246,206,249,197,323,0,323,8,310,10,323,0,310,10,301,13,323,0,301,13,250,40,323,0,250,40,249,25,323,0,249,25,246,16,323,0,246,16,241,11,323,0,241,11,232,9,323,0,232,9,219,7,323,0,219,7,219,0,39,16,33,11,127,0,127,0,33,11,25,9,127,0,25,9,12,7,116,225,12,225,25,216,116,225,25,216,33,212,116,225,33,212,39,206,116,225,39,206,42,197,116,225,42,197,93,212,116,225,93,212,102,216,116,225,102,216,116,218,42,183,85,23,84,30,84,126,84,112,107,112,84,126,107,112,118,126,118,126,107,112,126,111,118,126,126,111,148,124,148,124,126,111,142,107,148,124,142,107,155,98,42,183,84,30,84,189,42,183,84,189,85,199,42,183,85,199,88,207,42,183,88,207,93,212,42,183,93,212,42,197,164,43,155,29,155,3,155,3,155,29,141,20,155,3,141,20,127,0,127,0,141,20,123,15,127,0,123,15,102,14,102,14,94,14,127,0,127,0,94,14,89,16,127,0,89,16,42,25,42,25,89,16,42,40,155,3,179,10,164,43,164,43,179,10,167,64,174,117,167,64,179,10,174,117,179,10,194,105,194,105,179,10,197,23,194,105,197,23,208,86,208,86,197,23,209,40,208,86,209,40,213,62,174,117,148,124,155,98,174,117,155,98,164,84,174,117,164,84,167,64,42,40,89,16,86,19,42,40,86,19,85,23,42,40,85,23,42,183,127,0,12,7,12,0,39,16,127,0,42,25,25,216,12,225,12,218,250,183,293,26,292,36,232,216,219,225,219,218,300,212,250,183,295,207, 84,126,84,189,85,199,88,207,93,212,102,216,116,218,116,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,127,0,155,3,179,10,197,23,209,40,213,62,208,86,194,105,174,117,148,124,118,126,16383,16383,84,112,107,112,126,111,142,107,155,98,164,84,167,64,164,43,155,29,141,20,123,15,102,14,94,14,89,16,86,19,85,23,84,30, 39,16,33,11,127,0,127,0,33,11,25,9,127,0,25,9,12,7,116,225,12,225,25,216,116,225,25,216,33,212,116,225,33,212,39,206,116,225,39,206,42,197,116,225,42,197,93,212,116,225,93,212,102,216,116,225,102,216,116,218,42,183,85,23,84,30,84,126,84,112,107,112,84,126,107,112,118,126,118,126,107,112,126,111,118,126,126,111,148,124,148,124,126,111,142,107,148,124,142,107,155,98,42,183,84,30,84,189,42,183,84,189,85,199,42,183,85,199,88,207,42,183,88,207,93,212,42,183,93,212,42,197,164,43,155,29,155,3,155,3,155,29,141,20,155,3,141,20,127,0,127,0,141,20,123,15,127,0,123,15,102,14,102,14,94,14,127,0,127,0,94,14,89,16,127,0,89,16,42,25,42,25,89,16,42,40,155,3,179,10,164,43,164,43,179,10,167,64,174,117,167,64,179,10,174,117,179,10,194,105,194,105,179,10,197,23,194,105,197,23,208,86,208,86,197,23,209,40,208,86,209,40,213,62,174,117,148,124,155,98,174,117,155,98,164,84,174,117,164,84,167,64,42,40,89,16,86,19,42,40,86,19,85,23,42,40,85,23,42,183,127,0,12,7,12,0,39,16,127,0,42,25,25,216,12,225,12,218, 30,228,23,157,32,157,38,173,46,189,58,203,75,212,99,216,122,212,140,200,154,182,162,157,165,128,75,128,75,112,165,112,160,87,150,64,135,47,114,35,88,31,71,33,56,37,42,46,28,59,15,78,7,74,18,53,32,32,49,14,72,0,101,-4,136,1,165,16,187,41,200,73,205,110,201,147,189,179,169,206,140,223,102,230,92,230,84,229,63,222,59,220,56,218,52,217,48,217,44,218,42,219,40,221,38,224,37,228, 59,220,56,218,58,203,58,203,56,218,52,217,58,203,52,217,48,217,48,217,44,218,46,189,46,189,44,218,42,219,46,189,42,219,40,221,30,228,32,157,37,228,37,228,32,157,38,173,37,228,38,173,38,224,38,224,38,173,46,189,38,224,46,189,40,221,15,78,18,53,28,59,28,59,18,53,32,32,28,59,32,32,42,46,42,46,32,32,49,14,42,46,49,14,56,37,56,37,49,14,72,0,56,37,72,0,71,33,71,33,72,0,88,31,114,35,88,31,101,-4,114,35,101,-4,136,1,99,216,92,230,84,229,99,216,84,229,78,227,99,216,78,227,75,212,99,216,102,230,92,230,75,212,78,227,72,225,75,212,72,225,66,223,75,212,66,223,63,222,75,212,63,222,59,220,75,212,59,220,58,203,48,217,46,189,58,203,75,128,165,112,165,128,165,128,165,112,165,16,165,128,165,16,169,206,205,110,201,147,200,73,200,73,201,147,189,179,200,73,189,179,187,41,187,41,189,179,169,206,187,41,169,206,165,16,169,206,140,223,140,200,169,206,140,200,154,182,169,206,154,182,162,157,169,206,162,157,165,128,122,212,140,200,140,223,122,212,140,223,102,230,122,212,102,230,99,216,165,112,160,87,165,16,165,16,160,87,150,64,165,16,150,64,136,1,136,1,150,64,135,47,136,1,135,47,114,35,88,31,72,0,101,-4,18,53,15,78,7,74,32,157,30,228,23,157,165,112,75,128,75,112, 84,124,84,189,85,199,88,207,93,212,102,216,116,218,116,225,12,225,12,218,25,216,33,212,39,206,42,197,42,25,39,16,33,11,25,9,12,7,12,0,116,0,116,7,102,9,93,13,88,18,85,26,84,36,84,108,131,108,138,70,153,39,176,16,205,0,239,-4,276,1,308,17,331,43,346,76,352,116,346,154,331,186,308,210,278,225,243,230,207,225,177,211,154,189,138,160,131,124,16383,16383,306,102,304,70,296,44,284,25,268,13,248,9,237,10,227,13,218,18,210,25,203,34,193,51,185,70,180,91,177,113,176,137,179,164,186,186,199,202,215,212,234,216,246,215,257,211,266,206,274,199,281,191,290,177,297,161,302,142,305,122,306,102, 39,16,33,11,116,0,116,0,33,11,25,9,116,0,25,9,12,7,116,225,12,225,25,216,116,225,25,216,33,212,116,225,33,212,39,206,116,225,39,206,42,197,116,225,42,197,93,212,116,225,93,212,102,216,116,225,102,216,116,218,138,160,131,124,131,108,131,108,131,124,84,124,131,108,84,124,84,108,85,26,84,36,42,183,85,26,42,183,42,40,42,183,84,36,84,189,42,183,84,189,85,199,42,183,85,199,88,207,42,183,88,207,93,212,42,183,93,212,42,197,116,0,116,7,102,9,116,0,102,9,93,13,116,0,93,13,42,40,116,0,42,40,42,25,116,0,42,25,39,16,42,40,93,13,88,18,42,40,88,18,85,26,180,91,176,16,185,70,185,70,176,16,205,0,185,70,205,0,193,51,193,51,205,0,203,34,210,25,203,34,205,0,210,25,205,0,239,-4,278,225,243,230,246,215,246,215,243,230,234,216,215,212,234,216,243,230,215,212,243,230,207,225,304,70,296,44,308,17,308,17,296,44,284,25,308,17,284,25,276,1,276,1,284,25,268,13,276,1,268,13,248,9,248,9,237,10,239,-4,239,-4,237,10,227,13,239,-4,227,13,218,18,257,211,266,206,278,225,278,225,266,206,274,199,278,225,274,199,281,191,281,191,290,177,308,210,308,210,290,177,297,161,308,210,297,161,302,142,346,154,331,186,331,43,346,154,331,43,346,76,346,154,346,76,352,116,304,70,308,17,306,102,306,102,308,17,308,210,308,210,308,17,331,43,308,210,331,43,331,186,308,210,302,142,305,122,308,210,305,122,306,102,308,210,278,225,281,191,248,9,239,-4,276,1,176,137,179,164,177,211,177,211,179,164,186,186,177,211,186,186,207,225,207,225,186,186,199,202,207,225,199,202,215,212,131,108,138,70,138,160,138,160,138,70,153,39,138,160,153,39,154,189,154,189,153,39,176,16,154,189,176,16,176,137,176,137,177,211,154,189,177,113,176,137,176,16,177,113,176,16,180,91,278,225,246,215,257,211,210,25,239,-4,218,18,116,0,12,7,12,0,25,216,12,225,12,218, 224,225,121,225,91,224,65,219,45,210,31,193,26,167,30,148,40,131,55,118,74,109,97,104,37,31,32,25,26,19,19,14,11,9,2,7,2,0,64,0,142,103,151,103,151,25,148,16,143,11,135,8,123,7,123,0,224,0,224,8,211,10,202,13,197,18,194,26,193,40,193,183,194,198,197,207,202,213,211,216,224,218,16383,16383,151,117,131,117,111,119,94,125,82,135,74,148,71,165,75,185,85,198,99,206,117,210,136,211,142,211,147,209,149,206,151,202,151,195, 26,19,19,14,64,0,64,0,19,14,11,9,64,0,11,9,2,7,97,104,64,0,142,103,97,104,142,103,111,119,97,104,111,119,94,125,97,104,94,125,82,135,97,104,82,135,74,148,97,104,74,148,74,109,85,198,91,224,75,185,75,185,91,224,65,219,75,185,65,219,71,165,71,165,74,109,74,148,26,167,30,148,31,193,31,193,30,148,40,131,31,193,40,131,45,210,45,210,40,131,55,118,45,210,55,118,65,219,65,219,55,118,74,109,65,219,74,109,71,165,148,16,143,11,224,0,224,0,143,11,135,8,224,0,135,8,123,7,147,209,224,225,142,211,142,211,224,225,136,211,117,210,136,211,121,225,117,210,121,225,99,206,99,206,121,225,91,224,99,206,91,224,85,198,224,8,211,10,224,0,224,0,211,10,202,13,224,0,202,13,151,38,151,38,202,13,197,18,151,38,197,18,151,103,151,103,197,18,151,117,151,103,151,117,142,103,142,103,151,117,131,117,142,103,131,117,111,119,64,0,97,104,37,31,64,0,37,31,32,25,64,0,32,25,26,19,224,225,147,209,149,206,224,225,149,206,151,202,224,225,151,202,151,195,224,225,151,195,202,213,224,225,202,213,211,216,224,225,211,216,224,218,193,40,193,183,151,195,151,195,193,183,194,198,151,195,194,198,197,207,151,195,194,26,193,40,224,225,121,225,136,211,151,117,197,18,194,26,151,117,194,26,151,195,151,25,148,16,224,0,151,25,224,0,151,38,224,0,123,7,123,0,202,213,151,195,197,207,64,0,2,7,2,0, 266,59,253,44,242,34,234,29,228,26,222,25,216,28,216,31,215,33,216,38,217,44,218,49,220,55,221,61,247,151,249,159,252,180,252,186,250,202,245,214,236,223,224,228,208,230,189,227,169,216,147,196,123,165,99,123,98,123,133,252,205,278,211,300,139,273,146,296,148,306,151,315,153,324,156,332,158,340,155,342,143,337,131,333,116,329,98,325,76,320,76,312,85,312,92,311,99,309,103,306,104,301,104,293,103,290,103,286,93,257,45,239,40,218,87,234,23,0,65,0,78,41,88,72,98,97,109,117,121,137,137,159,152,177,167,191,180,200,190,203,198,202,203,199,207,194,209,188,209,175,207,161,206,155,204,150,185,78,182,66,178,54,175,41,173,31,172,23,174,13,177,5,183,0,190,-3,199,-4,211,-2,225,3,240,14,256,30,273,54, 99,123,98,123,99,123,99,123,98,123,109,117,99,123,109,117,123,165,123,165,109,117,121,137,104,296,104,293,133,252,133,252,104,293,103,290,133,252,103,290,103,286,103,286,93,257,98,123,98,123,93,257,98,97,98,123,98,97,109,117,203,199,208,230,198,202,198,202,208,230,190,203,180,200,190,203,189,227,180,200,189,227,169,216,123,165,137,159,147,196,147,196,137,159,152,177,147,196,152,177,169,216,169,216,152,177,167,191,169,216,167,191,180,200,204,150,185,78,190,-3,204,150,190,-3,199,-4,204,150,199,-4,211,-2,204,150,211,-2,206,155,211,-2,216,31,215,33,215,33,224,228,211,-2,211,-2,224,228,209,181,211,-2,209,181,209,175,211,-2,209,175,208,168,224,228,215,33,216,38,224,228,216,38,217,44,224,228,217,44,218,49,224,228,218,49,220,55,224,228,220,55,221,61,224,228,221,61,247,151,224,228,247,151,236,223,209,188,209,181,224,228,209,188,224,228,208,230,209,188,208,230,207,194,208,230,189,227,190,203,249,159,250,166,250,202,250,202,250,166,251,173,250,202,251,173,252,186,252,186,251,173,252,180,247,151,249,159,250,202,247,151,250,202,245,214,247,151,245,214,236,223,218,27,225,3,220,26,220,26,225,3,222,25,228,26,222,25,225,3,228,26,225,3,240,14,256,30,273,54,266,59,256,30,266,59,253,44,256,30,253,44,242,34,256,30,242,34,240,14,234,29,228,26,240,14,234,29,240,14,242,34,225,3,218,27,216,28,225,3,216,28,216,31,225,3,216,31,211,-2,207,161,206,155,211,-2,207,161,211,-2,208,168,183,0,190,-3,185,78,183,0,185,78,182,66,183,0,182,66,178,54,183,0,178,54,177,5,175,41,173,31,174,13,175,41,174,13,177,5,175,41,177,5,178,54,65,0,78,41,87,234,87,234,78,41,88,72,87,234,88,72,93,257,93,257,88,72,98,97,45,239,40,218,87,234,45,239,87,234,93,257,85,312,92,311,98,325,98,325,92,311,99,309,98,325,99,309,116,329,116,329,99,309,103,306,116,329,103,306,104,301,104,301,104,299,133,252,133,252,104,299,104,296,76,320,76,312,85,312,76,320,85,312,98,325,151,315,153,324,155,342,155,342,153,324,156,332,155,342,156,332,158,340,133,252,139,273,143,337,143,337,139,273,146,296,143,337,146,296,155,342,155,342,146,296,148,306,155,342,148,306,151,315,133,252,143,337,131,333,133,252,131,333,116,329,133,252,116,329,104,301,103,286,98,123,133,252,139,273,133,252,205,278,139,273,205,278,211,300,65,0,87,234,23,0,174,13,173,31,172,23,208,230,203,199,207,194,121,137,137,159,123,165, 344,337,341,331,335,324,327,316,316,310,302,308,271,312,246,322,222,334,193,344,154,348,118,342,88,327,65,305,51,278,46,248,49,224,60,204,77,189,100,179,128,176,136,176,144,177,151,179,159,182,167,186,163,197,157,195,150,193,144,191,137,190,131,190,116,192,102,198,90,208,82,222,79,241,83,262,93,278,106,289,122,295,138,297,168,293,193,283,216,272,242,262,273,258,303,263,325,276,340,294,349,314,355,334,16383,16383,352,209,344,217,335,225,325,231,312,235,295,237,275,234,257,225,241,212,231,195,227,174,232,145,243,121,257,99,269,76,273,49,271,34,264,22,253,11,238,5,219,2,204,4,191,8,181,16,172,28,165,44,158,63,149,82,136,98,118,110,94,114,72,109,53,97,38,82,28,65,22,51,34,49,39,57,45,64,53,69,61,73,69,74,75,73,81,70,87,65,92,58,97,49,102,39,108,29,114,20,122,11,132,3,144,-3,157,-9,172,-13,192,-15,215,-16,253,-11,285,1,311,22,329,47,335,76,329,103,316,127,300,149,287,169,281,186,283,197,287,205,294,211,302,214,310,215,316,215,322,214,328,211,335,207,343,200, 102,198,90,208,100,179,100,179,90,208,82,222,100,179,82,222,77,189,77,189,82,222,79,241,88,327,79,241,83,262,88,327,83,262,93,278,154,348,138,297,168,293,154,348,168,293,193,344,193,344,168,293,193,283,193,344,193,283,222,334,222,334,193,283,216,272,222,334,216,272,242,262,222,334,242,262,246,322,246,322,242,262,273,258,246,322,273,258,271,312,271,312,273,258,302,308,316,310,302,308,303,263,316,310,303,263,325,276,355,334,344,337,349,314,349,314,344,337,341,331,349,314,341,331,340,294,340,294,341,331,335,324,340,294,335,324,327,316,327,316,316,310,325,276,327,316,325,276,340,294,302,308,273,258,303,263,295,237,275,234,283,197,283,197,275,234,281,186,285,1,281,186,275,234,285,1,275,234,273,49,273,49,271,34,285,1,285,1,271,34,264,22,285,1,264,22,253,-11,253,-11,264,22,253,11,253,-11,253,11,238,5,325,231,312,235,316,215,316,215,312,235,310,215,302,214,310,215,312,235,302,214,312,235,295,237,295,237,283,197,287,205,295,237,287,205,294,211,295,237,294,211,302,214,343,200,352,209,344,217,343,200,344,217,335,225,343,200,335,225,335,207,316,215,322,214,325,231,325,231,322,214,328,211,325,231,328,211,335,225,335,225,328,211,335,207,335,76,329,103,329,47,329,47,329,103,316,127,329,47,316,127,311,22,311,22,316,127,300,149,311,22,300,149,287,169,287,169,281,186,285,1,287,169,285,1,311,22,238,5,219,2,253,-11,253,-11,219,2,215,-16,215,-16,219,2,204,4,215,-16,204,4,192,-15,192,-15,204,4,191,8,192,-15,191,8,181,16,93,278,106,289,118,342,118,342,106,289,122,295,118,342,122,295,154,348,154,348,122,295,138,297,65,305,51,278,60,204,65,305,60,204,77,189,65,305,77,189,79,241,65,305,79,241,88,327,51,278,46,248,49,224,51,278,49,224,60,204,157,195,150,193,151,179,151,179,150,193,144,191,151,179,144,191,144,177,144,177,144,191,137,190,144,177,137,190,136,176,136,176,137,190,131,190,128,176,136,176,131,190,128,176,131,190,116,192,128,176,116,192,102,198,128,176,102,198,100,179,159,182,167,186,163,197,159,182,163,197,157,195,159,182,157,195,151,179,94,114,72,109,75,73,75,73,72,109,69,74,61,73,69,74,72,109,61,73,72,109,53,97,53,97,38,82,39,57,53,97,39,57,45,64,53,97,45,64,53,69,53,97,53,69,61,73,34,49,39,57,38,82,34,49,38,82,28,65,34,49,28,65,22,51,81,70,87,65,94,114,94,114,87,65,92,58,94,114,92,58,97,49,97,49,102,39,118,110,118,110,102,39,108,29,118,110,108,29,114,20,122,11,132,3,136,98,136,98,132,3,144,-3,136,98,144,-3,149,82,149,82,144,-3,157,-9,149,82,157,-9,158,63,158,63,157,-9,172,-13,158,63,172,-13,165,44,165,44,172,-13,172,28,181,16,172,28,172,-13,181,16,172,-13,192,-15,118,110,114,20,122,11,118,110,122,11,136,98,118,110,94,114,97,49,231,195,232,145,241,212,241,212,232,145,243,121,241,212,243,121,257,225,257,225,243,121,257,99,257,225,257,99,275,234,275,234,257,99,269,76,275,234,269,76,273,49,232,145,231,195,227,174,94,114,75,73,81,70,88,327,93,278,118,342, 177,262,198,294,219,325,240,354,261,380,281,403,291,412,302,421,313,428,324,432,335,434,343,433,350,430,355,426,357,420,358,413,350,375,325,339,287,307,237,280,178,262,16383,16383,51,258,62,251,73,246,85,242,97,240,109,239,104,230,98,221,83,194,66,162,51,131,41,101,34,74,32,50,35,30,43,13,56,2,72,-4,89,-6,114,-2,140,11,169,35,201,68,239,112,226,123,191,83,161,52,135,30,113,17,94,13,85,14,78,18,73,24,71,32,70,41,77,74,94,114,117,158,142,201,165,239,232,256,290,286,337,325,367,368,378,411,377,427,371,440,363,448,351,454,336,455,299,445,257,415,212,372,166,318,123,258,111,258,98,259,86,262,73,267,61,275, 142,201,165,239,166,318,166,318,165,239,177,262,177,262,165,239,178,262,237,280,178,262,232,256,237,280,232,256,290,286,313,428,336,455,302,421,302,421,336,455,299,445,302,421,299,445,291,412,291,412,299,445,281,403,261,380,281,403,299,445,261,380,299,445,257,415,351,454,336,455,343,433,343,433,336,455,335,434,324,432,335,434,336,455,324,432,336,455,313,428,355,426,357,420,363,448,363,448,357,420,358,413,367,368,358,413,350,375,367,368,350,375,337,325,337,325,350,375,325,339,337,325,325,339,290,286,290,286,325,339,287,307,290,286,287,307,237,280,351,454,343,433,350,430,351,454,350,430,355,426,351,454,355,426,363,448,371,440,363,448,367,368,371,440,367,368,378,411,371,440,378,411,377,427,177,262,198,294,212,372,212,372,198,294,219,325,212,372,219,325,257,415,257,415,219,325,240,354,257,415,240,354,261,380,232,256,178,262,165,239,34,74,35,30,41,101,41,101,35,30,43,13,41,101,43,13,51,131,51,131,43,13,56,2,51,131,56,2,66,162,66,162,56,2,72,-4,66,162,72,-4,70,41,70,41,83,194,66,162,73,246,85,242,86,262,86,262,85,242,97,240,86,262,97,240,98,259,98,259,97,240,109,239,98,259,109,239,111,258,111,258,109,239,117,158,111,258,117,158,123,258,123,258,117,158,142,201,123,258,142,201,166,318,73,267,61,275,62,251,73,267,62,251,73,246,73,267,73,246,86,262,117,158,109,239,104,230,117,158,104,230,98,221,117,158,98,221,94,114,94,114,98,221,93,212,94,114,93,212,88,203,94,114,88,203,83,194,94,114,83,194,77,74,239,112,226,123,201,68,201,68,226,123,191,83,201,68,191,83,169,35,169,35,191,83,161,52,169,35,161,52,140,11,140,11,161,52,135,30,140,11,135,30,114,-2,114,-2,135,30,113,17,114,-2,113,17,94,13,94,13,85,14,89,-6,89,-6,85,14,78,18,89,-6,78,18,73,24,72,-4,89,-6,73,24,72,-4,73,24,71,32,72,-4,71,32,70,41,94,13,89,-6,114,-2,62,251,61,275,51,258,35,30,34,74,32,50,83,194,70,41,77,74,177,262,212,372,166,318,358,413,367,368,363,448, 406,57,402,52,396,46,384,36,379,35,361,47,353,78,347,119,335,159,309,190,309,191,331,203,348,218,361,236,368,256,371,277,367,300,355,321,335,337,308,348,272,352,206,304,193,317,178,329,160,339,140,345,118,348,89,344,63,335,43,319,30,297,25,270,31,247,45,229,62,214,76,197,82,175,79,163,73,153,64,144,54,138,45,134,49,123,74,132,97,145,115,161,128,180,132,200,126,227,112,245,95,259,81,275,75,299,76,308,80,318,87,325,97,330,108,332,133,322,149,297,157,265,161,231,162,203,162,165,160,123,156,84,149,56,137,45,129,47,116,54,100,62,86,70,76,75,30,2,41,-3,51,9,56,14,60,17,63,20,70,17,83,11,97,3,111,-4,122,-10,149,19,173,53,193,88,209,125,220,161,257,170,269,162,276,149,280,132,282,113,283,94,284,70,289,44,298,21,313,1,333,-10,339,-10,355,0,372,11,388,24,403,36,415,47,16383,16383,222,179,223,189,223,200,224,212,224,233,223,242,222,253,220,265,217,276,214,286,225,297,235,304,245,310,255,313,266,314,283,310,296,302,305,291,310,278,312,266,310,246,303,226,289,208,268,192,238,182, 82,175,79,163,82,175,82,175,79,163,97,145,82,175,97,145,95,259,82,175,95,259,81,275,82,175,81,275,76,197,76,197,81,275,75,299,63,335,75,299,76,308,63,335,76,308,89,344,89,344,76,308,80,318,89,344,80,318,87,325,118,348,108,332,133,322,118,348,133,322,140,345,140,345,133,322,149,297,140,345,149,297,160,339,160,339,149,297,157,265,160,339,157,265,161,231,162,165,160,123,173,53,173,53,160,123,156,84,173,53,156,84,149,19,149,19,156,84,149,56,149,19,149,56,137,45,137,45,129,47,149,19,149,19,129,47,122,-10,220,161,257,170,222,179,220,161,222,179,222,253,220,161,222,253,220,265,220,161,220,265,217,276,220,161,217,276,214,286,220,161,214,286,209,125,222,179,223,189,223,242,223,242,223,189,223,200,223,242,223,200,224,233,224,233,223,200,224,212,224,233,224,212,224,223,206,304,193,317,193,88,193,88,193,317,178,329,193,88,178,329,173,53,173,53,178,329,162,203,63,20,70,17,76,75,76,75,70,17,83,11,76,75,83,11,86,70,86,70,83,11,97,3,86,70,97,3,100,62,100,62,97,3,111,-4,100,62,111,-4,116,54,116,54,111,-4,122,-10,116,54,122,-10,129,47,76,75,30,2,41,-3,76,75,41,-3,46,3,76,75,46,3,51,9,76,75,51,9,56,14,76,75,56,14,60,17,76,75,60,17,63,20,97,330,108,332,118,348,97,330,118,348,89,344,97,330,89,344,87,325,63,335,43,319,45,229,63,335,45,229,62,214,63,335,62,214,76,197,63,335,76,197,75,299,31,247,45,229,43,319,31,247,43,319,30,297,31,247,30,297,25,270,95,259,97,145,112,245,112,245,97,145,115,161,112,245,115,161,126,227,126,227,115,161,128,180,126,227,128,180,132,200,74,132,97,145,79,163,74,132,79,163,73,153,74,132,73,153,64,144,74,132,64,144,54,138,74,132,54,138,49,123,54,138,45,134,49,123,276,149,289,208,269,162,269,162,289,208,268,192,269,162,268,192,257,170,257,170,268,192,238,182,235,304,245,310,272,352,272,352,245,310,255,313,272,352,255,313,266,314,266,314,283,310,272,352,272,352,283,310,308,348,312,266,331,203,335,337,335,337,331,203,348,218,335,337,348,218,355,321,355,321,348,218,361,236,355,321,361,236,367,300,367,300,361,236,368,256,367,300,368,256,371,277,310,278,312,266,335,337,310,278,335,337,308,348,310,278,308,348,305,291,308,348,283,310,296,302,308,348,296,302,305,291,310,246,303,226,309,191,310,246,309,191,331,203,310,246,331,203,312,266,309,190,309,191,303,226,309,190,303,226,313,1,309,190,313,1,335,159,402,52,396,46,403,36,403,36,396,46,390,41,403,36,390,41,388,24,388,24,390,41,384,36,388,24,384,36,379,35,379,35,361,47,372,11,372,11,361,47,355,0,313,1,333,-10,335,159,335,159,333,-10,339,-10,335,159,339,-10,347,119,347,119,339,-10,355,0,347,119,355,0,353,78,353,78,355,0,361,47,283,94,284,70,289,208,289,208,284,70,289,44,289,208,289,44,303,226,303,226,289,44,298,21,303,226,298,21,313,1,276,149,280,132,289,208,289,208,280,132,282,113,289,208,282,113,283,94,406,57,402,52,403,36,406,57,403,36,415,47,379,35,372,11,388,24,272,352,206,304,214,286,272,352,214,286,225,297,272,352,225,297,235,304,206,304,193,88,209,125,206,304,209,125,214,286,161,231,162,203,178,329,161,231,178,329,160,339,222,179,257,170,238,182,162,165,173,53,162,203,222,179,223,242,222,253, 429,110,429,143,125,143,121,145,119,147,117,150,117,155,119,161,123,167,132,176,141,186,149,195,165,215,155,224,134,202,112,180,89,160,63,143,36,129,36,124,63,110,89,93,112,73,134,51,154,29,164,39,157,49,149,59,140,68,132,78,123,86,120,89,118,92,116,96,116,99,117,102,119,105,122,107,126,109,129,110, 121,145,119,147,119,105,119,105,119,147,117,150,119,105,117,150,117,102,117,102,117,150,117,153,116,99,112,180,112,73,112,73,112,180,89,160,112,73,89,160,89,93,89,93,89,160,63,143,89,93,63,143,63,110,63,110,63,143,36,129,63,110,36,129,36,124,155,224,134,202,141,186,155,224,141,186,149,195,155,224,149,195,157,205,155,224,157,205,165,215,134,202,112,180,118,158,134,202,118,158,119,161,134,202,119,161,121,164,134,202,121,164,123,167,134,202,123,167,132,176,134,202,132,176,141,186,117,155,118,158,112,180,117,155,112,180,117,153,140,68,132,78,134,51,134,51,132,78,123,86,134,51,123,86,120,89,129,143,125,143,126,109,129,143,126,109,129,110,129,143,129,110,429,110,129,143,429,110,429,143,122,107,126,109,125,143,122,107,125,143,121,145,122,107,121,145,119,105,154,29,164,39,157,49,154,29,157,49,149,59,154,29,149,59,140,68,154,29,140,68,134,51,116,96,116,99,112,73,116,96,112,73,117,94,117,94,112,73,134,51,117,94,134,51,118,92,118,92,134,51,120,89,117,102,117,153,116,99,117,153,112,180,116,99, 225,212,203,232,181,254,162,278,144,303,130,331,125,331,111,303,94,278,74,254,52,233,30,213,40,203,49,210,69,226,79,235,88,243,90,246,93,248,97,250,100,251,103,250,109,244,111,238,111,-77,144,-77,144,237,145,242,146,246,148,248,151,250,157,250,159,249,168,243,177,234,187,226,197,217,206,209,216,202, 90,246,93,248,94,278,94,278,93,248,95,249,94,278,95,249,111,303,111,303,95,249,97,250,111,303,97,250,100,251,100,251,103,250,111,303,111,303,103,250,106,247,111,303,106,247,109,244,110,241,111,238,111,303,111,303,111,238,125,331,125,331,111,238,144,-77,125,331,144,-77,130,331,130,331,144,-77,144,237,130,331,144,237,144,303,144,303,144,237,145,242,144,303,145,242,146,246,88,243,90,246,94,278,88,243,94,278,79,235,79,235,94,278,74,254,79,235,74,254,69,226,69,226,74,254,59,218,52,233,30,213,40,203,52,233,40,203,49,210,52,233,49,210,59,218,52,233,59,218,74,254,146,246,148,248,162,278,162,278,148,248,151,250,162,278,151,250,154,250,154,250,157,250,162,278,162,278,157,250,159,249,162,278,159,249,162,247,187,226,197,217,203,232,203,232,197,217,206,209,203,232,206,209,225,212,225,212,206,209,216,202,181,254,162,278,162,247,181,254,162,247,165,245,181,254,165,245,168,243,181,254,168,243,177,234,181,254,177,234,187,226,181,254,187,226,203,232,111,238,111,-77,144,-77,144,303,146,246,162,278,111,303,109,244,110,241, 428,129,400,143,375,160,352,180,330,201,310,224,300,214,314,194,323,185,332,175,340,166,343,164,345,161,347,159,347,157,348,154,347,151,341,145,338,144,334,143,35,143,35,110,334,110,339,109,343,108,345,106,347,103,347,97,346,95,340,86,331,77,322,67,314,58,306,48,299,38,309,28,330,51,351,72,375,92,400,110,428,124, 347,97,351,72,347,100,347,100,351,72,348,154,348,154,351,72,352,180,352,180,351,72,375,92,352,180,375,92,375,160,375,160,375,92,400,110,375,160,400,110,400,143,400,143,400,110,428,124,400,143,428,124,428,129,352,180,330,201,332,175,352,180,332,175,340,166,352,180,340,166,343,164,352,180,343,164,345,161,352,180,345,161,347,159,352,180,347,159,347,157,352,180,347,157,348,154,300,214,307,204,310,224,310,224,307,204,314,194,310,224,314,194,330,201,330,201,314,194,323,185,330,201,323,185,332,175,35,143,334,110,334,143,338,144,334,143,339,109,338,144,339,109,341,145,341,145,339,109,343,108,341,145,343,108,344,148,344,148,343,108,345,106,344,148,345,106,347,151,347,151,345,106,347,103,347,151,347,103,347,100,322,67,330,51,331,77,331,77,330,51,351,72,331,77,351,72,340,86,340,86,351,72,342,89,351,72,347,97,346,95,351,72,346,95,344,92,351,72,344,92,342,89,314,58,306,48,309,28,314,58,309,28,330,51,314,58,330,51,322,67,348,154,347,151,347,100,334,110,35,143,35,110,334,143,334,110,339,109,309,28,306,48,299,38, 216,50,206,43,186,27,168,9,165,7,163,5,160,3,158,3,156,2,153,3,147,9,145,12,145,331,112,331,112,16,111,11,110,8,105,3,99,3,96,4,90,8,88,10,78,19,69,28,49,44,40,51,30,41,53,20,74,-1,94,-24,111,-49,126,-77,131,-77,145,-49,162,-24,182,-1,203,20,225,41, 110,8,107,5,111,-49,111,-49,107,5,105,3,111,-49,105,3,102,3,102,3,99,3,111,-49,111,-49,99,3,96,4,111,-49,96,4,94,-24,94,-24,96,4,93,6,94,-24,93,6,90,8,150,6,147,9,162,-24,162,-24,147,9,145,12,162,-24,145,12,145,-49,145,-49,145,12,145,16,145,16,145,331,131,-77,131,-77,145,331,126,-77,145,331,112,331,126,-77,126,-77,112,331,112,16,126,-77,112,16,111,-49,111,-49,112,16,111,11,111,-49,111,11,110,8,163,5,160,3,162,-24,162,-24,160,3,158,3,162,-24,158,3,156,2,156,2,153,3,162,-24,162,-24,153,3,150,6,186,27,177,18,182,-1,182,-1,177,18,168,9,182,-1,168,9,165,7,206,43,196,35,203,20,206,43,203,20,225,41,206,43,225,41,216,50,186,27,182,-1,203,20,186,27,203,20,196,35,163,5,162,-24,182,-1,163,5,182,-1,165,7,90,8,88,10,94,-24,94,-24,88,10,78,19,94,-24,78,19,74,-1,74,-1,78,19,69,28,74,-1,69,28,59,36,53,20,74,-1,59,36,53,20,59,36,49,44,53,20,49,44,40,51,53,20,40,51,30,41,145,-49,145,16,131,-77, 444,129,417,143,391,160,368,180,346,201,325,224,315,214,322,204,330,194,339,185,348,175,359,164,361,161,363,157,363,154,362,151,360,148,357,145,354,144,350,143,108,143,104,145,102,147,100,150,100,155,101,158,107,167,116,176,125,186,133,195,141,205,148,215,138,224,96,180,72,160,47,143,19,129,19,124,47,110,72,93,95,73,117,51,137,29,147,39,133,59,124,68,115,78,104,89,102,92,100,94,100,96,99,99,100,102,103,105,109,109,113,110,350,110,355,109,358,108,361,106,363,100,362,97,362,95,356,86,347,77,338,67,330,58,322,48,315,38,325,28,345,51,367,72,391,92,417,110,444,124, 104,145,102,147,103,105,103,105,102,147,100,150,103,105,100,150,100,102,100,102,100,150,100,153,99,99,96,180,95,73,95,73,96,180,72,160,95,73,72,160,72,93,72,93,72,160,47,143,72,93,47,143,47,110,47,110,47,143,19,129,47,110,19,129,19,124,138,224,117,202,125,186,138,224,125,186,133,195,138,224,133,195,141,205,138,224,141,205,148,215,117,202,96,180,101,158,117,202,101,158,103,161,117,202,103,161,105,164,117,202,105,164,107,167,117,202,107,167,116,176,117,202,116,176,125,186,100,155,101,158,96,180,100,155,96,180,100,153,124,68,115,78,117,51,117,51,115,78,107,86,117,51,107,86,104,89,137,29,147,39,140,49,137,29,140,49,133,59,137,29,133,59,124,68,137,29,124,68,117,51,363,100,367,72,363,154,363,154,367,72,368,180,368,180,367,72,391,92,368,180,391,92,391,160,391,160,391,92,417,110,391,160,417,110,417,143,417,143,417,110,444,124,417,143,444,124,444,129,368,180,346,201,348,175,368,180,348,175,357,166,368,180,357,166,359,164,368,180,359,164,361,161,368,180,361,161,362,159,368,180,362,159,363,157,368,180,363,157,363,154,315,214,322,204,325,224,325,224,322,204,330,194,325,224,330,194,346,201,346,201,330,194,339,185,346,201,339,185,348,175,350,110,355,109,350,143,354,144,350,143,355,109,354,144,355,109,357,145,357,145,355,109,358,108,357,145,358,108,360,148,360,148,358,108,361,106,360,148,361,106,362,151,362,151,361,106,362,103,362,151,362,103,363,100,338,67,345,51,347,77,347,77,345,51,367,72,347,77,367,72,356,86,356,86,367,72,358,89,362,97,362,95,367,72,362,97,367,72,363,100,360,92,358,89,367,72,360,92,367,72,362,95,330,58,322,48,325,28,330,58,325,28,345,51,330,58,345,51,338,67,363,154,362,151,363,100,350,110,350,143,113,110,113,110,350,143,113,143,113,110,113,143,109,109,108,143,104,145,106,107,108,143,106,107,109,109,108,143,109,109,113,143,100,96,99,99,95,73,100,96,95,73,100,94,100,94,95,73,117,51,100,94,117,51,102,92,102,92,117,51,104,89,100,102,100,153,99,99,104,145,103,105,106,107,325,28,322,48,315,38,100,153,96,180,99,99, 225,246,203,266,182,288,162,312,145,337,131,365,126,365,112,337,94,312,74,288,53,267,31,247,40,237,50,244,70,260,79,269,88,277,93,282,96,283,100,285,104,284,107,281,111,275,112,272,112,-16,111,-21,110,-25,107,-28,105,-29,102,-30,93,-27,90,-25,88,-22,78,-13,69,-5,59,2,49,10,40,17,30,7,53,-12,74,-34,94,-58,111,-83,126,-111,131,-111,145,-83,162,-58,181,-34,203,-12,225,7,215,17,206,10,196,2,186,-5,163,-28,160,-29,158,-30,156,-30,153,-29,150,-27,147,-24,145,-20,145,276,147,280,149,282,152,284,157,284,160,283,169,277,178,268,187,260,197,251,206,243,216,236, 69,-5,74,-34,78,-13,78,-13,74,-34,94,-58,78,-13,94,-58,88,-22,88,-22,94,-58,90,-25,91,280,93,282,94,312,94,312,93,282,96,283,94,312,96,283,112,337,112,337,96,283,98,284,112,337,98,284,100,285,100,285,104,284,112,337,112,337,104,284,107,281,112,337,107,281,109,278,110,-25,107,-28,111,-83,111,-83,107,-28,105,-29,111,-83,105,-29,102,-30,102,-30,99,-29,111,-83,111,-83,99,-29,96,-28,111,-83,96,-28,94,-58,94,-58,96,-28,93,-27,94,-58,93,-27,90,-25,109,278,111,275,112,337,112,337,111,275,112,272,112,272,126,-111,126,365,126,365,126,-111,131,-111,126,365,131,-111,131,365,131,365,131,-111,145,-83,131,365,145,-83,145,271,145,271,145,-83,145,-17,88,277,91,280,94,312,88,277,94,312,79,269,79,269,94,312,74,288,79,269,74,288,70,260,70,260,74,288,60,252,53,267,31,247,40,237,53,267,40,237,50,244,53,267,50,244,60,252,53,267,60,252,74,288,147,280,149,282,162,312,162,312,149,282,152,284,162,312,152,284,155,284,155,284,157,284,162,312,162,312,157,284,160,283,162,312,160,283,163,281,187,260,197,251,203,266,203,266,197,251,206,243,203,266,206,243,225,246,225,246,206,243,216,236,182,288,162,312,163,281,182,288,163,281,166,279,182,288,166,279,169,277,182,288,169,277,178,268,182,288,178,268,187,260,182,288,187,260,203,266,145,337,131,365,145,271,145,337,145,271,145,276,145,337,145,276,147,280,145,337,147,280,162,312,163,-28,160,-29,162,-58,162,-58,160,-29,158,-30,162,-58,158,-30,156,-30,156,-30,153,-29,162,-58,162,-58,153,-29,150,-27,162,-58,150,-27,147,-24,186,-5,177,-14,181,-34,181,-34,177,-14,168,-23,181,-34,168,-23,165,-26,206,10,196,2,203,-12,206,10,203,-12,225,7,206,10,225,7,215,17,186,-5,181,-34,203,-12,186,-5,203,-12,196,2,163,-28,162,-58,181,-34,163,-28,181,-34,165,-26,145,-20,145,-17,145,-83,145,-20,145,-83,162,-58,145,-20,162,-58,147,-24,112,-16,111,-21,111,-83,112,-16,111,-83,126,-111,112,-16,126,-111,112,272,59,2,49,10,53,-12,59,2,53,-12,74,-34,59,2,74,-34,69,-5,40,17,30,7,53,-12,40,17,53,-12,49,10,110,-25,111,-83,111,-21,112,337,112,272,126,365, 428,-54,118,271,115,274,111,280,110,282,110,285,111,287,111,288,112,290,113,291,115,292,117,294,121,295,124,296,153,296,166,297,178,298,190,300,190,315,182,314,173,313,125,313,103,315,81,318,60,324,39,331,35,328,43,306,48,285,51,263,53,241,54,219,53,210,53,193,52,184,51,176,65,176,68,188,70,214,70,243,72,249,73,251,76,254,77,254,78,255,83,255,85,254,88,254,92,252,404,-77, 48,285,51,263,60,324,60,324,51,263,53,241,60,324,53,241,54,219,54,219,53,210,65,176,65,176,53,210,53,201,65,176,53,201,53,193,60,324,39,331,43,306,60,324,43,306,48,285,77,254,78,255,81,318,81,318,78,255,79,255,81,318,79,255,80,255,80,255,83,255,81,318,81,318,83,255,103,315,81,318,60,324,71,246,81,318,71,246,72,249,81,318,72,249,73,251,81,318,73,251,75,253,81,318,75,253,76,254,81,318,76,254,77,254,65,176,68,188,70,243,70,243,68,188,69,201,70,243,69,201,70,239,70,239,69,201,70,214,70,239,70,214,70,226,60,324,54,219,65,176,60,324,65,176,70,243,60,324,70,243,71,246,52,184,51,176,65,176,52,184,65,176,53,193,103,315,92,252,110,282,103,315,110,282,110,284,110,284,110,285,103,315,103,315,110,285,111,287,103,315,111,287,111,288,103,315,83,255,85,254,103,315,85,254,88,254,103,315,88,254,90,253,103,315,90,253,92,252,103,315,111,288,125,313,125,313,111,288,112,290,125,313,112,290,113,291,113,291,115,292,125,313,125,313,115,292,117,294,125,313,117,294,121,295,147,313,127,296,140,296,147,313,140,296,153,296,147,313,147,312,125,313,147,313,125,313,127,296,165,313,166,297,173,313,173,313,166,297,178,298,173,313,178,298,182,314,182,314,178,298,190,300,182,314,190,300,190,315,156,313,147,312,147,313,156,313,147,313,153,296,156,313,153,296,166,297,156,313,166,297,165,313,124,296,127,296,125,313,124,296,125,313,121,295,428,-54,118,271,404,-77,404,-77,118,271,115,274,404,-77,115,274,92,252,92,252,115,274,113,277,92,252,113,277,111,280,43,306,39,331,35,328,92,252,111,280,110,282, 425,331,403,324,382,318,360,315,338,313,289,313,281,314,272,315,272,300,284,298,297,297,309,296,339,296,342,295,346,294,348,292,350,291,351,290,352,288,353,287,353,282,352,280,348,274,345,271,35,-54,59,-77,372,252,373,253,375,254,377,254,380,255,385,255,387,254,388,254,388,253,390,251,391,249,392,246,392,226,393,214,395,188,397,176,411,176,411,185,410,193,410,241,412,263,415,285,421,307,428,328, 272,315,272,315,281,314,281,314,272,315,284,298,281,314,284,298,289,313,289,313,284,298,297,297,289,313,297,297,298,313,298,313,297,297,309,296,298,313,309,296,307,313,307,313,309,296,315,313,338,313,315,313,322,296,338,313,322,296,335,296,375,254,377,254,382,318,382,318,377,254,380,255,382,318,380,255,382,255,382,255,384,255,403,324,403,324,384,255,385,255,403,324,385,255,387,254,353,285,353,284,360,315,360,315,353,284,372,252,360,315,372,252,382,318,382,318,372,252,373,253,382,318,373,253,375,254,372,252,353,284,353,282,372,252,353,282,352,280,372,252,352,280,350,277,372,252,350,277,348,274,372,252,348,274,345,271,372,252,345,271,59,-77,410,193,410,201,403,324,403,324,410,201,410,210,403,324,410,210,410,219,410,219,410,241,403,324,403,324,410,241,412,263,403,324,412,263,415,285,403,324,415,285,425,331,425,331,415,285,421,307,425,331,421,307,428,328,395,188,397,176,403,324,403,324,397,176,411,176,403,324,411,176,410,193,410,193,411,176,411,185,403,324,387,254,388,254,403,324,388,254,388,253,403,324,388,253,390,251,403,324,390,251,391,249,403,324,391,249,392,246,403,324,392,246,392,243,403,324,392,243,392,239,403,324,392,239,392,226,403,324,392,226,393,214,403,324,393,214,394,201,403,324,394,201,395,188,403,324,382,318,382,255,360,315,338,313,339,296,360,315,339,296,342,295,360,315,342,295,346,294,360,315,346,294,348,292,360,315,348,292,350,291,360,315,350,291,351,290,360,315,351,290,352,288,360,315,352,288,353,287,360,315,353,287,353,285,335,296,339,296,338,313,315,313,309,296,322,296,59,-77,345,271,35,-54,284,298,272,315,272,300, 428,-74,421,-53,415,-31,412,-9,410,12,410,60,411,68,411,76,397,77,395,65,392,26,392,7,391,4,390,2,387,-1,380,-1,377,0,373,0,372,2,59,331,35,307,345,-17,348,-20,352,-26,353,-28,353,-33,352,-34,351,-36,350,-36,346,-40,342,-41,335,-41,322,-42,309,-42,297,-43,284,-45,272,-46,272,-60,281,-60,289,-59,338,-59,360,-61,382,-65,403,-70,425,-77, 335,-41,322,-42,338,-59,338,-59,322,-42,315,-59,307,-59,315,-59,309,-42,307,-59,309,-42,298,-59,298,-59,309,-42,297,-43,298,-59,297,-43,289,-59,289,-59,297,-43,284,-45,289,-59,284,-45,281,-60,281,-60,284,-45,272,-46,281,-60,272,-46,272,-60,322,-42,309,-42,315,-59,353,-33,352,-34,360,-61,360,-61,352,-34,351,-36,360,-61,351,-36,350,-36,372,2,59,331,345,-17,372,2,345,-17,348,-20,372,2,348,-20,350,-23,372,2,350,-23,352,-26,372,2,352,-26,353,-28,372,2,353,-28,353,-30,372,2,353,-30,360,-61,372,2,360,-61,382,-65,372,2,382,-65,373,0,387,-1,385,-1,403,-70,403,-70,385,-1,384,-1,403,-70,384,-1,382,-1,382,-1,380,-1,382,-65,382,-65,380,-1,377,0,382,-65,377,0,375,0,360,-61,353,-30,353,-32,360,-61,353,-32,353,-33,393,39,392,26,403,-70,403,-70,392,26,392,14,403,-70,392,14,392,10,415,-31,412,-9,403,-70,403,-70,412,-9,410,12,403,-70,410,12,410,35,410,35,410,43,403,-70,403,-70,410,43,410,52,403,-70,410,52,410,60,411,76,397,77,403,-70,411,76,403,-70,410,60,411,76,410,60,411,68,403,-70,397,77,395,65,403,-70,395,65,394,52,403,-70,394,52,393,39,403,-70,392,10,392,7,403,-70,392,7,391,4,403,-70,391,4,390,2,403,-70,390,2,388,0,403,-70,388,0,387,-1,382,-1,382,-65,403,-70,425,-77,428,-74,421,-53,425,-77,421,-53,415,-31,425,-77,415,-31,403,-70,360,-61,350,-36,348,-38,360,-61,348,-38,346,-40,360,-61,346,-40,342,-41,360,-61,342,-41,339,-41,360,-61,339,-41,338,-59,339,-41,335,-41,338,-59,345,-17,59,331,35,307,373,0,382,-65,375,0, 428,307,404,331,92,2,90,0,88,0,85,-1,77,-1,76,0,75,0,73,2,72,4,70,10,70,39,68,65,65,77,51,76,53,60,53,43,54,35,53,12,51,-9,48,-31,43,-53,35,-74,39,-77,60,-70,81,-65,103,-61,125,-59,173,-59,182,-60,190,-60,190,-46,178,-45,166,-43,153,-42,140,-42,127,-41,121,-41,117,-40,113,-36,112,-36,111,-34,111,-33,110,-32,110,-28,111,-26,115,-20,118,-17, 78,-1,81,-65,79,-1,79,-1,81,-65,80,-1,83,-1,80,-1,81,-65,83,-1,81,-65,103,-61,111,-34,111,-33,103,-61,103,-61,111,-33,110,-32,103,-61,110,-32,110,-30,110,-30,110,-28,103,-61,103,-61,110,-28,92,2,103,-61,92,2,90,0,115,-20,118,-17,404,331,115,-20,404,331,92,2,404,331,118,-17,428,307,92,2,110,-28,111,-26,92,2,111,-26,113,-23,92,2,113,-23,115,-20,103,-61,90,0,88,0,103,-61,88,0,85,-1,103,-61,85,-1,83,-1,147,-59,140,-42,127,-41,147,-59,127,-41,125,-59,147,-59,153,-42,140,-42,156,-59,165,-59,166,-43,166,-43,165,-59,173,-59,166,-43,173,-59,178,-45,178,-45,173,-59,182,-60,178,-45,182,-60,190,-46,190,-46,182,-60,190,-60,156,-59,166,-43,153,-42,156,-59,153,-42,147,-59,121,-41,117,-40,125,-59,125,-59,117,-40,115,-38,125,-59,115,-38,113,-36,124,-41,121,-41,125,-59,124,-41,125,-59,127,-41,125,-59,113,-36,112,-36,125,-59,112,-36,111,-34,125,-59,111,-34,103,-61,81,-65,78,-1,77,-1,81,-65,77,-1,76,0,81,-65,76,0,75,0,81,-65,75,0,73,2,81,-65,73,2,72,4,81,-65,72,4,71,7,81,-65,71,7,60,-70,70,10,70,14,69,52,70,10,69,52,68,65,70,10,68,65,65,77,70,10,65,77,60,-70,70,10,60,-70,71,7,70,39,69,52,70,14,70,39,70,14,70,26,60,-70,65,77,54,35,60,-70,54,35,53,12,60,-70,53,12,51,-9,60,-70,51,-9,48,-31,60,-70,48,-31,43,-53,60,-70,43,-53,39,-77,53,60,53,51,65,77,65,77,53,51,53,43,65,77,53,43,54,35,65,77,51,76,52,68,65,77,52,68,53,60,43,-53,35,-74,39,-77, 279,331,243,331,206,232,74,232,36,331,1,331,123,0,156,0,16383,16383,195,201,140,51,84,201, 156,0,279,331,195,201,195,201,279,331,206,232,195,201,206,232,84,201,84,201,206,232,74,232,84,201,74,232,123,0,123,0,74,232,36,331,123,0,36,331,1,331,140,51,84,201,123,0,140,51,123,0,156,0,140,51,156,0,195,201,206,232,279,331,243,331, 202,110,169,110,169,65,165,48,155,37,141,30,128,27,117,26,107,26,92,29,78,36,67,47,63,65,63,308,67,326,78,337,92,344,105,346,116,347,126,347,140,344,154,338,165,326,169,307,169,262,202,262,202,305,196,339,180,360,158,373,136,379,117,380,97,379,74,373,52,361,36,339,30,306,30,65,36,32,51,11,72,0,94,-5,114,-6,134,-5,157,0,179,10,196,30,202,61, 105,346,116,347,116,347,117,380,116,347,126,347,117,380,126,347,136,379,136,379,126,347,140,344,136,379,140,344,158,373,158,373,140,344,154,338,158,373,154,338,165,326,202,305,196,339,202,262,202,262,196,339,180,360,202,262,180,360,169,307,169,307,180,360,165,326,78,337,92,344,97,379,97,379,92,344,105,346,97,379,105,346,117,380,117,380,105,346,116,347,74,373,52,361,63,308,74,373,63,308,67,326,74,373,67,326,78,337,74,373,78,337,97,379,30,306,30,65,36,32,30,306,36,32,36,339,36,339,36,32,51,11,36,339,51,11,52,361,52,361,51,11,63,65,52,361,63,65,63,308,165,48,155,37,157,0,157,0,155,37,141,30,157,0,141,30,134,-5,134,-5,141,30,128,27,134,-5,128,27,117,26,117,26,107,26,114,-6,114,-6,107,26,94,-5,107,26,92,29,94,-5,94,-5,92,29,78,36,94,-5,78,36,72,0,72,0,78,36,67,47,72,0,67,47,63,65,63,65,51,11,72,0,202,110,169,110,179,10,202,110,179,10,196,30,202,110,196,30,202,61,179,10,169,110,169,65,179,10,169,65,165,48,179,10,165,48,157,0,117,26,114,-6,134,-5,202,262,169,307,169,262,158,373,165,326,180,360, 98,313,112,317,119,318,127,319,134,319,161,314,179,300,191,279,198,255,200,228,200,221,199,214,199,207,198,200,196,194,189,203,180,210,169,214,159,217,148,218,107,210,72,188,44,156,26,117,20,75,22,51,30,29,43,11,62,0,88,-5,148,9,190,47,217,98,231,154,235,204,232,250,220,287,202,313,175,329,142,334,131,334,121,333,101,327,93,323,16383,16383,184,160,182,140,180,131,178,121,176,110,166,80,152,53,135,30,116,15,94,9,78,13,68,21,63,33,61,46,60,59,65,100,79,139,99,172,124,194,153,203,161,201,169,197,177,189,182,176,184,160, 127,319,134,319,134,319,142,334,134,319,161,314,142,334,161,314,175,329,175,329,161,314,179,300,175,329,179,300,202,313,202,313,179,300,191,279,202,313,191,279,198,255,112,317,119,318,121,333,121,333,119,318,127,319,121,333,127,319,131,334,131,334,127,319,134,319,131,334,134,319,142,334,93,323,98,313,101,327,101,327,98,313,105,315,101,327,105,315,111,330,111,330,105,315,112,317,111,330,112,317,121,333,152,53,135,30,148,9,148,9,135,30,116,15,148,9,116,15,94,9,94,9,78,13,88,-5,88,-5,78,13,68,21,88,-5,68,21,62,0,62,0,68,21,63,33,62,0,63,33,61,46,61,46,60,59,62,0,62,0,60,59,44,156,44,156,60,59,72,188,72,188,60,59,65,100,20,75,22,51,26,117,26,117,22,51,30,29,26,117,30,29,44,156,44,156,30,29,43,11,44,156,43,11,62,0,159,217,153,203,161,201,159,217,161,201,169,214,169,214,161,201,169,197,169,214,169,197,180,210,180,210,169,197,177,189,180,210,177,189,182,176,79,139,99,172,107,210,107,210,99,172,124,194,107,210,124,194,148,218,148,218,124,194,153,203,148,218,153,203,159,217,72,188,65,100,79,139,72,188,79,139,107,210,182,140,180,131,190,47,190,47,180,131,178,121,190,47,178,121,176,110,176,110,166,80,190,47,190,47,166,80,152,53,190,47,152,53,148,9,198,200,196,194,217,98,217,98,196,194,190,47,190,47,196,194,189,203,190,47,189,203,184,160,184,160,189,203,182,176,190,47,184,160,183,150,190,47,183,150,182,140,94,9,88,-5,148,9,235,204,232,250,231,154,231,154,232,250,220,287,231,154,220,287,217,98,217,98,220,287,202,313,217,98,202,313,200,228,200,228,202,313,198,255,217,98,200,228,200,221,217,98,200,221,199,214,217,98,199,214,199,207,217,98,199,207,198,200,180,210,182,176,189,203, 243,0,243,331,36,331,36,298,210,298,210,182,42,182,42,149,210,149,210,33,36,33,36,0, 42,182,210,149,210,182,210,182,210,149,243,0,210,182,243,0,210,298,210,298,243,0,243,331,210,298,243,331,36,331,243,0,210,149,210,33,243,0,210,33,36,33,243,0,36,33,36,0,210,298,36,331,36,298,210,149,42,182,42,149, 243,0,243,331,199,331,219,387,190,387,170,331,36,331,36,298,159,298,119,182,42,182,42,149,108,149,68,33,36,33,36,0,56,0,36,-60,65,-60,85,0,16383,16383,210,182,148,182,188,298,210,298,16383,16383,210,33,97,33,137,149,210,149, 36,331,159,298,170,331,170,331,159,298,188,298,170,331,188,298,190,387,190,387,188,298,199,331,190,387,199,331,219,387,159,298,137,149,148,182,148,182,137,149,210,149,148,182,210,149,210,182,210,182,210,149,243,0,210,182,243,0,210,298,210,298,243,0,243,331,210,298,243,331,199,331,159,298,119,182,137,149,137,149,119,182,108,149,137,149,108,149,97,33,97,33,108,149,85,0,97,33,85,0,243,0,68,33,36,33,56,0,68,33,56,0,65,-60,68,33,65,-60,85,0,68,33,85,0,108,149,210,33,97,33,243,0,210,33,243,0,210,149,42,182,42,149,108,149,42,182,108,149,119,182,65,-60,56,0,36,-60,159,298,36,331,36,298,56,0,36,33,36,0,159,298,148,182,188,298,199,331,188,298,210,298, 353,291,318,291,289,258,272,270,253,279,233,285,212,290,190,291,138,283,93,259,57,223,34,178,25,126,27,100,33,75,43,51,56,30,72,11,28,-39,63,-39,92,-6,110,-17,129,-26,148,-33,169,-37,190,-39,242,-30,288,-6,324,28,348,74,356,126,354,152,348,176,338,200,325,221,309,241,16383,16383,287,217,300,201,310,184,317,166,322,147,323,127,316,85,297,48,269,19,232,0,190,-6,174,-5,158,-2,142,2,127,9,113,18,16383,16383,94,36,81,51,71,68,64,86,60,106,58,127,65,168,84,205,112,233,148,252,190,258,208,257,225,254,241,248,256,241,267,233, 323,127,316,85,324,28,324,28,316,85,297,48,324,28,297,48,288,-6,288,-6,297,48,269,19,288,-6,269,19,242,-30,242,-30,269,19,232,0,242,-30,232,0,190,-39,190,-39,232,0,190,-6,127,9,129,-26,142,2,142,2,129,-26,148,-33,142,2,148,-33,158,-2,158,-2,148,-33,169,-37,158,-2,169,-37,174,-5,174,-5,169,-37,190,-39,174,-5,190,-39,190,-6,127,9,113,18,129,-26,267,233,113,18,287,217,267,233,287,217,272,270,129,-26,113,18,110,-17,110,-17,113,18,94,36,110,-17,94,36,92,-6,92,-6,94,36,81,51,92,-6,81,51,72,11,72,11,81,51,71,68,72,11,71,68,64,86,58,127,65,168,57,223,58,127,57,223,56,30,58,127,56,30,60,106,60,106,56,30,72,11,60,106,72,11,64,86,27,100,33,75,34,178,34,178,33,75,43,51,34,178,43,51,57,223,57,223,43,51,56,30,267,233,272,270,256,241,256,241,272,270,253,279,256,241,253,279,241,248,241,248,253,279,233,285,241,248,233,285,225,254,225,254,233,285,212,290,225,254,212,290,208,257,208,257,212,290,190,258,148,252,190,258,190,291,148,252,190,291,138,283,65,168,84,205,93,259,93,259,84,205,112,233,93,259,112,233,138,283,138,283,112,233,148,252,212,290,190,291,190,258,318,291,289,258,300,201,318,291,300,201,309,241,318,291,309,241,353,291,289,258,272,270,287,217,289,258,287,217,300,201,63,-39,92,-6,72,11,63,-39,72,11,28,-39,348,176,338,200,348,74,348,176,348,74,356,126,348,176,356,126,354,152,325,221,309,241,310,184,325,221,310,184,317,166,325,221,317,166,322,147,325,221,322,147,323,127,325,221,323,127,324,28,325,221,324,28,348,74,325,221,348,74,338,200,310,184,309,241,300,201,94,36,113,18,267,233,57,223,65,168,93,259,27,100,34,178,25,126, 333,0,185,337,175,337,31,0,16383,16383,272,21,63,21,167,267, 175,337,31,0,63,21,63,21,31,0,333,0,63,21,333,0,272,21,272,21,333,0,185,337,272,21,185,337,175,337,175,337,63,21,167,267,175,337,167,267,272,21, 334,331,31,331,180,-5,190,-5,16383,16383,302,310,197,64,93,310, 334,331,31,331,93,310,334,331,93,310,302,310,334,331,302,310,197,64,334,331,197,64,190,-5,180,-5,190,-5,197,64,180,-5,197,64,93,310,180,-5,93,310,31,331, 313,-12,313,20,167,20,137,24,111,37,89,57,73,82,64,109,313,109,313,142,65,142,74,170,90,195,112,215,138,228,167,233,313,233,313,266,166,266,121,258,84,238,55,207,37,169,30,126,37,83,55,45,84,14,122,-5,167,-12, 55,45,84,14,64,109,64,109,65,142,55,45,55,45,65,142,55,207,55,45,55,207,37,83,37,83,55,207,37,169,37,83,37,169,30,126,65,142,64,109,313,109,65,142,313,109,313,142,90,195,112,215,121,258,121,258,112,215,138,228,121,258,138,228,166,266,166,266,138,228,167,233,166,266,167,233,313,266,313,266,167,233,313,233,84,238,55,207,65,142,84,238,65,142,74,170,84,238,74,170,90,195,84,238,90,195,121,258,167,-12,313,-12,313,20,167,-12,313,20,167,20,167,-12,167,20,137,24,167,-12,137,24,122,-5,137,24,111,37,122,-5,122,-5,111,37,89,57,122,-5,89,57,84,14,84,14,89,57,73,82,84,14,73,82,64,109, 313,-12,313,20,154,20,148,22,142,23,136,25,179,109,313,109,313,142,195,142,239,233,313,233,313,266,256,266,289,331,257,331,225,266,166,266,121,258,84,238,55,207,37,169,30,126,33,97,42,70,55,45,73,24,96,7,54,-78,84,-78,121,-5,130,-7,139,-10,157,-12,167,-12,16383,16383,209,233,164,142,65,142,74,170,90,195,112,215,138,228,167,233,16383,16383,147,109,112,37,98,49,86,62,76,77,69,93,64,109, 96,7,96,7,84,-78,96,7,84,-78,121,-5,96,7,121,-5,98,49,96,7,98,49,86,62,96,7,86,62,76,77,96,7,76,77,73,24,55,45,73,24,64,109,64,109,73,24,69,93,69,93,73,24,76,77,161,20,154,20,157,-12,157,-12,154,20,148,22,157,-12,148,22,148,-11,148,-11,148,22,142,23,148,-11,142,23,139,-10,139,-10,142,23,136,25,139,-10,136,25,130,-7,147,109,112,37,121,-5,147,109,121,-5,130,-7,147,109,130,-7,136,25,147,109,136,25,179,109,147,109,179,109,164,142,147,109,164,142,65,142,147,109,65,142,64,109,167,-12,313,-12,313,20,167,-12,313,20,167,20,167,-12,167,20,161,20,167,-12,161,20,157,-12,90,195,112,215,121,258,121,258,112,215,138,228,121,258,138,228,166,266,166,266,138,228,167,233,166,266,167,233,225,266,225,266,167,233,209,233,225,266,209,233,239,233,239,233,209,233,195,142,256,266,289,331,257,331,256,266,257,331,239,233,256,266,239,233,313,233,256,266,313,233,313,266,179,109,313,109,195,142,179,109,195,142,209,233,179,109,209,233,164,142,84,238,55,207,65,142,84,238,65,142,74,170,84,238,74,170,90,195,84,238,90,195,121,258,30,126,33,97,37,169,37,169,33,97,42,70,37,169,42,70,55,207,55,207,42,70,55,45,55,207,55,45,65,142,65,142,55,45,64,109,195,142,313,109,313,142,84,-78,96,7,54,-78,98,49,121,-5,112,37,225,266,239,233,257,331, 211,22,211,55,138,55,116,57,97,64,83,75,72,90,65,109,211,109,211,142,65,142,72,162,82,177,97,188,115,194,137,196,211,196,211,229,137,229,102,224,73,210,51,188,37,159,32,126,37,93,51,65,73,42,102,28,137,22, 83,75,72,90,73,42,73,42,72,90,65,109,73,42,65,109,51,188,73,42,51,188,51,65,51,65,51,188,37,159,51,65,37,159,37,93,37,93,37,159,32,126,82,177,97,188,102,224,102,224,97,188,115,194,102,224,115,194,137,229,137,229,115,194,137,196,51,188,65,109,65,142,65,142,65,109,211,142,211,142,65,109,211,109,211,229,137,229,137,196,211,229,137,196,211,196,73,210,51,188,65,142,73,210,65,142,72,162,73,210,72,162,82,177,73,210,82,177,102,224,97,64,102,28,116,57,116,57,102,28,137,22,116,57,137,22,138,55,138,55,137,22,211,22,138,55,211,22,211,55,83,75,73,42,102,28,83,75,102,28,97,64, 30,266,30,233,175,233,205,228,231,215,253,195,269,170,278,142,30,142,30,109,278,109,269,82,253,57,232,37,205,24,175,20,30,20,30,-12,175,-12,220,-5,258,14,287,45,306,83,312,126,313,126,306,169,288,207,259,238,222,258,177,266, 269,82,253,57,258,14,258,14,253,57,232,37,258,14,232,37,220,-5,220,-5,232,37,205,24,220,-5,205,24,175,20,177,266,30,266,175,233,177,266,175,233,205,228,177,266,205,228,222,258,312,126,306,169,306,83,306,83,306,169,288,207,306,83,288,207,287,45,287,45,288,207,278,109,287,45,278,109,269,82,231,215,253,195,259,238,259,238,253,195,269,170,259,238,269,170,288,207,288,207,269,170,278,142,288,207,278,142,278,109,222,258,205,228,231,215,222,258,231,215,259,238,175,-12,220,-5,175,20,175,-12,175,20,30,20,175,-12,30,20,30,-12,278,109,278,142,30,142,278,109,30,142,30,109,269,82,258,14,287,45,175,233,30,266,30,233, 289,331,257,331,222,258,213,261,204,263,196,264,186,265,177,266,30,266,30,233,175,233,182,232,188,232,194,231,200,229,206,228,164,142,30,142,30,109,147,109,103,20,30,20,30,-12,86,-12,54,-78,84,-78,117,-12,175,-12,220,-5,258,14,287,45,306,83,312,126,313,126,310,155,301,183,287,208,269,229,247,247,16383,16383,195,142,230,214,244,203,256,190,266,175,273,159,278,142,16383,16383,278,109,269,82,253,57,232,37,205,24,175,20,133,20,179,109, 86,-12,54,-78,84,-78,86,-12,84,-78,117,-12,86,-12,117,-12,103,20,86,-12,103,20,30,20,86,-12,30,20,30,-12,147,109,103,20,117,-12,147,109,117,-12,133,20,147,109,133,20,179,109,147,109,179,109,164,142,147,109,164,142,30,142,147,109,30,142,30,109,269,82,253,57,258,14,258,14,253,57,232,37,258,14,232,37,220,-5,220,-5,232,37,205,24,220,-5,205,24,175,20,195,142,230,214,206,228,206,228,213,261,204,263,206,228,204,263,200,229,200,229,204,263,196,264,200,229,196,264,194,231,194,231,196,264,188,232,30,266,175,233,177,266,177,266,175,233,182,232,177,266,182,232,186,265,186,265,182,232,188,232,186,265,188,232,196,264,257,331,222,258,230,214,257,331,230,214,247,247,257,331,247,247,289,331,230,214,244,203,247,247,247,247,244,203,256,190,247,247,256,190,269,229,269,229,256,190,266,175,269,229,266,175,273,159,213,261,206,228,230,214,213,261,230,214,222,258,273,159,278,142,287,208,278,109,278,142,195,142,278,109,195,142,179,109,179,109,195,142,206,228,179,109,206,228,164,142,312,126,310,155,306,83,306,83,310,155,301,183,306,83,301,183,287,45,287,45,301,183,287,208,287,45,287,208,278,109,278,109,287,208,278,142,269,82,258,14,287,45,269,82,287,45,278,109,175,-12,220,-5,175,20,175,-12,175,20,133,20,175,-12,133,20,117,-12,269,229,273,159,287,208,175,233,30,266,30,233, 32,229,32,196,105,196,128,194,146,188,161,177,171,162,177,142,32,142,32,109,177,109,171,90,161,75,146,64,127,57,105,55,32,55,32,22,107,22,141,28,170,42,192,65,206,93,211,126,206,159,192,188,170,210,140,224,105,229, 105,229,32,229,105,229,105,229,32,229,105,196,105,229,105,196,140,224,140,224,105,196,128,194,140,224,128,194,146,188,192,188,177,142,192,65,192,65,177,142,177,109,192,65,177,109,171,90,32,142,32,109,177,109,32,142,177,109,177,142,146,188,161,177,170,210,170,210,161,177,171,162,170,210,171,162,192,188,192,188,171,162,177,142,206,159,192,188,192,65,206,159,192,65,206,93,206,159,206,93,211,126,170,42,192,65,171,90,170,42,171,90,161,75,170,42,161,75,146,64,170,42,146,64,141,28,127,57,105,55,107,22,127,57,107,22,141,28,127,57,141,28,146,64,32,55,32,22,107,22,32,55,107,22,105,55,105,196,32,229,32,196,140,224,146,188,170,210, 243,0,243,320,30,320,30,0, 243,0,243,320,30,320,243,0,30,320,30,0, 474,-128,474,-115,465,-115,447,-112,433,-104,424,-92,418,-74,416,-51,416,307,418,330,423,347,434,359,451,366,474,368,474,382,26,382,26,368,35,368,52,366,66,360,76,349,83,331,85,305,85,-60,83,-80,77,-95,67,-106,54,-112,36,-115,26,-115,26,-128,210,-128,210,-115,195,-115,177,-112,165,-104,157,-91,152,-72,151,-48,151,349,350,349,350,-48,349,-69,344,-88,337,-102,324,-111,306,-115,290,-115,290,-128, 77,-95,67,-106,210,-128,210,-128,67,-106,54,-112,210,-128,54,-112,36,-115,344,-88,337,-102,474,-128,474,-128,337,-102,324,-111,474,-128,324,-111,306,-115,474,382,26,382,35,368,474,382,35,368,52,366,474,382,52,366,66,360,474,382,66,360,76,349,474,382,76,349,151,349,474,382,151,349,350,349,474,382,350,349,434,359,474,382,434,359,451,366,474,382,451,366,474,368,433,-104,424,-92,350,-48,350,-48,424,-92,418,-74,350,-48,418,-74,350,349,350,349,418,-74,416,-51,350,349,416,-51,416,307,350,349,416,307,418,330,350,349,418,330,423,347,350,349,423,347,434,359,165,-104,157,-91,85,-60,85,-60,157,-91,152,-72,85,-60,152,-72,85,305,85,305,152,-72,151,-48,85,305,151,-48,151,349,83,331,85,305,151,349,83,331,151,349,76,349,474,-128,474,-115,465,-115,474,-128,465,-115,447,-112,474,-128,447,-112,433,-104,474,-128,433,-104,349,-69,474,-128,349,-69,344,-88,290,-115,290,-128,474,-128,290,-115,474,-128,306,-115,210,-128,210,-115,195,-115,210,-128,195,-115,177,-112,210,-128,177,-112,83,-80,210,-128,83,-80,77,-95,85,-60,83,-80,177,-112,85,-60,177,-112,165,-104,26,-115,26,-128,210,-128,26,-115,210,-128,36,-115,349,-69,433,-104,350,-48,35,368,26,382,26,368, 474,-128,474,-115,451,-112,434,-106,423,-94,418,-77,416,-54,416,304,418,327,424,345,433,358,447,365,465,368,474,368,474,382,290,382,290,368,306,368,324,364,337,355,344,341,349,322,350,300,350,-96,151,-96,151,300,152,325,157,344,165,357,177,365,195,368,210,368,210,382,26,382,26,368,36,368,54,366,67,359,77,348,83,333,85,313,85,-53,83,-78,76,-96,66,-107,52,-113,35,-115,26,-115,26,-128, 76,-96,66,-107,474,-128,474,-128,66,-107,52,-113,474,-128,52,-113,35,-115,77,348,83,333,210,382,210,382,83,333,177,365,210,382,177,365,195,368,210,382,195,368,210,368,85,313,85,-53,151,-96,85,313,151,-96,151,300,85,313,151,300,152,325,85,313,152,325,157,344,85,313,157,344,165,357,85,313,165,357,177,365,85,313,177,365,83,333,210,382,26,382,36,368,210,382,36,368,54,366,210,382,54,366,67,359,210,382,67,359,77,348,434,-106,423,-94,350,-96,350,-96,423,-94,418,-77,350,-96,418,-77,350,300,349,322,350,300,433,358,349,322,433,358,474,382,474,382,433,358,447,365,474,382,447,365,465,368,474,382,465,368,474,368,416,-54,416,304,350,300,350,300,416,304,418,327,350,300,418,327,424,345,474,382,290,382,306,368,474,382,306,368,324,364,474,382,324,364,337,355,474,382,337,355,344,341,474,382,344,341,349,322,474,-128,474,-115,451,-112,474,-128,451,-112,434,-106,474,-128,434,-106,350,-96,474,-128,350,-96,151,-96,474,-128,151,-96,76,-96,83,-78,76,-96,151,-96,83,-78,151,-96,85,-53,26,-115,26,-128,474,-128,26,-115,474,-128,35,-115,350,300,418,-77,416,-54,306,368,290,382,290,368,433,358,350,300,424,345,36,368,26,382,26,368, 428,20,413,20,405,-7,394,-30,379,-48,357,-59,328,-63,121,-63,289,153,144,349,304,349,339,346,364,336,381,318,392,292,400,256,415,256,415,382,41,382,225,126,29,-128,401,-128, 415,382,41,382,144,349,415,382,144,349,304,349,415,382,304,349,339,346,415,382,339,346,364,336,415,382,364,336,381,318,415,382,381,318,392,292,415,382,392,292,400,256,415,382,400,256,415,256,225,126,29,-128,121,-63,225,126,121,-63,289,153,225,126,289,153,144,349,225,126,144,349,41,382,394,-30,379,-48,401,-128,401,-128,379,-48,357,-59,401,-128,357,-59,328,-63,405,-7,394,-30,401,-128,405,-7,401,-128,428,20,405,-7,428,20,413,20,121,-63,29,-128,401,-128,121,-63,401,-128,328,-63, 310,110,310,143,32,143,32,110, 310,110,310,143,32,143,310,110,32,143,32,110, 319,218,319,251,24,251,24,218,16383,16383,319,54,319,86,188,86,188,191,155,191,155,86,24,86,24,54,155,54,155,-43,188,-43,188,54, 24,251,24,218,319,218,24,251,319,218,319,251,188,191,155,191,188,-43,188,-43,155,191,155,86,188,-43,155,86,155,54,155,54,155,86,24,86,155,54,24,86,24,54,188,54,319,54,188,86,188,86,319,54,319,86,188,-43,155,54,155,-43, 203,339,201,349,196,358,189,365,180,369,171,371,161,369,153,365,146,358,141,350,139,339,140,328,145,319,151,313,160,308,171,307,181,309,190,313,197,320,201,329,203,339,16383,16383,318,110,318,143,188,143,188,273,155,273,155,143,24,143,24,110,155,110,155,-20,188,-20,188,110, 171,371,171,307,180,369,180,369,171,307,181,309,180,369,181,309,189,365,189,365,181,309,190,313,189,365,190,313,196,358,196,358,190,313,197,320,196,358,197,320,201,349,201,349,197,320,201,329,201,349,201,329,203,339,139,339,140,328,141,350,141,350,140,328,145,319,141,350,145,319,146,358,146,358,145,319,151,313,146,358,151,313,153,365,153,365,151,313,160,308,153,365,160,308,161,369,161,369,160,308,171,307,161,369,171,307,171,371,188,273,155,273,188,-20,188,-20,155,273,155,143,188,-20,155,143,155,110,155,110,155,143,24,143,155,110,24,143,24,110,188,110,318,110,188,143,188,143,318,110,318,143,188,-20,155,110,155,-20, 239,355,203,355,23,-110,59,-110, 239,355,203,355,23,-110,239,355,23,-110,59,-110, 201,46,44,205,12,205,171,46, 201,46,44,205,12,205,201,46,12,205,171,46, 228,169,227,175,225,181,221,185,216,189,210,190,208,190,206,189,204,189,202,188,200,186,191,180,182,170,170,158,156,145,137,133,138,153,142,172,146,190,150,204,151,215,150,222,147,227,143,231,138,234,132,235,127,234,121,231,117,227,114,222,113,215,114,204,118,189,122,172,126,153,127,132,111,143,96,155,72,179,62,186,63,186,60,188,58,189,56,189,54,190,51,190,45,189,40,185,37,181,34,175,33,169,34,165,35,162,37,159,40,156,44,153,55,149,70,144,87,139,105,133,122,125,105,117,88,111,71,106,56,102,46,98,42,95,39,91,37,87,36,82,35,78,36,73,38,69,42,65,47,63,54,62,56,62,59,63,61,64,67,66,75,72,85,83,98,95,112,108,127,118,126,98,122,80,118,63,114,49,113,37,114,31,117,26,121,21,127,18,132,17,138,18,143,21,147,26,150,31,151,37,150,49,146,63,142,80,138,98,137,118,157,104,173,89,185,75,196,65,208,61,215,62,220,65,224,70,227,75,228,81,227,85,226,88,224,91,221,95,217,97,207,101,193,105,177,109,159,116,140,125,161,135,179,142,195,146,208,149,218,153,221,155,224,158,226,162,228,165,228,169, 146,63,142,80,143,21,143,21,142,80,138,98,143,21,138,98,138,18,138,18,138,98,137,118,137,133,138,234,132,17,132,17,138,234,132,235,132,17,132,235,127,118,127,118,132,235,127,132,127,118,127,132,122,125,122,125,127,132,111,143,138,153,142,172,143,231,143,231,142,172,146,190,143,231,146,190,147,227,147,227,146,190,150,204,147,227,150,204,150,222,150,222,150,204,151,215,138,234,137,133,138,153,138,234,138,153,143,231,127,118,126,98,127,18,127,118,127,18,132,17,113,37,114,31,114,49,114,49,114,31,117,26,114,49,117,26,118,63,118,63,117,26,121,21,118,63,121,21,122,80,122,80,121,21,127,18,122,80,127,18,126,98,137,118,157,104,140,125,140,125,157,104,159,116,159,116,157,104,173,89,159,116,173,89,177,109,177,109,173,89,185,75,177,109,185,75,193,105,193,105,185,75,196,65,193,105,196,65,207,101,207,101,196,65,208,61,207,101,208,61,217,97,217,97,208,61,215,62,217,97,215,62,220,65,221,155,224,158,225,181,225,181,224,158,226,162,225,181,226,162,227,175,227,175,226,162,228,165,227,175,228,165,228,169,221,185,216,189,218,153,221,185,218,153,221,155,221,185,221,155,225,181,216,189,210,190,218,153,218,153,210,190,208,190,218,153,208,190,208,149,208,149,208,190,206,189,208,149,206,189,204,189,204,189,202,188,208,149,208,149,202,188,200,186,208,149,200,186,195,146,195,146,200,186,191,180,195,146,191,180,182,170,156,145,140,125,161,135,156,145,161,135,170,158,170,158,161,135,179,142,170,158,179,142,182,170,182,170,179,142,195,146,137,133,137,118,140,125,137,133,140,125,156,145,137,118,137,133,132,17,137,118,132,17,138,18,228,81,227,85,227,75,227,75,227,85,226,88,227,75,226,88,224,70,224,70,226,88,224,91,224,70,224,91,221,95,221,95,217,97,220,65,221,95,220,65,224,70,150,49,146,63,147,26,150,49,147,26,150,31,150,49,150,31,151,37,127,132,132,235,127,234,127,132,127,234,126,153,126,153,127,234,122,172,122,172,127,234,121,231,122,172,121,231,118,189,118,189,121,231,117,227,118,189,117,227,114,204,114,204,117,227,114,222,114,204,114,222,113,215,75,72,85,83,88,111,88,111,85,83,98,95,88,111,98,95,105,117,105,117,98,95,112,108,105,117,112,108,122,125,122,125,112,108,127,118,71,106,56,102,59,63,71,106,59,63,61,64,71,106,61,64,64,65,71,106,64,65,67,66,71,106,67,66,75,72,71,106,75,72,88,111,56,102,46,98,47,63,56,102,47,63,54,62,56,102,54,62,56,62,56,102,56,62,59,63,42,65,47,63,46,98,42,65,46,98,42,95,42,65,42,95,39,91,42,65,39,91,38,69,37,87,36,82,36,73,37,87,36,73,38,69,37,87,38,69,39,91,122,125,111,143,105,133,105,133,111,143,96,155,105,133,96,155,87,139,87,139,96,155,83,168,87,139,83,168,72,179,70,144,87,139,72,179,70,144,72,179,62,186,70,144,62,186,60,188,70,144,60,188,58,189,70,144,58,189,56,189,70,144,56,189,55,149,55,149,56,189,54,190,55,149,54,190,51,190,55,149,51,190,45,189,55,149,45,189,44,153,40,185,37,181,37,159,40,185,37,159,40,156,40,185,40,156,44,153,40,185,44,153,45,189,33,169,34,165,34,175,34,175,34,165,35,162,34,175,35,162,37,181,37,181,35,162,37,159,36,73,36,82,35,78,146,63,143,21,147,26, 155,126,152,147,142,166,128,180,110,190,89,194,67,190,48,181,33,167,24,148,20,127,23,105,33,86,47,72,66,62,88,59,109,62,128,72,142,86,152,105,155,126,16383,16383,122,126,120,115,116,105,108,98,99,93,88,92,77,93,67,98,60,106,55,115,53,127,55,138,59,147,67,154,77,159,89,161,99,159,108,154,116,147,120,137,122,126, 60,106,66,62,67,98,67,98,66,62,88,59,67,98,88,59,77,93,77,93,88,59,88,92,99,93,88,92,88,59,99,93,88,59,109,62,55,138,59,147,67,190,67,190,59,147,67,154,67,190,67,154,89,194,89,194,67,154,77,159,89,194,77,159,89,161,89,161,99,159,110,190,110,190,99,159,108,154,110,190,108,154,116,147,20,127,23,105,24,148,24,148,23,105,33,86,24,148,33,86,33,167,33,167,33,86,47,72,33,167,47,72,48,181,48,181,47,72,53,127,55,138,67,190,48,181,55,138,48,181,53,127,155,126,152,147,152,105,152,105,152,147,142,166,152,105,142,166,142,86,142,86,142,166,128,180,142,86,128,180,128,72,128,72,128,180,122,126,128,72,122,126,120,115,128,72,120,115,116,105,128,180,110,190,116,147,128,180,116,147,120,137,128,180,120,137,122,126,110,190,89,194,89,161,109,62,128,72,116,105,109,62,116,105,108,98,109,62,108,98,99,93,55,115,53,127,47,72,55,115,47,72,66,62,55,115,66,62,60,106, 155,126,152,147,142,166,128,180,110,190,89,194,67,190,48,181,33,167,24,148,20,127,23,105,33,86,47,72,66,62,88,59,109,62,128,72,142,86,152,105,155,126, 20,127,23,105,24,148,24,148,23,105,33,86,24,148,33,86,33,167,33,167,33,86,47,72,33,167,47,72,48,181,48,181,47,72,66,62,48,181,66,62,67,190,67,190,66,62,88,59,67,190,88,59,89,194,89,194,88,59,109,62,89,194,109,62,110,190,110,190,109,62,128,72,110,190,128,72,128,180,128,180,128,72,142,86,128,180,142,86,142,166,142,166,142,86,152,105,142,166,152,105,152,147,152,147,152,105,155,126, 482,487,454,487,248,-45,246,-45,143,222,134,222,56,160,62,150,69,155,83,163,89,165,94,165,102,164,108,161,114,155,120,147,126,136,227,-128,243,-128, 76,159,83,163,134,222,134,222,83,163,89,165,134,222,89,165,94,165,94,165,102,164,134,222,134,222,102,164,108,161,134,222,108,161,114,155,143,222,134,222,227,-128,227,-128,134,222,126,136,120,147,126,136,134,222,120,147,134,222,114,155,134,222,56,160,62,150,134,222,62,150,69,155,134,222,69,155,76,159,143,222,227,-128,246,-45,246,-45,227,-128,243,-128,246,-45,243,-128,248,-45,248,-45,243,-128,482,487,248,-45,482,487,454,487, 149,381,156,391,162,399,169,404,177,407,185,408,195,407,202,404,208,399,212,392,213,382,211,369,204,359,195,351,183,345,171,340,171,335,184,335,189,334,193,333,196,333,206,328,213,323,219,315,222,306,223,296,222,284,217,274,210,266,201,261,190,259,186,260,182,260,178,262,173,264,168,267,164,270,161,272,152,275,146,273,144,271,142,268,142,265,143,260,146,255,152,251,160,249,171,248,193,250,214,257,231,269,242,286,247,307,245,320,240,331,233,340,223,347,210,352,218,358,224,365,229,373,232,381,233,388,231,400,226,410,218,417,206,421,193,423,178,421,166,416,156,407,149,396,143,382,16383,16383,482,487,454,487,248,-45,246,-45,143,222,134,222,56,160,62,150,69,155,83,163,89,165,94,165,102,164,108,161,114,155,120,147,126,136,227,-128,243,-128, 158,273,160,249,161,272,161,272,160,249,171,248,161,272,171,248,164,270,164,270,171,248,168,267,173,264,168,267,171,248,173,264,171,248,193,250,149,381,156,391,156,407,156,407,156,391,162,399,156,407,162,399,166,416,166,416,162,399,169,404,166,416,169,404,178,421,178,421,169,404,177,407,178,421,177,407,185,408,185,408,195,407,193,423,193,423,195,407,206,421,149,396,143,382,149,381,149,396,149,381,156,407,184,335,189,334,195,351,195,351,189,334,193,333,195,351,193,333,196,333,196,333,206,328,204,359,204,359,206,328,211,369,183,345,171,340,178,335,183,345,178,335,184,335,183,345,184,335,195,351,204,359,195,351,196,333,210,352,218,358,211,369,211,369,218,358,213,382,218,417,213,382,218,358,218,417,218,358,226,410,226,410,218,358,224,365,226,410,224,365,229,373,195,407,202,404,206,421,206,421,202,404,208,399,206,421,208,399,218,417,218,417,208,399,212,392,218,417,212,392,213,382,231,400,226,410,229,373,231,400,229,373,232,381,231,400,232,381,233,388,210,352,211,369,206,328,210,352,206,328,213,323,210,352,213,323,223,347,242,286,247,307,245,320,242,286,245,320,240,331,242,286,240,331,233,340,242,286,233,340,231,269,223,296,231,269,233,340,223,296,233,340,223,347,223,347,213,323,219,315,223,347,219,315,222,306,223,347,222,306,223,296,210,266,214,257,217,274,217,274,214,257,231,269,217,274,231,269,222,284,222,284,231,269,223,296,190,259,193,250,201,261,201,261,193,250,214,257,201,261,214,257,210,266,193,423,178,421,185,408,186,260,182,260,193,250,186,260,193,250,190,259,178,262,173,264,193,250,178,262,193,250,182,260,155,274,152,275,152,251,155,274,152,251,160,249,155,274,160,249,158,273,149,274,146,273,146,255,149,274,146,255,152,251,149,274,152,251,152,275,144,271,142,268,143,260,144,271,143,260,146,255,144,271,146,255,146,273,76,159,83,163,134,222,134,222,83,163,89,165,134,222,89,165,94,165,94,165,102,164,134,222,134,222,102,164,108,161,134,222,108,161,114,155,143,222,134,222,227,-128,227,-128,134,222,126,136,120,147,126,136,134,222,120,147,134,222,114,155,134,222,56,160,62,150,134,222,62,150,69,155,134,222,69,155,76,159,143,222,227,-128,246,-45,246,-45,227,-128,243,-128,246,-45,243,-128,248,-45,248,-45,243,-128,482,487,248,-45,482,487,454,487,143,260,142,268,142,265,178,335,171,340,171,335, 252,291,252,312,225,312,225,421,210,421,131,312,131,291,201,291,201,249,225,249,225,291,16383,16383,201,312,142,312,201,395,16383,16383,482,487,454,487,248,-45,246,-45,143,222,134,222,56,160,62,150,69,155,83,163,89,165,94,165,102,164,108,161,114,155,120,147,126,136,227,-128,243,-128, 131,291,201,291,131,312,131,312,201,291,142,312,131,312,142,312,210,421,210,421,142,312,201,395,210,421,201,395,225,249,225,249,201,395,201,312,225,249,201,312,201,291,201,291,201,312,142,312,210,421,225,249,225,421,225,312,225,291,252,291,225,312,252,291,252,312,76,159,83,163,134,222,134,222,83,163,89,165,134,222,89,165,94,165,94,165,102,164,134,222,134,222,102,164,108,161,134,222,108,161,114,155,143,222,134,222,227,-128,227,-128,134,222,126,136,120,147,126,136,134,222,120,147,134,222,114,155,134,222,56,160,62,150,134,222,62,150,69,155,134,222,69,155,76,159,143,222,227,-128,246,-45,246,-45,227,-128,243,-128,246,-45,243,-128,248,-45,248,-45,243,-128,482,487,248,-45,482,487,454,487,225,249,201,291,201,249, 321,42,304,45,287,54,270,70,253,92,235,121,235,123,245,137,258,150,275,162,296,170,321,173,321,215,294,211,272,201,254,185,239,165,225,142,199,174,177,195,156,207,137,213,116,215,95,212,70,201,46,180,28,147,21,100,26,63,39,35,59,15,83,4,108,0,135,3,159,12,180,27,198,47,213,73,232,47,250,27,271,12,294,3,321,0,16383,16383,202,90,193,78,180,66,164,54,144,45,120,42,96,47,76,59,62,78,53,101,50,126,53,144,60,161,71,174,85,182,100,185,121,181,140,169,160,150,181,124,202,92, 213,73,232,47,213,73,213,73,232,47,225,142,213,73,225,142,202,92,202,92,199,174,181,124,181,124,199,174,177,195,181,124,177,195,160,150,160,150,177,195,156,207,160,150,156,207,140,169,140,169,156,207,137,213,140,169,137,213,121,181,121,181,137,213,116,215,121,181,116,215,100,185,53,144,60,161,70,201,70,201,60,161,71,174,70,201,71,174,95,212,95,212,71,174,85,182,95,212,85,182,100,185,21,100,26,63,28,147,28,147,26,63,39,35,28,147,39,35,46,180,46,180,39,35,59,15,46,180,59,15,50,126,50,126,53,144,46,180,46,180,53,144,70,201,202,90,193,78,198,47,198,47,193,78,180,66,198,47,180,66,180,27,180,27,180,66,164,54,180,27,164,54,159,12,159,12,164,54,144,45,159,12,144,45,135,3,135,3,144,45,120,42,135,3,120,42,108,0,108,0,120,42,96,47,108,0,96,47,83,4,83,4,96,47,76,59,83,4,76,59,62,78,59,15,83,4,62,78,59,15,62,78,53,101,59,15,53,101,50,126,287,54,270,70,271,12,271,12,270,70,253,92,271,12,253,92,250,27,250,27,253,92,235,121,250,27,235,121,232,47,321,173,321,215,296,170,296,170,321,215,294,211,296,170,294,211,275,162,275,162,294,211,272,201,275,162,272,201,258,150,258,150,272,201,254,185,258,150,254,185,245,137,245,137,254,185,239,165,245,137,239,165,235,123,235,123,239,165,225,142,235,123,225,142,232,47,235,123,232,47,235,121,304,45,287,54,294,3,304,45,294,3,321,0,304,45,321,0,321,42,199,174,202,92,225,142,213,73,202,92,202,90,213,73,202,90,198,47,100,185,116,215,95,212,287,54,271,12,294,3, 427,111,422,148,408,177,387,198,363,210,336,215,309,211,287,201,269,185,253,165,239,142,213,174,191,195,171,207,151,213,131,215,110,212,84,201,60,180,42,147,35,100,40,63,54,35,73,15,97,4,123,0,150,3,174,12,195,27,213,47,228,73,246,47,264,27,284,12,305,3,328,0,363,7,390,25,410,51,423,81,427,111,16383,16383,249,123,259,136,270,149,285,161,304,170,328,173,352,169,371,157,385,138,394,115,397,89,394,70,387,54,377,41,363,33,347,30,327,33,308,45,290,63,270,89,249,121,16383,16383,217,90,207,78,195,66,179,54,159,45,134,42,110,47,91,59,77,78,68,101,65,126,67,144,74,161,85,174,99,182,115,185,135,181,155,169,175,150,195,124,217,92, 228,73,246,47,228,73,228,73,246,47,239,142,228,73,239,142,217,92,217,92,213,174,195,124,195,124,213,174,191,195,195,124,191,195,175,150,175,150,191,195,171,207,175,150,171,207,155,169,155,169,171,207,151,213,155,169,151,213,135,181,135,181,151,213,131,215,135,181,131,215,115,185,67,144,74,161,84,201,84,201,74,161,85,174,84,201,85,174,110,212,110,212,85,174,99,182,110,212,99,182,115,185,35,100,40,63,42,147,42,147,40,63,54,35,42,147,54,35,60,180,60,180,54,35,73,15,60,180,73,15,65,126,65,126,67,144,60,180,60,180,67,144,84,201,217,90,207,78,213,47,213,47,207,78,195,66,213,47,195,66,195,27,195,27,195,66,179,54,195,27,179,54,174,12,174,12,179,54,159,45,174,12,159,45,150,3,150,3,159,45,134,42,150,3,134,42,123,0,123,0,134,42,110,47,123,0,110,47,97,4,97,4,110,47,91,59,97,4,91,59,77,78,73,15,97,4,77,78,73,15,77,78,68,101,73,15,68,101,65,126,336,215,328,173,352,169,336,215,352,169,363,210,363,210,352,169,371,157,363,210,371,157,387,198,387,198,371,157,385,138,387,198,385,138,394,115,270,149,285,161,287,201,287,201,285,161,304,170,287,201,304,170,309,211,309,211,304,170,328,173,309,211,328,173,336,215,239,142,249,123,253,165,253,165,249,123,259,136,253,165,259,136,269,185,269,185,259,136,270,149,269,185,270,149,287,201,264,27,249,121,246,47,246,47,249,121,249,123,246,47,249,123,239,142,249,121,264,27,270,89,270,89,264,27,284,12,270,89,284,12,290,63,290,63,284,12,305,3,290,63,305,3,308,45,308,45,305,3,328,0,308,45,328,0,327,33,327,33,328,0,347,30,363,33,347,30,363,7,363,33,363,7,390,25,387,198,394,115,408,177,408,177,394,115,397,89,410,51,397,89,394,70,410,51,394,70,390,25,390,25,394,70,387,54,390,25,387,54,377,41,422,148,408,177,410,51,422,148,410,51,423,81,422,148,423,81,427,111,347,30,328,0,363,7,213,174,217,92,239,142,228,73,217,92,217,90,228,73,217,90,213,47,115,185,131,215,110,212,363,33,390,25,377,41,397,89,410,51,408,177, 317,0,317,33,58,33,58,292,25,292,25,0, 58,33,58,292,25,292,58,33,25,292,25,0,58,33,25,0,317,0,58,33,317,0,317,33, 321,0,321,33,91,33,310,252,285,273,12,0, 91,33,310,252,285,273,91,33,285,273,12,0,91,33,12,0,321,0,91,33,321,0,321,33, 321,0,321,33,271,33,265,61,257,88,247,113,233,138,218,160,310,252,284,273,196,185,186,195,174,205,169,209,148,182,168,166,172,161,11,0,239,0,239,-18,238,-24,238,-30,270,-35,272,-21,272,0,16383,16383,90,33,194,137,207,118,217,98,226,77,233,56,237,33, 90,33,194,137,172,161,172,161,174,205,169,209,172,161,169,209,168,166,168,166,169,209,163,170,169,209,148,182,153,178,169,209,153,178,158,174,169,209,158,174,163,170,194,137,207,118,196,185,196,185,207,118,218,160,196,185,218,160,284,273,284,273,218,160,310,252,207,118,217,98,218,160,218,160,217,98,226,77,218,160,226,77,233,138,233,138,226,77,233,56,233,138,233,56,237,33,194,137,196,185,191,190,194,137,191,190,186,195,194,137,186,195,180,200,194,137,180,200,174,205,194,137,174,205,172,161,233,138,237,33,247,113,239,0,237,33,90,33,239,0,90,33,11,0,11,0,90,33,172,161,265,61,257,88,270,-35,270,-35,257,88,247,113,270,-35,247,113,239,0,239,0,247,113,237,33,272,0,321,0,321,33,272,0,321,33,271,33,272,0,271,33,271,-28,272,0,271,-28,272,-21,272,0,272,-21,272,-14,272,0,272,-14,272,-6,271,33,265,61,270,-35,271,33,270,-35,271,-28,270,-35,239,0,239,-5,270,-35,239,-5,239,-12,270,-35,239,-12,239,-18,270,-35,239,-18,238,-24,270,-35,238,-24,238,-30, 326,40,281,59,284,72,286,86,288,99,290,127,289,140,288,154,286,168,280,196,326,216,314,246,269,228,266,234,263,241,257,253,253,259,225,243,228,237,231,232,233,226,236,220,238,215,28,127,239,40,237,34,234,29,232,23,229,17,225,12,254,-5,258,1,261,8,265,14,268,21,270,27,314,9,16383,16383,114,127,249,184,252,172,254,161,255,149,257,127,256,115,254,93,252,82,249,71, 256,115,258,1,257,127,257,127,258,1,260,247,260,247,258,1,261,8,260,247,261,8,263,241,263,241,261,8,265,14,263,241,265,14,266,234,266,234,265,14,268,21,266,234,268,21,269,228,269,228,268,21,270,27,269,228,270,27,280,196,280,196,270,27,281,59,280,196,281,59,283,182,283,182,281,59,284,72,283,182,284,72,286,168,286,168,284,72,286,86,286,168,286,86,288,154,288,154,286,86,288,99,288,154,288,99,289,140,289,140,288,99,289,113,289,140,289,113,290,127,314,9,326,40,281,59,314,9,281,59,270,27,314,246,269,228,280,196,314,246,280,196,326,216,255,149,256,138,257,253,257,253,256,138,257,127,257,253,257,127,260,247,249,184,252,172,253,259,253,259,252,172,254,161,253,259,254,161,257,253,257,253,254,161,255,149,253,259,225,243,228,237,253,259,228,237,231,232,253,259,231,232,233,226,253,259,233,226,236,220,253,259,236,220,238,215,253,259,238,215,249,184,255,104,254,93,254,-5,255,104,254,-5,258,1,255,104,258,1,256,115,254,-5,254,93,252,82,254,-5,252,82,249,71,254,-5,249,71,239,40,254,-5,239,40,237,34,254,-5,237,34,234,29,254,-5,234,29,232,23,254,-5,232,23,229,17,254,-5,229,17,225,12,238,215,28,127,114,127,114,127,28,127,239,40,114,127,239,40,249,71,238,215,114,127,249,184, 83,-93,83,345,50,345,50,-93, 83,-93,83,345,50,345,83,-93,50,345,50,-93, 190,152,179,178,118,147,118,345,84,345,84,130,12,93,23,66,84,98,84,-93,118,-93,118,114, 84,130,12,93,23,66,84,130,23,66,84,98,84,130,84,98,118,-93,84,130,118,-93,84,345,84,345,118,-93,118,345,118,147,118,114,190,152,118,147,190,152,179,178,118,-93,84,98,84,-93, 197,-93,197,345,164,345,164,-93,16383,16383,98,-93,98,345,65,345,65,-93, 164,345,164,-93,197,-93,164,345,197,-93,197,345,65,345,65,-93,98,-93,65,345,98,-93,98,345, 293,181,281,207,219,175,219,345,185,345,185,158,119,125,119,345,86,345,86,108,12,70,23,44,86,75,86,-93,119,-93,119,93,185,126,185,-93,219,-93,219,143, 86,108,12,70,23,44,86,108,23,44,86,75,86,108,86,75,119,-93,86,108,119,-93,86,345,219,345,185,345,219,-93,219,-93,185,345,185,158,219,-93,185,158,185,126,185,126,185,158,119,125,185,126,119,125,119,93,119,-93,119,345,86,345,219,143,293,181,219,175,219,175,293,181,281,207,219,-93,185,126,185,-93,119,-93,86,75,86,-93, 295,-14,157,268,152,268,16,-14,47,-14,155,201,262,-14, 16,-14,47,-14,152,268,152,268,47,-14,155,201,152,268,155,201,157,268,157,268,155,201,262,-14,157,268,262,-14,295,-14, 295,268,263,268,156,52,48,268,16,268,153,-14,158,-14, 295,268,263,268,158,-14,158,-14,263,268,156,52,158,-14,156,52,153,-14,153,-14,156,52,48,268,153,-14,48,268,16,268, 286,-15,286,132,280,177,261,215,233,243,197,261,155,268,113,262,77,244,49,216,30,178,24,134,24,-15,57,-15,57,132,62,165,76,193,97,215,124,230,155,235,186,230,212,215,234,193,248,165,253,132,253,-15, 253,132,253,132,248,165,248,165,253,132,261,215,248,165,261,215,234,193,234,193,261,215,233,243,234,193,233,243,212,215,212,215,233,243,197,261,212,215,197,261,186,230,186,230,197,261,155,235,124,230,155,235,155,268,124,230,155,268,113,262,62,165,76,193,77,244,77,244,76,193,97,215,77,244,97,215,113,262,113,262,97,215,124,230,49,216,30,178,57,-15,49,216,57,-15,57,132,49,216,57,132,62,165,49,216,62,165,77,244,24,134,24,-15,57,-15,24,134,57,-15,30,178,197,261,155,268,155,235,286,-15,286,132,280,177,286,-15,280,177,261,215,286,-15,261,215,253,132,286,-15,253,132,253,-15, 286,268,253,268,253,120,248,87,234,59,212,37,186,23,155,17,124,23,97,37,76,60,62,88,57,121,57,268,24,268,24,118,30,74,49,37,77,9,113,-8,155,-15,197,-8,233,9,261,38,280,75,286,120, 253,120,248,87,261,38,261,38,248,87,234,59,261,38,234,59,233,9,233,9,234,59,212,37,233,9,212,37,197,-8,197,-8,212,37,186,23,197,-8,186,23,155,-15,155,-15,186,23,155,17,286,268,253,268,261,38,286,268,261,38,280,75,286,268,280,75,286,120,76,60,77,9,97,37,97,37,77,9,113,-8,97,37,113,-8,124,23,124,23,113,-8,155,-15,124,23,155,-15,155,17,62,88,57,121,49,37,62,88,49,37,77,9,62,88,77,9,76,60,57,268,24,268,30,74,57,268,30,74,49,37,57,268,49,37,57,121,30,74,24,268,24,118,253,120,261,38,253,268, 102,-61,94,-89,86,-112,77,-129,67,-140,54,-144,52,-143,50,-143,49,-142,49,-137,52,-135,54,-132,57,-127,57,-116,54,-112,51,-109,46,-108,42,-107,34,-109,27,-113,21,-119,18,-127,16,-136,18,-143,22,-150,28,-155,37,-158,49,-159,78,-153,102,-135,119,-111,131,-84,140,-58,231,308,239,337,247,362,257,380,268,393,281,397,283,397,285,396,287,394,287,392,286,390,284,387,281,384,279,379,278,372,279,368,281,364,289,360,294,360,302,361,309,366,315,372,318,380,320,390,318,396,314,402,307,407,298,411,287,412,255,404,231,385,213,359,201,330,193,303, 49,-140,49,-137,51,-109,51,-109,49,-137,52,-135,51,-109,52,-135,54,-112,54,-112,52,-135,54,-132,54,-112,54,-132,57,-116,57,-116,54,-132,57,-127,57,-116,57,-127,57,-120,18,-127,18,-143,21,-119,21,-119,18,-143,22,-150,21,-119,22,-150,27,-113,27,-113,22,-150,28,-155,27,-113,28,-155,34,-109,34,-109,28,-155,37,-158,34,-109,37,-158,42,-107,42,-107,37,-158,49,-159,42,-107,49,-159,46,-108,46,-108,49,-159,49,-140,86,-112,77,-129,78,-153,78,-153,77,-129,67,-140,78,-153,67,-140,54,-144,54,-144,52,-143,78,-153,78,-153,52,-143,50,-143,78,-153,50,-143,49,-159,49,-159,50,-143,49,-142,49,-159,49,-142,49,-141,285,396,287,412,283,397,283,397,287,412,281,397,268,393,281,397,287,412,268,393,287,412,255,404,289,360,294,360,298,411,298,411,294,360,302,361,298,411,302,361,307,407,307,407,302,361,309,366,307,407,309,366,314,402,314,402,309,366,315,372,314,402,315,372,318,396,318,396,315,372,318,380,318,396,318,380,320,390,279,379,279,368,281,384,281,384,279,368,281,364,281,384,281,364,284,387,284,387,281,364,285,362,284,387,285,362,286,390,286,390,285,362,289,360,286,390,289,360,287,392,287,392,289,360,298,411,287,412,285,396,286,395,287,412,286,395,287,394,287,412,287,394,287,392,287,412,287,392,298,411,255,404,231,385,231,308,255,404,231,308,239,337,255,404,239,337,247,362,255,404,247,362,257,380,255,404,257,380,268,393,231,308,231,385,213,359,231,308,213,359,201,330,231,308,201,330,193,303,231,308,193,303,140,-58,94,-89,102,-135,102,-61,102,-61,102,-135,119,-111,102,-61,119,-111,193,303,193,303,119,-111,131,-84,193,303,131,-84,140,-58,86,-112,78,-153,102,-135,86,-112,102,-135,94,-89,49,-140,49,-159,49,-141,279,368,279,379,278,372,18,-143,18,-127,16,-136,46,-108,49,-140,51,-109, 223,-61,215,-89,207,-112,198,-129,188,-140,175,-144,173,-143,172,-143,170,-142,170,-140,171,-137,173,-135,175,-132,178,-127,179,-120,178,-116,175,-112,172,-109,168,-108,163,-107,155,-109,148,-113,142,-119,139,-127,137,-136,138,-143,141,-150,146,-155,154,-158,165,-159,195,-153,219,-135,238,-111,252,-84,261,-58,352,308,360,337,368,362,378,380,389,393,402,397,404,397,406,396,408,394,408,392,407,390,405,387,402,384,400,379,399,372,400,368,402,364,410,360,415,360,423,361,430,366,435,372,439,380,440,390,439,396,436,402,431,407,424,411,413,412,381,404,355,385,336,359,323,330,314,303,16383,16383,102,-61,94,-89,86,-112,77,-129,67,-140,54,-144,52,-143,50,-143,49,-142,49,-137,52,-135,54,-132,57,-127,57,-116,54,-112,51,-109,46,-108,42,-107,34,-109,27,-113,21,-119,18,-127,16,-136,17,-143,20,-150,25,-155,33,-158,44,-159,74,-153,98,-135,117,-111,131,-84,140,-58,231,308,239,337,247,362,257,380,268,393,281,397,283,397,285,396,287,394,287,392,286,390,284,387,281,384,279,379,278,372,279,368,281,364,289,360,294,360,302,361,309,366,315,372,318,380,320,390,319,396,316,402,310,407,302,411,292,412,260,404,234,385,215,359,201,330,193,303, 49,-137,51,-109,49,-140,49,-140,46,-108,44,-159,44,-159,46,-108,42,-107,44,-159,42,-107,34,-109,51,-109,52,-135,54,-112,54,-112,52,-135,54,-132,54,-112,54,-132,57,-116,57,-116,54,-132,57,-127,57,-116,57,-127,57,-120,94,-89,86,-112,98,-135,98,-135,86,-112,77,-129,98,-135,77,-129,74,-153,74,-153,77,-129,67,-140,74,-153,67,-140,54,-144,54,-144,52,-143,74,-153,74,-153,52,-143,50,-143,74,-153,50,-143,44,-159,44,-159,50,-143,49,-142,44,-159,49,-142,49,-141,171,-137,172,-109,170,-140,170,-140,168,-108,165,-159,165,-159,168,-108,163,-107,165,-159,163,-107,155,-109,172,-109,173,-135,175,-112,175,-112,173,-135,175,-132,175,-112,175,-132,178,-116,178,-116,175,-132,178,-127,178,-116,178,-127,179,-120,215,-89,207,-112,219,-135,219,-135,207,-112,198,-129,219,-135,198,-129,195,-153,195,-153,198,-129,188,-140,195,-153,188,-140,175,-144,175,-144,173,-143,195,-153,195,-153,173,-143,172,-143,195,-153,172,-143,165,-159,165,-159,172,-143,170,-142,165,-159,170,-142,170,-141,285,396,292,412,283,397,283,397,292,412,281,397,268,393,281,397,292,412,268,393,292,412,260,404,302,361,302,411,294,360,294,360,302,411,292,412,294,360,292,412,289,360,289,360,292,412,287,392,289,360,287,392,286,390,289,360,286,390,285,362,285,362,286,390,284,387,285,362,284,387,281,364,281,364,284,387,281,384,281,364,281,384,279,368,279,368,281,384,279,379,279,368,279,379,278,372,320,390,319,396,318,380,318,380,319,396,316,402,318,380,316,402,315,372,315,372,316,402,310,407,315,372,310,407,309,366,309,366,310,407,302,411,309,366,302,411,302,361,292,412,285,396,286,395,292,412,286,395,287,394,292,412,287,394,287,392,260,404,234,385,239,337,260,404,239,337,247,362,260,404,247,362,257,380,260,404,257,380,268,393,231,308,239,337,234,385,231,308,234,385,215,359,231,308,215,359,201,330,231,308,201,330,193,303,231,308,193,303,140,-58,94,-89,98,-135,102,-61,102,-61,98,-135,117,-111,102,-61,117,-111,193,303,193,303,117,-111,131,-84,193,303,131,-84,140,-58,49,-140,44,-159,49,-141,16,-136,17,-143,18,-127,18,-127,17,-143,20,-150,18,-127,20,-150,21,-119,21,-119,20,-150,25,-155,21,-119,25,-155,27,-113,27,-113,25,-155,33,-158,27,-113,33,-158,34,-109,34,-109,33,-158,44,-159,406,396,413,412,404,397,404,397,413,412,402,397,389,393,402,397,413,412,389,393,413,412,381,404,423,361,424,411,415,360,415,360,424,411,413,412,415,360,413,412,410,360,410,360,413,412,408,392,410,360,408,392,407,390,410,360,407,390,406,362,406,362,407,390,405,387,406,362,405,387,402,364,402,364,405,387,402,384,402,364,402,384,400,379,400,379,399,372,400,368,400,379,400,368,402,364,440,390,439,396,439,380,439,380,439,396,436,402,439,380,436,402,435,372,435,372,436,402,431,407,435,372,431,407,430,366,430,366,431,407,424,411,430,366,424,411,423,361,413,412,406,396,407,395,413,412,407,395,408,394,413,412,408,394,408,392,381,404,355,385,360,337,381,404,360,337,368,362,381,404,368,362,378,380,381,404,378,380,389,393,352,308,360,337,355,385,352,308,355,385,336,359,352,308,336,359,323,330,352,308,323,330,314,303,352,308,314,303,261,-58,215,-89,219,-135,223,-61,223,-61,219,-135,238,-111,223,-61,238,-111,314,303,314,303,238,-111,252,-84,314,303,252,-84,261,-58,170,-140,165,-159,170,-141,137,-136,138,-143,139,-127,139,-127,138,-143,141,-150,139,-127,141,-150,142,-119,142,-119,141,-150,146,-155,142,-119,146,-155,148,-113,148,-113,146,-155,154,-158,148,-113,154,-158,155,-109,155,-109,154,-158,165,-159,168,-108,170,-140,172,-109,172,-109,171,-137,173,-135,46,-108,49,-140,51,-109,51,-109,49,-137,52,-135, 344,-61,336,-89,328,-112,319,-129,309,-140,296,-144,294,-143,293,-143,291,-141,291,-140,292,-137,297,-132,299,-127,300,-120,299,-116,296,-112,293,-109,288,-108,284,-107,276,-109,269,-113,263,-119,259,-127,258,-136,259,-143,262,-150,267,-155,275,-158,286,-159,316,-153,341,-135,359,-111,373,-84,382,-58,473,308,481,337,489,362,499,380,510,393,523,397,525,397,527,396,529,394,529,392,528,390,526,387,523,384,521,379,520,372,521,368,523,364,531,360,536,360,544,361,551,366,556,372,560,380,561,390,560,396,558,402,552,407,545,411,534,412,502,404,476,385,457,359,443,330,435,303,16383,16383,223,-61,215,-89,207,-112,198,-129,187,-140,175,-144,173,-143,171,-143,169,-141,169,-140,170,-137,175,-132,177,-127,178,-120,177,-116,175,-112,171,-109,167,-108,162,-107,154,-109,147,-113,142,-119,138,-127,137,-136,138,-143,141,-150,146,-155,154,-158,164,-159,194,-153,219,-135,238,-111,251,-84,260,-58,352,308,359,337,368,362,377,380,388,393,402,397,404,397,405,396,407,395,407,392,406,390,402,384,399,379,398,372,399,368,402,364,405,362,409,360,414,360,422,361,429,366,435,372,438,380,440,390,439,396,436,402,431,407,423,411,412,412,380,404,355,385,336,359,322,330,314,303,16383,16383,102,-61,94,-89,86,-112,77,-129,67,-140,54,-144,52,-143,50,-143,49,-142,49,-137,52,-135,54,-132,57,-127,57,-116,54,-112,51,-109,46,-108,42,-107,34,-109,27,-113,21,-119,18,-127,16,-136,17,-143,20,-150,25,-155,33,-158,44,-159,74,-153,98,-135,117,-111,131,-84,140,-58,231,308,239,337,247,362,257,380,268,393,281,397,283,397,285,396,287,394,287,392,286,390,284,387,281,384,279,379,278,372,279,368,281,364,289,360,294,360,302,361,309,366,315,372,318,380,320,390,319,396,316,402,310,407,302,411,292,412,260,404,234,385,215,359,201,330,193,303, 49,-137,51,-109,49,-140,49,-140,46,-108,44,-159,44,-159,46,-108,42,-107,44,-159,42,-107,34,-109,51,-109,52,-135,54,-112,54,-112,52,-135,54,-132,54,-112,54,-132,57,-116,57,-116,54,-132,57,-127,57,-116,57,-127,57,-120,94,-89,86,-112,98,-135,98,-135,86,-112,77,-129,98,-135,77,-129,74,-153,74,-153,77,-129,67,-140,74,-153,67,-140,54,-144,54,-144,52,-143,74,-153,74,-153,52,-143,50,-143,74,-153,50,-143,44,-159,44,-159,50,-143,49,-142,44,-159,49,-142,49,-141,170,-137,171,-109,169,-140,169,-140,167,-108,164,-159,164,-159,167,-108,162,-107,164,-159,162,-107,154,-109,171,-109,172,-135,175,-112,175,-112,172,-135,175,-132,175,-112,175,-132,177,-116,177,-116,175,-132,177,-127,177,-116,177,-127,178,-120,215,-89,207,-112,219,-135,219,-135,207,-112,198,-129,219,-135,198,-129,194,-153,194,-153,198,-129,187,-140,194,-153,187,-140,175,-144,175,-144,173,-143,194,-153,194,-153,173,-143,171,-143,194,-153,171,-143,164,-159,164,-159,171,-143,170,-142,164,-159,170,-142,169,-141,285,396,292,412,283,397,283,397,292,412,281,397,268,393,281,397,292,412,268,393,292,412,260,404,302,361,302,411,294,360,294,360,302,411,292,412,294,360,292,412,289,360,289,360,292,412,287,392,289,360,287,392,286,390,289,360,286,390,285,362,285,362,286,390,284,387,285,362,284,387,281,364,281,364,284,387,281,384,281,364,281,384,279,368,279,368,281,384,279,379,279,368,279,379,278,372,292,-137,293,-109,291,-140,291,-140,288,-108,286,-159,286,-159,288,-108,284,-107,286,-159,284,-107,276,-109,293,-109,294,-135,296,-112,296,-112,294,-135,297,-132,296,-112,297,-132,299,-116,299,-116,297,-132,299,-127,299,-116,299,-127,300,-120,320,390,319,396,318,380,318,380,319,396,316,402,318,380,316,402,315,372,315,372,316,402,310,407,315,372,310,407,309,366,309,366,310,407,302,411,309,366,302,411,302,361,292,412,285,396,286,395,292,412,286,395,287,394,292,412,287,394,287,392,260,404,234,385,239,337,260,404,239,337,247,362,260,404,247,362,257,380,260,404,257,380,268,393,231,308,239,337,234,385,231,308,234,385,215,359,231,308,215,359,201,330,231,308,201,330,193,303,231,308,193,303,140,-58,94,-89,98,-135,102,-61,102,-61,98,-135,117,-111,102,-61,117,-111,193,303,193,303,117,-111,131,-84,193,303,131,-84,140,-58,49,-140,44,-159,49,-141,16,-136,17,-143,18,-127,18,-127,17,-143,20,-150,18,-127,20,-150,21,-119,21,-119,20,-150,25,-155,21,-119,25,-155,27,-113,27,-113,25,-155,33,-158,27,-113,33,-158,34,-109,34,-109,33,-158,44,-159,336,-89,328,-112,341,-135,341,-135,328,-112,319,-129,341,-135,319,-129,316,-153,316,-153,319,-129,309,-140,316,-153,309,-140,296,-144,296,-144,294,-143,316,-153,316,-153,294,-143,293,-143,316,-153,293,-143,286,-159,286,-159,293,-143,292,-142,286,-159,292,-142,291,-141,405,396,412,412,404,397,404,397,412,412,402,397,388,393,402,397,412,412,388,393,412,412,380,404,422,361,423,411,414,360,414,360,423,411,412,412,414,360,412,412,409,360,409,360,412,412,407,392,409,360,407,392,406,390,409,360,406,390,405,362,405,362,406,390,404,387,405,362,404,387,402,364,402,364,404,387,402,384,402,364,402,384,399,379,399,379,398,372,399,368,399,379,399,368,402,364,440,390,439,396,438,380,438,380,439,396,436,402,438,380,436,402,435,372,435,372,436,402,431,407,435,372,431,407,429,366,429,366,431,407,423,411,429,366,423,411,422,361,412,412,405,396,407,395,412,412,407,395,407,394,412,412,407,394,407,392,380,404,355,385,359,337,380,404,359,337,368,362,380,404,368,362,377,380,380,404,377,380,388,393,352,308,359,337,355,385,352,308,355,385,336,359,352,308,336,359,322,330,352,308,322,330,314,303,352,308,314,303,260,-58,215,-89,219,-135,223,-61,223,-61,219,-135,238,-111,223,-61,238,-111,314,303,314,303,238,-111,251,-84,314,303,251,-84,260,-58,169,-140,164,-159,169,-141,137,-136,138,-143,138,-127,138,-127,138,-143,141,-150,138,-127,141,-150,142,-119,142,-119,141,-150,146,-155,142,-119,146,-155,147,-113,147,-113,146,-155,154,-158,147,-113,154,-158,154,-109,154,-109,154,-158,164,-159,435,303,344,-61,359,-111,435,303,359,-111,373,-84,435,303,373,-84,382,-58,435,303,382,-58,473,308,435,303,473,308,443,330,344,-61,336,-89,341,-135,344,-61,341,-135,359,-111,291,-140,286,-159,291,-141,258,-136,259,-143,259,-127,259,-127,259,-143,262,-150,259,-127,262,-150,263,-119,263,-119,262,-150,267,-155,263,-119,267,-155,269,-113,269,-113,267,-155,275,-158,269,-113,275,-158,276,-109,276,-109,275,-158,286,-159,527,396,534,412,525,397,525,397,534,412,523,397,510,393,523,397,534,412,510,393,534,412,502,404,544,361,545,411,536,360,536,360,545,411,534,412,536,360,534,412,531,360,531,360,534,412,529,392,531,360,529,392,528,390,531,360,528,390,527,362,527,362,528,390,526,387,527,362,526,387,523,364,523,364,526,387,523,384,523,364,523,384,521,379,521,379,520,372,521,368,521,379,521,368,523,364,561,390,560,396,560,380,560,380,560,396,558,402,560,380,558,402,556,372,556,372,558,402,552,407,556,372,552,407,551,366,551,366,552,407,545,411,551,366,545,411,544,361,534,412,527,396,528,395,534,412,528,395,529,394,534,412,529,394,529,392,502,404,476,385,481,337,502,404,481,337,489,362,502,404,489,362,499,380,502,404,499,380,510,393,473,308,481,337,476,385,473,308,476,385,457,359,473,308,457,359,443,330,288,-108,291,-140,293,-109,293,-109,292,-137,294,-135,167,-108,169,-140,171,-109,171,-109,170,-137,172,-135,46,-108,49,-140,51,-109,51,-109,49,-137,52,-135, 176,238,167,238,131,232,101,216,76,192,60,161,55,126,58,99,67,74,81,53,100,35,123,22,102,-61,94,-89,86,-112,77,-129,67,-140,54,-144,52,-143,50,-143,49,-142,49,-137,52,-135,54,-132,57,-127,57,-116,54,-112,51,-109,46,-108,42,-107,34,-109,27,-113,21,-119,18,-127,16,-136,18,-143,22,-150,28,-155,37,-158,49,-159,78,-153,102,-135,119,-111,131,-84,140,-58,157,13,167,13,202,19,233,35,258,59,274,90,280,126,276,152,267,177,253,199,234,216,211,229,231,308,239,337,247,362,257,381,268,393,281,397,283,397,285,396,287,394,287,392,286,390,284,387,281,384,279,379,278,372,279,368,281,364,289,360,294,360,302,361,309,366,315,372,318,380,320,390,318,396,314,402,307,407,298,411,287,412,255,404,231,385,213,358,201,330,193,303,16383,16383,162,32,206,210,224,199,239,185,251,167,258,147,261,126,256,96,243,70,222,50,197,37,167,32,16383,16383,172,219,127,41,109,52,95,66,83,84,76,104,74,126,78,155,92,181,112,201,137,214,167,219, 49,-140,49,-137,51,-109,51,-109,49,-137,52,-135,51,-109,52,-135,54,-112,54,-112,52,-135,54,-132,54,-112,54,-132,57,-116,57,-116,54,-132,57,-127,57,-116,57,-127,57,-120,18,-127,18,-143,21,-119,21,-119,18,-143,22,-150,21,-119,22,-150,27,-113,27,-113,22,-150,28,-155,27,-113,28,-155,34,-109,34,-109,28,-155,37,-158,34,-109,37,-158,42,-107,42,-107,37,-158,49,-159,42,-107,49,-159,46,-108,46,-108,49,-159,49,-140,86,-112,77,-129,78,-153,78,-153,77,-129,67,-140,78,-153,67,-140,54,-144,54,-144,52,-143,78,-153,78,-153,52,-143,50,-143,78,-153,50,-143,49,-159,49,-159,50,-143,49,-142,49,-159,49,-142,49,-141,95,66,100,35,109,52,109,52,100,35,123,22,109,52,123,22,127,41,127,41,123,22,131,-84,127,41,131,-84,172,219,172,219,131,-84,140,-58,172,219,140,-58,157,13,83,84,76,104,81,53,83,84,81,53,100,35,83,84,100,35,95,66,76,104,74,126,81,53,81,53,74,126,67,74,67,74,74,126,76,192,76,192,74,126,78,155,201,330,193,303,206,210,206,210,193,303,176,238,206,210,176,238,172,219,172,219,176,238,167,238,172,219,167,238,167,219,167,219,167,238,137,214,78,155,92,181,101,216,101,216,92,181,112,201,101,216,112,201,131,232,131,232,112,201,137,214,131,232,137,214,167,238,60,161,55,126,58,99,60,161,58,99,67,74,60,161,67,74,76,192,289,360,294,360,298,411,298,411,294,360,302,361,298,411,302,361,307,407,307,407,302,361,309,366,307,407,309,366,314,402,314,402,309,366,315,372,314,402,315,372,318,396,318,396,315,372,318,380,318,396,318,380,320,390,279,379,279,368,281,384,281,384,279,368,281,364,281,384,281,364,284,387,284,387,281,364,285,362,284,387,285,362,286,390,286,390,285,362,289,360,286,390,289,360,287,392,287,392,289,360,298,411,287,412,255,404,268,393,287,412,268,393,281,397,287,412,281,397,283,397,287,412,283,397,285,396,287,412,285,396,286,395,287,412,286,395,287,394,287,412,287,394,287,392,287,412,287,392,298,411,255,404,231,385,231,308,255,404,231,308,239,337,255,404,239,337,247,362,255,404,247,362,257,381,255,404,257,381,268,393,213,358,201,330,206,210,213,358,206,210,211,229,213,358,211,229,231,308,213,358,231,308,231,385,162,32,206,210,172,219,162,32,172,219,159,13,162,32,159,13,161,13,162,32,161,13,163,13,162,32,163,13,167,32,94,-89,102,-135,102,-61,102,-61,102,-135,119,-111,102,-61,119,-111,123,22,123,22,119,-111,131,-84,86,-112,78,-153,102,-135,86,-112,102,-135,94,-89,49,-140,49,-159,49,-141,258,59,274,90,261,126,261,126,267,177,258,147,258,147,267,177,253,199,258,147,253,199,251,167,251,167,253,199,239,185,234,216,211,229,224,199,234,216,224,199,239,185,234,216,239,185,253,199,274,90,280,126,276,152,274,90,276,152,267,177,274,90,267,177,261,126,258,59,261,126,256,96,258,59,256,96,243,70,258,59,243,70,233,35,163,13,165,13,167,32,167,32,165,13,167,13,167,32,167,13,197,37,197,37,167,13,202,19,197,37,202,19,222,50,222,50,202,19,233,35,222,50,233,35,243,70,224,199,211,229,206,210,279,368,279,379,278,372,18,-143,18,-127,16,-136,172,219,157,13,159,13,76,192,78,155,101,216,46,-108,49,-140,51,-109, 296,231,284,234,271,236,258,237,244,238,214,238,231,308,239,337,247,362,257,380,268,393,281,397,283,397,285,396,287,394,287,392,286,390,284,387,281,384,279,379,278,372,279,368,281,364,289,360,294,360,302,361,309,366,315,372,318,380,320,390,319,396,316,402,310,407,302,411,292,412,260,404,234,385,215,358,201,330,193,303,175,233,135,222,101,204,76,182,61,155,55,126,58,104,67,84,82,65,102,48,126,35,102,-61,94,-89,86,-112,77,-129,67,-140,54,-144,52,-143,50,-143,49,-142,49,-137,52,-135,54,-132,57,-127,57,-116,54,-112,51,-109,46,-108,42,-107,34,-109,27,-113,21,-119,18,-127,16,-136,17,-143,20,-150,25,-155,33,-158,44,-159,74,-153,99,-135,117,-111,131,-84,140,-58,160,22,172,19,200,15,230,13,235,13,237,14,242,14,223,-61,216,-89,208,-112,199,-129,188,-140,175,-144,173,-143,172,-143,170,-142,170,-140,171,-137,173,-135,175,-132,178,-127,179,-120,178,-116,175,-112,172,-109,168,-108,163,-107,155,-109,148,-113,142,-119,139,-127,137,-136,138,-143,141,-150,146,-155,154,-158,165,-159,195,-153,220,-135,239,-111,252,-84,261,-58,280,18,321,29,356,47,382,70,398,96,404,126,401,149,391,170,376,189,355,206,330,219,352,308,360,337,368,362,378,380,389,393,402,397,404,397,406,396,408,394,408,392,407,390,405,387,402,384,400,379,399,372,400,368,402,364,410,360,415,360,423,361,430,366,435,372,439,380,440,390,439,396,436,402,431,407,424,411,413,412,381,404,355,385,336,359,323,330,314,303,16383,16383,325,200,345,188,362,175,374,160,382,143,385,126,380,103,367,82,345,64,318,50,285,39,16383,16383,247,33,235,33,232,32,228,32,214,33,201,34,188,36,176,38,165,41,209,219,241,219,267,217,291,211,16383,16383,131,54,111,65,96,78,84,93,77,109,74,126,79,149,91,170,112,188,138,203,171,213, 49,-137,51,-109,49,-140,49,-140,46,-108,44,-159,44,-159,46,-108,42,-107,44,-159,42,-107,34,-109,51,-109,52,-135,54,-112,54,-112,52,-135,54,-132,54,-112,54,-132,57,-116,57,-116,54,-132,57,-127,57,-116,57,-127,57,-120,94,-89,86,-112,99,-135,99,-135,86,-112,77,-129,99,-135,77,-129,74,-153,74,-153,77,-129,67,-140,74,-153,67,-140,54,-144,54,-144,52,-143,74,-153,74,-153,52,-143,50,-143,74,-153,50,-143,44,-159,44,-159,50,-143,49,-142,44,-159,49,-142,49,-141,96,78,102,48,111,65,111,65,102,48,126,35,111,65,126,35,131,54,131,54,126,35,131,-84,131,54,131,-84,171,213,171,213,131,-84,140,-58,171,213,140,-58,160,22,84,93,77,109,82,65,84,93,82,65,102,48,84,93,102,48,96,78,77,109,74,126,82,65,82,65,74,126,67,84,67,84,74,126,76,182,76,182,74,126,79,149,171,-137,172,-109,170,-140,170,-140,168,-108,165,-159,165,-159,168,-108,163,-107,165,-159,163,-107,155,-109,172,-109,173,-135,175,-112,175,-112,173,-135,175,-132,175,-112,175,-132,178,-116,178,-116,175,-132,178,-127,178,-116,178,-127,179,-120,216,-89,208,-112,220,-135,220,-135,208,-112,199,-129,220,-135,199,-129,195,-153,195,-153,199,-129,188,-140,195,-153,188,-140,175,-144,175,-144,173,-143,195,-153,195,-153,173,-143,172,-143,195,-153,172,-143,165,-159,165,-159,172,-143,170,-142,165,-159,170,-142,170,-141,201,330,193,303,209,219,209,219,193,303,175,233,209,219,175,233,171,213,171,213,175,233,138,203,138,203,175,233,135,222,138,203,135,222,112,188,112,188,135,222,101,204,112,188,101,204,91,170,91,170,101,204,79,149,61,155,55,126,58,104,61,155,58,104,67,84,61,155,67,84,76,182,285,396,292,412,283,397,283,397,292,412,281,397,268,393,281,397,292,412,268,393,292,412,260,404,302,361,302,411,294,360,294,360,302,411,292,412,294,360,292,412,289,360,289,360,292,412,287,392,289,360,287,392,286,390,289,360,286,390,285,362,285,362,286,390,284,387,285,362,284,387,281,364,281,364,284,387,281,384,281,364,281,384,279,368,279,368,281,384,279,379,279,368,279,379,278,372,320,390,319,396,318,380,318,380,319,396,316,402,318,380,316,402,315,372,315,372,316,402,310,407,315,372,310,407,309,366,309,366,310,407,302,411,309,366,302,411,302,361,292,412,285,396,286,395,292,412,286,395,287,394,292,412,287,394,287,392,260,404,234,385,239,337,260,404,239,337,247,362,260,404,247,362,257,380,260,404,257,380,268,393,239,337,234,385,231,308,231,308,234,385,215,358,231,308,215,358,214,238,214,238,215,358,212,219,214,238,212,219,216,219,215,358,201,330,209,219,215,358,209,219,212,219,176,38,165,41,172,19,171,213,165,41,209,219,160,22,172,19,165,41,160,22,165,41,171,213,94,-89,99,-135,102,-61,102,-61,99,-135,117,-111,102,-61,117,-111,126,35,126,35,117,-111,131,-84,49,-140,44,-159,49,-141,16,-136,17,-143,18,-127,18,-127,17,-143,20,-150,18,-127,20,-150,21,-119,21,-119,20,-150,25,-155,21,-119,25,-155,27,-113,27,-113,25,-155,33,-158,27,-113,33,-158,34,-109,34,-109,33,-158,44,-159,296,231,284,234,291,211,291,211,325,200,296,231,296,231,325,200,314,303,406,396,413,412,404,397,404,397,413,412,402,397,389,393,402,397,413,412,389,393,413,412,381,404,423,361,424,411,415,360,415,360,424,411,413,412,415,360,413,412,410,360,410,360,413,412,408,392,410,360,408,392,407,390,410,360,407,390,406,362,406,362,407,390,405,387,406,362,405,387,402,364,402,364,405,387,402,384,402,364,402,384,400,379,400,379,399,372,400,368,400,379,400,368,402,364,440,390,439,396,439,380,439,380,439,396,436,402,439,380,436,402,435,372,435,372,436,402,431,407,435,372,431,407,430,366,430,366,431,407,424,411,430,366,424,411,423,361,413,412,406,396,407,395,413,412,407,395,408,394,413,412,408,394,408,392,381,404,355,385,360,337,381,404,360,337,368,362,381,404,368,362,378,380,381,404,378,380,389,393,336,359,330,219,352,308,336,359,352,308,355,385,355,385,352,308,360,337,336,359,325,200,330,219,330,219,325,200,345,188,330,219,345,188,355,206,355,206,345,188,362,175,355,206,362,175,376,189,376,189,362,175,374,160,376,189,374,160,382,143,323,330,314,303,325,200,323,330,325,200,336,359,291,211,247,33,252,-84,291,211,252,-84,261,-58,291,211,261,-58,280,18,291,211,280,18,285,39,291,211,285,39,325,200,243,33,239,33,239,14,243,33,239,14,242,14,243,33,242,14,252,-84,243,33,252,-84,247,33,216,-89,220,-135,223,-61,223,-61,220,-135,239,-111,223,-61,239,-111,242,14,242,14,239,-111,252,-84,170,-140,165,-159,170,-141,137,-136,138,-143,139,-127,139,-127,138,-143,141,-150,139,-127,141,-150,142,-119,142,-119,141,-150,146,-155,142,-119,146,-155,148,-113,148,-113,146,-155,154,-158,148,-113,154,-158,155,-109,155,-109,154,-158,165,-159,404,126,401,149,398,96,398,96,401,149,391,170,398,96,391,170,385,126,385,126,382,70,398,96,391,170,376,189,382,143,391,170,382,143,385,126,385,126,380,103,382,70,382,70,380,103,367,82,382,70,367,82,356,47,356,47,367,82,345,64,356,47,345,64,321,29,321,29,345,64,318,50,321,29,318,50,285,39,280,18,321,29,285,39,176,38,186,17,188,36,188,36,186,17,200,15,188,36,200,15,201,34,201,34,200,15,215,14,201,34,215,14,214,33,214,33,215,14,228,32,232,32,228,32,230,13,232,32,230,13,232,13,291,211,284,234,279,214,279,214,284,234,271,236,279,214,271,236,267,217,267,217,271,236,258,237,267,217,258,237,254,218,254,218,258,237,244,238,254,218,244,238,241,219,241,219,244,238,230,238,241,219,230,238,228,219,232,13,235,13,235,33,235,33,235,13,237,14,235,33,237,14,239,33,239,33,237,14,239,14,230,238,214,238,216,219,230,238,216,219,220,219,230,238,220,219,224,219,230,238,224,219,228,219,228,32,215,14,230,13,232,32,232,13,235,33,176,38,172,19,186,17,76,182,79,149,101,204,168,-108,170,-140,172,-109,172,-109,171,-137,173,-135,46,-108,49,-140,51,-109,51,-109,49,-137,52,-135, 319,60,319,93,170,93,200,160,319,160,319,193,214,193,274,331,247,331,187,193,24,193,24,160,172,160,143,93,24,93,24,60,128,60,69,-77,95,-77,156,60, 128,60,69,-77,95,-77,128,60,95,-77,156,60,128,60,156,60,143,93,128,60,143,93,24,93,128,60,24,93,24,60,172,160,143,93,156,60,172,160,156,60,170,93,172,160,170,93,200,160,172,160,200,160,187,193,172,160,187,193,24,193,172,160,24,193,24,160,214,193,274,331,247,331,214,193,247,331,200,160,214,193,200,160,319,160,214,193,319,160,319,193,170,93,156,60,319,60,170,93,319,60,319,93,187,193,200,160,247,331, 319,206,319,239,24,239,24,206,16383,16383,319,110,319,143,24,143,24,110,16383,16383,319,14,319,47,24,47,24,14, 24,239,24,206,319,206,24,239,319,206,319,239,24,143,24,110,319,110,24,143,319,110,319,143,24,47,24,14,319,14,24,47,319,14,319,47, 319,14,319,47,150,47,177,110,319,110,319,143,192,143,219,206,319,206,319,239,233,239,274,331,247,331,207,239,24,239,24,206,193,206,165,143,24,143,24,110,151,110,123,47,24,47,24,14,108,14,69,-77,95,-77,136,14, 108,14,69,-77,95,-77,108,14,95,-77,136,14,108,14,136,14,123,47,108,14,123,47,24,47,108,14,24,47,24,14,151,110,123,47,136,14,151,110,136,14,150,47,151,110,150,47,177,110,151,110,177,110,165,143,151,110,165,143,24,143,151,110,24,143,24,110,193,206,165,143,177,110,193,206,177,110,192,143,193,206,192,143,219,206,193,206,219,206,207,239,193,206,207,239,24,239,193,206,24,239,24,206,233,239,274,331,247,331,233,239,247,331,219,206,233,239,219,206,319,206,233,239,319,206,319,239,192,143,177,110,319,110,192,143,319,110,319,143,150,47,136,14,319,14,150,47,319,14,319,47,207,239,219,206,247,331, 319,239,319,272,24,272,24,239,16383,16383,319,153,319,186,24,186,24,153,16383,16383,319,67,319,100,24,100,24,67,16383,16383,319,-18,319,14,24,14,24,-18, 24,272,24,239,319,239,24,272,319,239,319,272,24,186,24,153,319,153,24,186,319,153,319,186,24,100,24,67,319,67,24,100,319,67,319,100,24,14,24,-18,319,-18,24,14,319,-18,319,14, 315,26,315,57,99,165,315,272,315,305,32,167,32,162,16383,16383,315,-50,315,-17,32,-17,32,-50, 99,165,315,272,315,305,99,165,315,305,32,167,99,165,32,167,315,26,99,165,315,26,315,57,32,-17,32,-50,315,-50,32,-17,315,-50,315,-17,315,26,32,167,32,162, 315,162,315,167,32,305,32,272,248,165,32,57,32,26,16383,16383,315,-50,315,-17,32,-17,32,-50, 248,165,32,57,315,162,248,165,315,162,315,167,248,165,315,167,32,305,248,165,32,305,32,272,32,-17,32,-50,315,-50,32,-17,315,-50,315,-17,315,162,32,57,32,26, 311,80,311,112,95,219,311,326,311,359,28,222,28,217,16383,16383,311,-5,311,27,28,27,28,-5,16383,16383,311,-104,311,-72,28,-72,28,-104, 95,219,311,326,311,359,95,219,311,359,28,222,95,219,28,222,311,80,95,219,311,80,311,112,28,27,28,-5,311,-5,28,27,311,-5,311,27,28,-72,28,-104,311,-104,28,-72,311,-104,311,-72,311,80,28,222,28,217, 311,217,311,222,28,359,28,326,244,219,28,112,28,80,16383,16383,311,-5,311,27,28,27,28,-5,16383,16383,311,-104,311,-72,28,-72,28,-104, 244,219,28,112,311,217,244,219,311,217,311,222,244,219,311,222,28,359,244,219,28,359,28,326,28,27,28,-5,311,-5,28,27,311,-5,311,27,28,-72,28,-104,311,-104,28,-72,311,-104,311,-72,311,217,28,112,28,80, 310,94,310,126,94,233,310,340,310,373,28,235,28,230,16383,16383,310,-91,310,-58,158,-58,200,8,310,8,310,41,221,41,245,79,215,79,191,41,28,41,28,8,171,8,128,-58,28,-58,28,-91,108,-91,84,-129,114,-129,138,-91, 94,233,310,340,310,373,94,233,310,373,28,235,94,233,28,235,310,94,94,233,310,94,310,126,28,41,171,8,191,41,191,41,171,8,200,8,191,41,200,8,215,79,215,79,200,8,221,41,215,79,221,41,245,79,221,41,200,8,310,8,221,41,310,8,310,41,108,-91,114,-129,128,-58,128,-58,114,-129,138,-91,128,-58,138,-91,171,8,171,8,138,-91,158,-58,171,8,158,-58,200,8,28,-58,28,-91,108,-91,28,-58,108,-91,128,-58,158,-58,138,-91,310,-91,158,-58,310,-91,310,-58,114,-129,108,-91,84,-129,171,8,28,41,28,8,310,94,28,235,28,230, 310,230,310,235,28,373,28,340,244,233,28,126,28,94,16383,16383,310,-91,310,-58,165,-58,207,8,310,8,310,41,228,41,252,79,222,79,198,41,28,41,28,8,177,8,135,-58,28,-58,28,-91,114,-91,91,-129,121,-129,145,-91, 244,233,28,126,310,230,244,233,310,230,310,235,244,233,310,235,28,373,244,233,28,373,28,340,28,41,177,8,198,41,198,41,177,8,207,8,198,41,207,8,222,79,222,79,207,8,228,41,222,79,228,41,252,79,228,41,207,8,310,8,228,41,310,8,310,41,114,-91,121,-129,135,-58,135,-58,121,-129,145,-91,135,-58,145,-91,177,8,177,8,145,-91,165,-58,177,8,165,-58,207,8,28,-58,28,-91,114,-91,28,-58,114,-91,135,-58,165,-58,145,-91,310,-91,165,-58,310,-91,310,-58,121,-129,114,-91,91,-129,177,8,28,41,28,8,310,230,28,126,28,94, 454,-12,454,18,238,127,454,233,454,266,171,129,171,124,16383,16383,295,-12,295,18,79,127,295,233,295,266,12,129,12,124, 238,127,454,233,454,266,238,127,454,266,171,129,238,127,171,129,454,-12,238,127,454,-12,454,18,79,127,295,233,295,266,79,127,295,266,12,129,79,127,12,129,295,-12,79,127,295,-12,295,18,295,-12,12,129,12,124,454,-12,171,129,171,124, 454,124,454,129,171,266,171,233,387,127,171,18,171,-12,16383,16383,295,124,295,129,12,266,12,233,228,127,12,18,12,-12, 387,127,171,18,454,124,387,127,454,124,454,129,387,127,454,129,171,266,387,127,171,266,171,233,228,127,12,18,295,124,228,127,295,124,295,129,228,127,295,129,12,266,228,127,12,266,12,233,295,124,12,18,12,-12,454,124,171,18,171,-12, 190,-102,179,-89,167,-74,154,-59,130,-25,149,4,165,35,176,66,183,97,185,127,183,156,176,187,164,218,149,248,130,278,142,296,154,312,167,328,179,342,190,355,190,365,174,353,158,340,143,326,130,312,117,296,103,312,89,326,74,340,59,353,42,365,42,357,66,329,78,313,91,296,103,278,84,249,68,218,57,187,50,156,47,127,50,97,57,66,68,35,84,4,103,-25,91,-42,78,-58,66,-74,42,-102,42,-111,59,-99,89,-73,117,-43,143,-73,158,-86,174,-99,190,-111,16383,16383,152,127,151,98,146,70,138,45,128,20,116,-2,104,20,95,45,87,71,82,98,80,127,82,155,87,182,95,208,105,233,117,256,128,233,138,208,146,182,151,155,152,127, 130,278,142,296,143,326,143,326,142,296,154,312,143,326,154,312,158,340,158,340,154,312,167,328,158,340,167,328,174,353,174,353,167,328,179,342,174,353,179,342,190,365,190,365,179,342,190,355,117,296,103,312,105,233,117,296,105,233,117,256,117,256,128,233,130,312,130,312,128,233,130,278,130,312,130,278,143,326,116,-2,117,-43,128,20,128,20,117,-43,130,-58,128,20,130,-58,130,-25,130,-25,130,-58,143,-73,130,-25,138,45,128,20,183,97,183,156,176,66,176,66,183,156,176,187,176,66,176,187,165,35,165,35,176,187,164,218,165,35,164,218,152,127,152,127,164,218,151,155,149,248,130,278,138,208,149,248,138,208,146,182,149,248,146,182,151,155,149,248,151,155,164,218,130,312,117,296,117,256,165,35,152,127,151,98,165,35,151,98,149,4,149,4,151,98,146,70,149,4,146,70,138,45,142,-42,143,-73,154,-59,154,-59,143,-73,158,-86,154,-59,158,-86,167,-74,167,-74,158,-86,174,-99,167,-74,174,-99,179,-89,179,-89,174,-99,190,-111,179,-89,190,-111,190,-102,105,233,103,312,103,278,103,278,103,312,91,296,91,296,103,312,89,326,91,296,89,326,78,313,78,313,89,326,74,340,78,313,74,340,66,329,66,329,74,340,59,353,66,329,59,353,54,343,54,343,59,353,42,365,54,343,42,365,42,357,103,-58,103,-25,91,-42,103,-58,91,-42,89,-73,89,-73,91,-42,78,-58,89,-73,78,-58,74,-86,74,-86,78,-58,66,-74,74,-86,66,-74,59,-99,59,-99,66,-74,54,-88,59,-99,54,-88,42,-102,104,20,95,45,103,-25,104,20,103,-25,103,-58,104,20,103,-58,117,-43,104,20,117,-43,116,-2,103,278,84,249,87,182,103,278,87,182,95,208,103,278,95,208,105,233,84,249,68,218,68,35,84,249,68,35,80,127,84,249,80,127,82,155,84,249,82,155,87,182,87,71,82,98,84,4,84,4,82,98,80,127,68,35,68,218,57,66,57,66,68,218,57,187,57,66,57,187,50,97,50,97,57,187,50,156,50,97,50,156,47,127,87,71,84,4,103,-25,87,71,103,-25,95,45,84,4,80,127,68,35,59,-99,42,-102,42,-111,130,-25,143,-73,142,-42,138,45,130,-25,149,4,183,156,183,97,185,127,130,278,128,233,138,208, 319,22,300,49,273,71,242,87,207,96,174,100,198,155,227,162,255,173,281,188,303,208,319,232,319,249,302,230,283,215,261,204,237,195,213,190,254,286,228,286,184,186,171,186,138,188,105,195,75,206,47,224,24,249,24,232,43,204,69,182,101,166,135,156,170,153,146,98,116,92,88,81,61,65,40,46,24,22,24,4,40,22,60,38,82,49,106,58,131,64,89,-32,116,-32,159,66,161,67,171,67,204,65,237,58,268,46,295,28,319,4, 40,22,60,38,61,65,61,65,60,38,82,49,61,65,82,49,88,81,88,81,82,49,106,58,88,81,106,58,116,92,116,92,106,58,131,64,146,98,131,64,159,66,146,98,159,66,170,153,170,153,159,66,161,67,170,153,161,67,164,67,40,22,61,65,40,46,40,22,40,46,24,22,40,22,24,22,24,4,135,156,170,153,138,188,138,188,170,153,171,186,173,186,171,186,171,67,173,186,171,67,174,100,174,100,171,67,204,65,174,100,204,65,207,96,207,96,204,65,237,58,207,96,237,58,242,87,242,87,237,58,268,46,242,87,268,46,273,71,273,71,268,46,295,28,273,71,295,28,300,49,300,49,295,28,319,4,300,49,319,4,319,22,24,249,43,204,47,224,47,224,43,204,69,182,47,224,69,182,75,206,75,206,69,182,101,166,75,206,101,166,105,195,105,195,101,166,135,156,105,195,135,156,138,188,171,67,171,186,170,153,171,67,170,153,168,67,170,153,164,67,166,67,170,153,166,67,168,67,131,64,89,-32,116,-32,131,64,116,-32,159,66,319,249,302,230,303,208,303,208,302,230,283,215,303,208,283,215,281,188,281,188,283,215,261,204,281,188,261,204,255,173,255,173,261,204,237,195,255,173,237,195,227,162,227,162,237,195,213,190,227,162,213,190,198,155,228,286,184,186,198,155,228,286,198,155,213,190,228,286,213,190,254,286,198,155,184,186,181,186,198,155,181,186,179,186,198,155,179,186,176,186,198,155,176,186,174,100,176,186,173,186,174,100,43,204,24,249,24,232,319,249,303,208,319,232,116,92,131,64,146,98, 310,-12,310,18,171,88,214,185,310,233,310,266,232,228,277,331,250,331,198,211,28,128,28,123,137,71,71,-77,99,-77,158,60,16383,16383,179,168,148,99,94,126, 198,211,28,128,94,126,94,126,28,128,137,71,94,126,137,71,148,99,148,99,137,71,158,60,148,99,158,60,179,168,179,168,158,60,171,88,179,168,171,88,214,185,94,126,179,168,198,211,198,211,179,168,214,185,198,211,214,185,250,331,250,331,214,185,232,228,250,331,232,228,277,331,137,71,71,-77,99,-77,137,71,99,-77,158,60,232,228,214,185,310,233,232,228,310,233,310,266,171,88,158,60,310,-12,171,88,310,-12,310,18,137,71,28,128,28,123, 310,123,310,128,203,181,268,331,241,331,180,192,28,266,28,233,168,164,126,68,28,18,28,-12,108,26,63,-77,89,-77,142,42,16383,16383,244,126,161,84,190,153, 108,26,63,-77,89,-77,108,26,89,-77,142,42,108,26,142,42,126,68,108,26,126,68,28,18,108,26,28,18,28,-12,168,164,126,68,142,42,168,164,142,42,161,84,168,164,161,84,190,153,168,164,190,153,180,192,168,164,180,192,28,266,168,164,28,266,28,233,203,181,268,331,241,331,203,181,241,331,190,153,203,181,190,153,244,126,203,181,244,126,310,128,310,123,310,128,244,126,310,123,244,126,161,84,310,123,161,84,142,42,180,192,190,153,241,331, 320,0,320,33,190,33,190,331,157,331,157,33,26,33,26,0, 190,331,157,331,190,33,190,33,157,331,157,33,190,33,157,33,320,0,320,0,157,33,26,33,320,0,26,33,26,0,190,33,320,0,320,33, }; mathgl-2.4.4/src/font.cpp0000644000175000017500000011154613513030041015416 0ustar alastairalastair/*************************************************************************** * font.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #ifdef WIN32 #include #include #else #include #endif #if !defined(__BORLANDC__) || (__CODEGEARC__ >= 0x0630) #include #else #include #endif #include "mgl2/base.h" #include "mgl2/font.h" #include "def_font.cc" #include "tex_table.cc" //----------------------------------------------------------------------------- //mglFont mglDefFont("nofont"); mglFont mglDefFont; #define MGL_USE_H12 {if(h1y2) y2=h2; h1=1e5; h2=-1e5;} //----------------------------------------------------------------------------- size_t MGL_EXPORT_PURE mgl_wcslen(const wchar_t *str) { long i=0; if(str) while(str[i]) i++; return i; } //----------------------------------------------------------------------------- long MGL_EXPORT_PURE mgl_internal_code(unsigned s, const std::vector &glyphs) { long i1=0,i2=glyphs.size()-1; wchar_t j = wchar_t(s & MGL_FONT_MASK); // let suppose that id[i]glyphs[i].id) i1=i+1; else return i; } return j==glyphs[i2].id ? i2 : -1; } //----------------------------------------------------------------------------- bool MGL_EXPORT mglGetStyle(const char *how, int *font, int *align) { bool col=false; if(align) *align = 1; // centering text by default if(!how || *how==0) return col; // NOTE: no brightness for text color for(;*how && *how!=':';how++) { if(strchr(MGL_COLORS,*how)) col = true; if(*how=='{' && how[1]=='x') col = true; } if(align) { *align = 1; if(strchr(how,'R')) *align = 2; // if(strchr(how,'C')) *align = 1; if(strchr(how,'L')) *align = 0; if(strchr(how,'D')) *align+= 4; } if(font) { *font = 0; if(strchr(how,'b')) *font = *font|MGL_FONT_BOLD; if(strchr(how,'i')) *font = *font|MGL_FONT_ITAL; if(strchr(how,'w')) *font = *font|MGL_FONT_WIRE; if(strchr(how,'o')) *font = *font|MGL_FONT_OLINE; if(strchr(how,'u')) *font = *font|MGL_FONT_ULINE; } return col; } //----------------------------------------------------------------------------- float mglFont::Puts(const char *str,const char *how,float c1,float c2) const { int font=0, align=1; float w=0; mglGetStyle(how,&font,&align); MGL_TO_WCS(str,w = Puts(wcs,font,align,c1,c2)); return w; } //----------------------------------------------------------------------------- float mglFont::Width(const char *str,const char *how, float *y1, float *y2) const { float w=0; MGL_TO_WCS(str,w = Width(wcs,how,y1,y2)); return w; } //----------------------------------------------------------------------------- float mglFont::Puts(const wchar_t *str,const char *how,float c1,float c2) const { int font=0, align=1; mglGetStyle(how,&font,&align); return Puts(str, font, align,c1,c2); } //----------------------------------------------------------------------------- float mglFont::Width(const wchar_t *str,const char *how, float *y1, float *y2) const { int font=0, align=1; float v1,v2; if(!y1) y1 = &v1; if(!y2) y2 = &v2; mglGetStyle(how,&font,&align); return Width(str, font, align, *y1, *y2); } //----------------------------------------------------------------------------- float mglFont::Puts(const wchar_t *str,int font,int align, float c1,float c2) const { if(GetNumGlyph()==0 || !str || *str==0) return 0; float ww=0,w=0,h = (align&4) ? 500./fact[0] : 0, y1=0,y2=0; size_t size = mgl_wcslen(str)+1,num=0; if(parse) { unsigned *wcs = new unsigned[size], *buf=wcs; memcpy(wcs,str,size*sizeof(wchar_t)); Convert(str, wcs); for(size_t i=0;wcs[i];i++) { if(wcs[i]=='\n') // parse '\n' symbol { wcs[i]=0; w = Puts(buf,0,0,1.f,0x10|font,c1,c2, y1,y2); // find width Puts(buf,-w*(align&3)/2.f,-h - 660*num/fact[0],1.f,font,c1,c2, y1,y2); // draw it really buf=wcs+i+1; num++; if(w>ww) ww=w; } // if(wcs[i]=='\\' && wcs[i+1]=='n' && (wcs[i+2]>' ' || wcschr(L"{}[]()!@#$%^&*/-?.,_=+\\\"", wcs[i+2]))) // parse '\n' symbol // { // wcs[i]=0; w = Puts(buf,0,0,1.f,0x10|font,c1,c2); // find width // Puts(buf,-w*(align&3)/2.f,-h - 720.*num/fact[0],1.f,font,c1,c2); // draw it really // buf=wcs+i+2; num++; if(w>ww) ww=w; // } } // draw string itself w = Puts(buf,0,0,1.f,0x10|font,c1,c2, y1,y2); // find width Puts(buf,-w*(align&3)/2.f,-h - 660*num/fact[0],1.f,font,c1,c2, y1,y2); // draw it really if(w>ww) ww=w; delete []wcs; } else { int s = (font/MGL_FONT_BOLD)&3; h *= fact[0]/fact[s]; for(size_t i=0;iGlyph(w, -h, 1, (s+(font&MGL_FONT_WIRE))?4:0, j, c1+i*(c2-c1)/(size-1)); } w+= GetWidth(s,j)/fact[s]; } } return ww; } //----------------------------------------------------------------------------- float mglFont::Width(const wchar_t *str,int font, int align, float &y1, float &y2) const { if(GetNumGlyph()==0 || !str || *str==0) return 0; float ww=0,w=0, h1=1e5,h2=-1e5; float h = (align&4) ? 500./fact[0] : 0; size_t size = mgl_wcslen(str)+1, num=0; y1=1e5; y2=-1e5; if(parse) { unsigned *wcs = new unsigned[size], *buf=wcs; memcpy(wcs,str,size*sizeof(wchar_t)); Convert(str, wcs); for(size_t i=0;wcs[i];i++) if(wcs[i]=='\n') // parse '\n' symbol { wcs[i]=0; w = Puts(buf,0,0,1.,0x10|font,'k','k', h1,h2); // find width h1 -= h+660*num/fact[0]; h2 -= h+660*num/fact[0]; MGL_USE_H12 buf=wcs+i+1; if(w>ww) ww=w; num++; } w = Puts(buf,0,0,1.,0x10|font,'k','k', h1,h2); h1 -= h+660*num/fact[0]; h2 -= h+660*num/fact[0]; MGL_USE_H12 if(wtex, bb->tex); } //----------------------------------------------------------------------------- // parse LaTeX commands (mostly symbols and acents, and some font-style commands) unsigned mglFont::Parse(const wchar_t *s) const { unsigned res = unsigned(-2); // Default is no symbol if(!s || !s[0]) return res; mglTeXsymb tst, *rts; tst.tex = s; rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, mgl_tex_num, sizeof(mglTeXsymb), mgl_tex_symb_cmp); if(rts) return rts->kod; for(long k=0;mgl_act_symb[k].kod;k++) // acents if(!wcscmp(s,mgl_act_symb[k].tex)) return mgl_act_symb[k].kod | MGL_FONT_ZEROW; // arbitrary UTF symbol if(s[0]=='u' && s[1]=='t' && s[2]=='f') { long k = wcstoul(s+3,NULL,16); return wchar_t(k); } // font/style changes for next symbol if(!wcscmp(s,L"big")) res = unsigned(-5); else if(!wcscmp(s,L"frac")) res = unsigned(-6); else if(!wcscmp(s,L"stack")) res = unsigned(-7); else if(!wcscmp(s,L"overset")) res = unsigned(-8); else if(!wcscmp(s,L"underset")) res = unsigned(-9); else if(!wcscmp(s,L"stackr")) res = unsigned(-10); else if(!wcscmp(s,L"stackl")) res = unsigned(-11); else if(!wcscmp(s,L"sub")) res = unsigned(-9); //unsigned(-12); else if(!wcscmp(s,L"sup")) res = unsigned(-8); //unsigned(-13); else if(!wcscmp(s,L"textsc")) res = unsigned(-14); // new else if(!wcscmp(s,L"dfrac")) res = unsigned(-15); else if(!wcscmp(s,L"b")) res = MGL_FONT_BOLD; else if(!wcscmp(s,L"i")) res = MGL_FONT_ITAL; else if(!wcscmp(s,L"bi")) res = MGL_FONT_BOLD|MGL_FONT_ITAL; else if(!wcscmp(s,L"r")) res = unsigned(-1); else if(!wcscmp(s,L"a")) res = MGL_FONT_OLINE; else if(!wcscmp(s,L"u")) res = MGL_FONT_ULINE; else if(!wcscmp(s,L"n")) res = '\n'; else if(!wcscmp(s,L"overline")) res = MGL_FONT_OLINE; else if(!wcscmp(s,L"underline"))res = MGL_FONT_ULINE; else if(!wcscmp(s,L"textbf")) res = MGL_FONT_BOLD; else if(!wcscmp(s,L"textit")) res = MGL_FONT_ITAL; else if(!wcscmp(s,L"textrm")) res = unsigned(-1); else if(!wcscmp(s,L"T2A")) res = unsigned(-1); else if(!wcscmp(s,L"w")) res = MGL_FONT_WIRE; else if(!wcscmp(s,L"wire")) res = MGL_FONT_WIRE; else if(!wcsncmp(s,L"color",5)) res = MGL_COLOR_MASK + (0xff & s[5]); return res; } //----------------------------------------------------------------------------- void mglFont::Convert(const wchar_t *str, unsigned *res) const { size_t j=0; wchar_t s[128]=L""; // TeX command and current char for(size_t i=0;str[i];i++) { wchar_t ch = str[i]; if(ch=='\\') // It can be TeX command { if(wcschr(L"{}_^\\@# ",str[i+1])) // No, it is usual symbol res[j++] = str[++i]; else // Yes, it is TeX command { size_t i0=i+1, k; for(k=0;isalnum(str[++i]) && k<127;k++) s[k] = str[i]; s[k] = 0; size_t r = Parse(s); if(r==unsigned(-2)) // command not found, so use next symbol itself { res[j++] = str[i0]; i = i0; } else if(r) { res[j++] = r; if(str[i]>' ') i--; if(str[i]==0) break; } } } else if(ch=='-' && str[i+1]=='-') { res[j++] = 0x2212; i++; } else if(ch=='\b'){} else if(ch<=' ' && ch!='\n') res[j++] = ' '; // no \t at this moment :( else if(ch=='_') res[j++] = MGL_FONT_LOWER; else if(ch=='^') res[j++] = MGL_FONT_UPPER; else if(ch=='@') res[j++] = MGL_FONT_UPPER|MGL_FONT_LOWER; else if(ch=='{') res[j++] = unsigned(-3); else if(ch=='}') res[j++] = unsigned(-4); else if(ch=='#' && str[i+1]>' ') res[j++] = MGL_COLOR_MASK + (0xff & str[++i]); // TODO inline colors -- stack of RGBA colors + index else res[j++] = ch; // It is just symbol } res[j] = 0; } //----------------------------------------------------------------------------- float mglFont::get_ptr(long &i,unsigned *str, unsigned **b1, unsigned **b2,float &w1,float &w2, float f1, float f2, int st) const { static unsigned s1[2]={0,0}, s2[2]={0,0}; i++; if(str[i]==unsigned(-3)) { i++; *b1 = str+i; for(long k=1;k>0 && str[i];i++) { if(str[i]==unsigned(-4)) k--; if(str[i]==unsigned(-3)) k++; } str[i-1]=0; } else { s1[0] = str[i]; *b1 = s1; i++; } if(str[i]==unsigned(-3)) { i++; *b2 = str+i; for(long k=1;k>0 && str[i];i++) { if(str[i]==unsigned(-4)) k--; if(str[i]==unsigned(-3)) k++; } str[i-1]=0; } else { s2[0] = str[i]; *b2 = s2; i++; } i--; float y1=0,y2=0; w1 = Puts(*b1, 0, 0, f1, 0x10|st,'k','k', y1,y2); w2 = Puts(*b2, 0, 0, f2, 0x10|st,'k','k', y1,y2); return w1>w2 ? w1 : w2; } //----------------------------------------------------------------------------- void mglFont::draw_ouline(int st, float x, float y, float f, float g, float ww, float ccol) const { if(st&MGL_FONT_OLINE) gr->Glyph(x,y+499*f/g, ww*g, (st&MGL_FONT_WIRE)?12:8, 0, ccol); if(st&MGL_FONT_ULINE) gr->Glyph(x,y-200*f/g, ww*g, (st&MGL_FONT_WIRE)?12:8, 0, ccol); } //----------------------------------------------------------------------------- #define MGL_CLEAR_STYLE {st = style; yy = y; ff = f; ccol=c1+dc*i; a = (st/MGL_FONT_BOLD)&3;} float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,float c1,float c2, float &y1,float &y2) const { if(GetNumGlyph()==0) return 0; float w=0; // string width int st = style; // current style unsigned *b1, *b2; // pointer to substring unsigned *str; // string itself float yy=y, ff=f, ww, w1, w2, h1=1e5,h2=-1e5; int a = (st/MGL_FONT_BOLD)&3; long i; for(i=0;text[i];i++); float dc=i>1?(c2-c1)/(i-1):0; str = new unsigned[i+1]; memcpy(str,text,(i+1)*sizeof(unsigned)); float ccol = 0; for(long i=0;str[i];i++) { ccol = ccol<0?ccol:c1+dc*i; unsigned s = str[i]; ww = 0; if(s==unsigned(-3)) // recursion call here for {}-block { i++; b1 = str+i; for(long k=1;k>0 && str[i];i++) { if(str[i]==unsigned(-4)) k--; if(str[i]==unsigned(-3)) k++; } str[i-1]=0; i--; ww = Puts(b1, x, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE } else if(s=='\n') // newline { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff, st); Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2)/2, yy-660*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 MGL_CLEAR_STYLE } else if(s==unsigned(-9)) // underset or sub { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st); Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2)/2, yy-175*ff/fact[a], ff/3, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE } else if(s==unsigned(-8)) // overset or sup { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st); Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2)/2, yy+400*ff/fact[a], ff/3, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h2,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE } /* else if(s==unsigned(-12)) // sub // NOTE: unused because is the same as \underset now { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st); Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol); Puts(b2, x+(ww-w2)/2, yy-250*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol); if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE }*/ /* else if(s==unsigned(-13)) // sup // NOTE: unused because is the same as \overset now { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st); Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol); Puts(b2, x+(ww-w2)/2, yy+450*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol); if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE }*/ else if(s==unsigned(-11)) // stackl { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st); Puts(b1, x, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE } else if(s==unsigned(-10)) // stacr { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st); Puts(b1, x+(ww-w1), yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2), yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE } else if(s==unsigned(-7)) // stack { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st); Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2)/2, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); MGL_CLEAR_STYLE } else if(s==unsigned(-6)) // frac { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st); Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2)/2, yy-60*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now { draw_ouline(st,x,y,f,fact[a],ww,ccol); gr->Glyph(x,y+150*f/fact[a], ww*fact[a], (st&MGL_FONT_WIRE)?12:8, 0, ccol); } MGL_CLEAR_STYLE } else if(s==unsigned(-15)) // dfrac { ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff, st); Puts(b1, x+(ww-w1)/2, yy+315*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 Puts(b2, x+(ww-w2)/2, yy-405*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol, h1,h2); MGL_USE_H12 if(gr && !(style&0x10)) // add under-/over- line now { draw_ouline(st,x,y,f,fact[a],ww,ccol); gr->Glyph(x,y+150*f/fact[a], ww*fact[a], (st&MGL_FONT_WIRE)?12:8, 0, ccol); } MGL_CLEAR_STYLE } else if(s==unsigned(-4)) MGL_CLEAR_STYLE // should be never here but if I miss sth ... else if(s==unsigned(-14)) // script symbols { long k=1; if(str[i+1]==unsigned(-3)) for(long j=i+2;k>0 && str[j];j++) { if(str[j]==unsigned(-3)) k++; if(str[j]==unsigned(-4)) k--; if(iswlower(str[j])) str[j] = MGL_FONT_UPPER|MGL_FONT_LOWER|towupper(str[j]); } } else if(s==unsigned(-5)) // large symbol ff *= 1.5; else if(s==unsigned(-1)) // set normal font st = style & MGL_FONT_ROMAN; else if((s&MGL_COLOR_MASK)==MGL_COLOR_MASK) // color specification ccol = -float(s & 0xff); // TODO inline colors -- make textures else { unsigned ss = s&MGL_FONT_MASK; if(ss) // draw symbol (glyph) { long j = Internal('!'); float dx=0; if(ss>' ') { j = Internal(ss); if(j==-1) continue; if(s & MGL_FONT_ZEROW) { long j=1; yy += 100*ff/fact[a]; while(str[i+j]>=unsigned(-15)) j++; unsigned sn = str[i+j]; if(sn' ') // specially center { long jj = Internal(sn&MGL_FONT_MASK); dx = jj<0?0:0.75*ff*(GetWidth(a,jj)-GetWidth(a,j))/fact[a]; if(dx<0) dx=0; } } h1 = yy+ff*glyphs[j].y1[a]/fact[a]; h2 = yy+ff*glyphs[j].y2[a]/fact[a]; MGL_USE_H12 if(gr && !(style&0x10)) { if(st & MGL_FONT_WIRE) gr->Glyph(x+dx,yy,ff,a+4,j,ccol); else gr->Glyph(x+dx,yy,ff,a,j,ccol); } } ww = j>=0?ff*GetWidth(a,j)/fact[a]:0; if(gr && !(style&0x10)) // add under-/over- line now draw_ouline(st,x,y,f,fact[a],ww,ccol); if(s & MGL_FONT_ZEROW) ww = 0; MGL_CLEAR_STYLE } // apply new styles if(s/MGL_FONT_BOLD) st = st | (s & MGL_FONT_STYLE); a = (st/MGL_FONT_BOLD)&3; ss = (s/MGL_FONT_UPPER)%4; if(ss) { if(ss==1) { ff *=0.6; yy += 250*ff/fact[a]; } // = 500*0.4 else if(ss==2) { ff *=0.6; yy -= 130*ff/fact[a]; } // = -500*0.16 else if(ss==3) { ff *=0.6; yy += 60*ff/fact[a]; } // = 500*0.12 } } x += ww; w += ww; } delete []str; return w; } //----------------------------------------------------------------------------- // copy normal style as default for other styles void mglFont::main_copy() { #pragma omp parallel for for(long i=0;i &buf, std::vector &extra) { gzFile fp; char str[256]; int n, tmpw, tmpnl, tmpnt, retVal; unsigned ss, tmpi, tmppl, tmppt; fp = gzopen(fname,"r"); if(!fp) return false; // false if no file // first string is comment (not used), second string have information if(!gzgets(fp,str,256) || strncmp(str,"# font",6) || !gzgets(fp,str,256)) { gzclose(fp); return false; } retVal = sscanf(str, "%d%f%u", &n, fact+s, &ss); //Check sscanf read all data (3 items) if(retVal != 3) { gzclose(fp); return false; } for(int i=0;i=0) // known symbol { mglGlyphDescr &g = glyphs[j]; g.width[s] = tmpw; g.ln[s] = -1-tmppl; g.tr[s] = -1-tmppt; g.numl[s] = tmpnl; g.numt[s] = tmpnt; } else { mglGlyphDescr g; g.id = tmpi; g.width[0] = g.width[1] = g.width[2] = g.width[3] = tmpw; g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = tmpnl; g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = -1-tmppl; g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = tmpnt; g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = -1-tmppt; #pragma omp critical extra.push_back(g); } } for(unsigned i=0;i &buf) { gzFile fp; int tmpi, tmpw, tmpnl, tmpnt; unsigned s, tmppl, tmppt,numg; char str[256]; fp = gzopen(fname,"r"); if(!fp) return false; // this font must be in any case // first string is comment (not used), second string have information if(!gzgets(fp,str,256) || strncmp(str,"# font",6) || !gzgets(fp,str,256)) { gzclose(fp); return false; } sscanf(str, "%u%f%u", &numg, fact, &s); fact[1] = fact[2] = fact[3] = fact[0]; // copy default factor for other font styles; // now allocate memory for all fonts mem_alloc(numg); // and load symbols itself for(size_t i=0;iy2) y2=y; } glyphs[i].y1[s] = y1; glyphs[i].y2[s] = y2; } } } //----------------------------------------------------------------------------- size_t mglFont::SaveBin(const char *fname) { FILE *fp = fopen(fname,"wb"); if(!fp) return 0; size_t sum=0; fwrite(&numb,sizeof(size_t),1,fp); sum += sizeof(size_t); fwrite(fact,sizeof(float),4,fp); sum += sizeof(float)*4; fwrite(Buf,sizeof(short),numb,fp); sum += sizeof(short)*numb; size_t len = glyphs.size(); fwrite(&len,sizeof(size_t),1,fp); sum += sizeof(long); fwrite(&(glyphs[0]),sizeof(mglGlyphDescr),len,fp); sum += sizeof(mglGlyphDescr)*len; fclose(fp); return sum; } //----------------------------------------------------------------------------- bool mglFont::LoadBin(const char *base, const char *path) { Clear(); // first clear old if(!path) path = MGL_FONT_PATH; char str[256], sep='/'; if(base && strstr(base,".vfmb")) snprintf(str,256,"%s%c%s",path,sep,base); else snprintf(str,256,"%s%c%s.vfmb",path,sep,base?base:""); str[255]=0; FILE *fp = fopen(str,"rb"); if(!fp) return false; size_t s, len; bool res = true; s = fread(&numb,sizeof(size_t),1,fp); if(s<1) res = false; s = fread(fact,sizeof(float),4,fp); if(s<4) res = false; Buf = new short[numb]; s = fread(Buf,sizeof(short),numb,fp); if(s=0 && buf[i]!=sep;i--); path = buf; buf[i]=0; base = buf+i+1; } if(LoadBin(base,path)) { delete []buf; return true; } } Clear(); // first clear old std::string sbase; if(base && strstr(base,".vfm")) // bypass user-specified extension in base name { size_t len = strlen(base); sbase = std::string(base).substr(0,len-4); base = sbase.c_str(); } snprintf(str,256,"%s%c%s.vfm",path,sep,base?base:""); str[255]=0; std::vector norm, bold, ital, both; if(!(base && *base) || !read_main(str,norm)) { read_def(); setlocale(LC_NUMERIC,loc.c_str()); if(buf) delete []buf; FillY12(); return true; } fact[1] = fact[2] = fact[3] = fact[0]; std::vector ex_b,ex_i,ex_bi; #pragma omp parallel sections { //================== bold =========================================== #pragma omp section { char str[256]; snprintf(str,256,"%s%c%s_b.vfm",path,sep,base); // this file may absent str[255]=0; read_data(str, 1, bold, ex_b); } //================== italic ========================================= #pragma omp section { char str[256]; snprintf(str,256,"%s%c%s_i.vfm",path,sep,base); str[255]=0; read_data(str, 2, ital, ex_i); } //================== bold-italic ==================================== #pragma omp section { char str[256]; snprintf(str,256,"%s%c%s_bi.vfm",path,sep,base); str[255]=0; read_data(str, 3, both, ex_bi); } } // now collect data numb = norm.size()+bold.size()+ital.size()+both.size(); Buf = new short[numb]; memcpy(Buf,&norm[0],norm.size()*sizeof(short)); long cur = norm.size(), len = long(bold.size()); if(bold.size()>0) memcpy(Buf+cur,&bold[0],bold.size()*sizeof(short)); #pragma omp parallel for for(long i=0;i0) memcpy(Buf+cur,&ital[0],ital.size()*sizeof(short)); #pragma omp parallel for for(long i=0;i0) memcpy(Buf+cur,&both[0],both.size()*sizeof(short)); #pragma omp parallel for for(long i=0;i=0) // known symbol { mglGlyphDescr &g = ex_b[j], &f = ex_i[i]; g.width[2] = f.width[2]; g.ln[2] = f.ln[2]; g.tr[2] = f.tr[2]; g.numl[2] = f.numl[2]; g.numt[2] = f.numt[2]; } else ex_b.push_back(ex_i[i]); } std::sort(ex_b.begin(),ex_b.end()); } if(ex_b.size()==0) ex_b = ex_bi; else { for(size_t i=0;i=0) // known symbol { mglGlyphDescr &g = ex_b[j], &f = ex_bi[i]; g.width[2] = f.width[3]; g.ln[2] = f.ln[3]; g.tr[2] = f.tr[3]; g.numl[2] = f.numl[3]; g.numt[2] = f.numt[3]; } else ex_b.push_back(ex_bi[i]); } std::sort(ex_b.begin(),ex_b.end()); } if(ex_b.size()>0) { glyphs.reserve(ex_b.size()); // preallocate memory glyphs.insert(glyphs.end(), ex_b.begin(), ex_b.end()); std::sort(glyphs.begin(),glyphs.end()); } // Finally normalize all factors fact[0] *= mgl_fgen; fact[1] *= mgl_fgen; fact[2] *= mgl_fgen; fact[3] *= mgl_fgen; FillY12(); setlocale(LC_NUMERIC,loc.c_str()); if(buf) delete []buf; return true; } //----------------------------------------------------------------------------- #if MGL_HAVE_PTHREAD pthread_mutex_t mutexRnd; #endif //----------------------------------------------------------------------------- float mgl_cos[360]; void static mgl_init() { mgl_textdomain(NULL,""); #if MGL_HAVE_PTHREAD pthread_mutex_init(&mutexRnd,0); #endif #ifndef WIN32 // win32 don't initialized threads before main() #pragma omp parallel for #endif for(long i=0;i<360;i++) mgl_cos[i] = cos(i*M_PI/180.); } //----------------------------------------------------------------------------- mglFont::mglFont(const char *name, const char *path) { parse = true; gr=0; Buf=0; // if(this==&mglDefFont) Load(name, path); else Copy(&mglDefFont); if(name && *name) Load(name, path); else if(this!=&mglDefFont) Copy(&mglDefFont); else { mgl_init(); // NOTE: this call init function for the library. Load(MGL_DEF_FONT_NAME,0); } } mglFont::~mglFont() { if(Buf) delete []Buf; } void mglFont::Restore() { Copy(&mglDefFont); } //----------------------------------------------------------------------------- void mglFont::Clear() { //#pragma omp critical(font) { if(Buf) delete []Buf; Buf=0; glyphs.clear(); } } //----------------------------------------------------------------------------- void mglFont::Copy(mglFont *f) { if(!f || f==this) return; #pragma omp critical(font) { if(Buf) delete []Buf; Buf=0; } // copy scale factors fact[0]=f->fact[0]; fact[1]=f->fact[1]; fact[2]=f->fact[2]; fact[3]=f->fact[3]; // copy symbols descriptions numb = f->numb; Buf = new short[numb]; memcpy(Buf, f->Buf, numb*sizeof(short)); // copy symbol parameters glyphs.resize(f->glyphs.size()); memcpy(&glyphs[0],&(f->glyphs)[0],glyphs.size()*sizeof(mglGlyphDescr)); } //----------------------------------------------------------------------------- long MGL_EXPORT mgl_check_tex_table() { size_t i=0; while(mgl_tex_symb[i].tex[0]) i++; long res = 0; if(mgl_tex_num!=i) { printf("real=%zu, set=%zu\n",i,mgl_tex_num); res = -1; } for(i=0;mgl_tex_symb[i].tex[0];i++) { mglTeXsymb tst, *rts; tst.tex = mgl_tex_symb[i].tex; rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, mgl_tex_num, sizeof(mglTeXsymb), mgl_tex_symb_cmp); if(!rts) { printf(_("Bad '%ls' at %zu\n"),mgl_tex_symb[i].tex,i); res = 1+i; } } return res; } //--------------------------------------------------------------------------- bool static test_transl(const char *p) { if(!p) return false; #if MGL_USE_GETTEXT std::string f = std::string(p) + "/ru/LC_MESSAGES/mathgl.mo"; FILE *fp = fopen(f.c_str(),"r"); if(fp) { bindtextdomain("mathgl", p); textdomain("mathgl"); fclose(fp); return true; } #endif return false; } void MGL_EXPORT mgl_textdomain(const char *argv0, const char *loc) { static const char *argv=NULL; if(!argv0) argv0=argv; else argv=argv0; setlocale(LC_ALL, loc); setlocale(LC_NUMERIC, "C"); #if MGL_USE_GETTEXT if(!test_transl(MGL_INSTALL_DIR"/share/locale/")) if(!test_transl("/usr/share/locale/")) if(!test_transl("/usr/local/share/locale/")) { char* cwd = getcwd(NULL,0); if(!test_transl(cwd)) { free(cwd); const char *f = argv0?strrchr(argv0,'/'):NULL; #ifdef WIN32 if(!f) f = argv0?strrchr(argv0,'\\'):NULL; #endif if(f) { std::string p(argv0,f-argv0); if(!test_transl(p.c_str())) return; } else return; } else if(cwd) free(cwd); } #endif } void MGL_EXPORT mgl_textdomain_(const char *locale, int l) { char *s=new char[l+1]; memcpy(s,locale,l); s[l]=0; mgl_textdomain(NULL,s); delete []s; } //--------------------------------------------------------------------------- mathgl-2.4.4/src/CMakeLists.txt0000644000175000017500000000504013513030041016473 0ustar alastairalastairset(mgl_src addon.cpp axis.cpp base_cf.cpp base.cpp canvas_cf.cpp canvas.cpp cont.cpp crust.cpp complex.cpp complex_ex.cpp complex_io.cpp fft.cpp data_gr.cpp data.cpp data_io.cpp data_ex.cpp data_png.cpp export_2d.cpp export_3d.cpp eval.cpp evalp.cpp export.cpp fit.cpp font.cpp obj.cpp other.cpp parser.cpp pde.cpp pixel.cpp pixel_gen.cpp plot.cpp prim.cpp surf.cpp vect.cpp volume.cpp evalc.cpp s_hull/s_hull_pro.cpp window.cpp fractal.cpp exec_dat.cpp exec_gr.cpp exec_set.cpp exec_prm.cpp c2mdual.c ) set(mgl_hdr ../include/mgl2/base_cf.h ../include/mgl2/fit.h ../include/mgl2/plot.h ../include/mgl2/base.h ../include/mgl2/prim.h ../include/mgl2/canvas_cf.h ../include/mgl2/font.h ../include/mgl2/canvas.h ../include/mgl2/surf.h ../include/mgl2/mgl_cf.h ../include/mgl2/type.h ${MathGL2_BINARY_DIR}/include/mgl2/config.h ${MathGL2_BINARY_DIR}/include/mgl2/dllexport.h cont.hpp ../include/mgl2/cont.h ../include/mgl2/mgl.h ../include/mgl2/vect.h ../include/mgl2/data.h ../include/mgl2/volume.h ../include/mgl2/data_cf.h ../include/mgl2/define.h ../include/mgl2/other.h ../include/mgl2/eval.h ../include/mgl2/parser.h ../include/mgl2/addon.h ../include/mgl2/evalc.h s_hull/s_hull_pro.h ../include/mgl2/wnd.h ../include/mgl2/canvas_wnd.h ../include/mgl2/thread.h ../include/mgl2/abstract.h ../include/mgl2/pde.h # tex_table.cc def_font.cc ) if(MSVC) add_definitions(-DMGL_LIB_MSVC) endif(MSVC) if(MGL_HAVE_GSL2) add_definitions(-DMGL_HAVE_GSL2) endif(MGL_HAVE_GSL2) if(MGL_HAVE_PNG) set(prc_src prc/PRCbitStream.cc prc/PRCdouble.cc prc/oPRCFile.cc prc/writePRC.cc prc.cpp ) set(prc_hdr prc/PRC.h prc/PRCbitStream.h prc/PRCdouble.h prc/oPRCFile.h prc/writePRC.h ) set(mgl_src ${mgl_src} ${prc_src} ) set(mgl_hdr ${mgl_hdr} ${prc_hdr} ) include_directories(prc) endif(MGL_HAVE_PNG) if(MGL_HAVE_OPENGL) set(mgl_src ${mgl_src} opengl.cpp ) set(mgl_hdr ${mgl_hdr} ../include/mgl2/opengl.h ) endif(MGL_HAVE_OPENGL) include(GenerateExportHeader) mgl_add_lib(mgl ${mgl_src} ${mgl_hdr}) generate_export_header(mgl EXPORT_FILE_NAME ../include/mgl2/dllexport.h) target_link_libraries(mgl ${MGL_DEP_LIBS}) target_link_libraries(mgl-static ${MGL_DEP_LIBS}) mgl_po_src(${mgl_src} ${mgl_hdr}) if(MGL_HAVE_MPI) mgl_add_lib(mpi mpi.cpp ../include/mgl2/mpi.h) target_link_libraries(mgl-mpi ${MPI_LIBRARIES} ) target_link_libraries(mgl-mpi-static ${MPI_LIBRARIES} ) target_include_directories(mgl-mpi SYSTEM PUBLIC ${MPI_CXX_INCLUDE_PATH}) endif(MGL_HAVE_MPI) install(FILES ${MathGL2_BINARY_DIR}/include/mgl2/dllexport.h DESTINATION ${MGL_INCLUDE_PATH}) mathgl-2.4.4/src/s_hull/0000755000175000017500000000000013513030041015222 5ustar alastairalastairmathgl-2.4.4/src/s_hull/s_hull_pro.h0000644000175000017500000000764213513030041017552 0ustar alastairalastair#ifndef _structures_h #define _structures_h // for FILE #include #include #include #include #include /* for use in s_hull_pro.cpp S-hull-pro, Copyright (c) 2012 Dr David SInclair Cambridge, UK email david@s-hull.org */ // Global replace int->long by A.Balakin 21 April 2014 -- 64bit version can handle huge data arrays struct Triad { long a,b, c; long ab, bc, ac; // adjacent edges index to neighbouring triangle. double ro, R,C; //std::set idx; Triad() {a=b=c=0; ab=bc=ac=-1; ro=-1; R=C=0;} // added by A.Balakin 21 April 2014 -- uninitialised variable Triad(long x, long y) : a(x), b(y),c(0), ab(-1), bc(-1), ac(-1), ro(-1), R(0), C(0) {} Triad(long x, long y, long z) : a(x), b(y), c(z), ab(-1), bc(-1), ac(-1), ro(-1), R(0), C(0) {} Triad(const Triad &p) : a(p.a), b(p.b), c(p.c), ab(p.ab), bc(p.bc), ac(p.ac), ro(p.ro), R(p.R), C(p.C) {} Triad &operator=(const Triad &p) { a = p.a; b = p.b; c = p.c; ab = p.ab; bc = p.bc; ac = p.ac; ro = p.ro; R = p.R; C = p.C; return *this; } }; /* point structure for s_hull only. has to keep track of triangle ids as hull evolves. */ struct Shx { long id, trid; double r,c, tr,tc, ro; Shx() {r=c=tr=tc=ro=0; id=-1; trid=0;} // added by A.Balakin 21 April 2014 -- uninitialised variable Shx(double a, double b) : r(a), c(b) { trid=0; ro=tr=tc=0; id=-1; } // added by A.Balakin 21 April 2014 -- uninitialised variable Shx(double a, double b, double x) : r(a), c(b), ro(x) { trid=0; tr=tc=0; id=-1; } // added by A.Balakin 21 April 2014 -- uninitialised variable Shx(const Shx &p) : id(p.id), trid(p.trid), r(p.r), c(p.c), tr(p.tr), tc(p.tc), ro(p.ro) {} Shx &operator=(const Shx &p) { id = p.id; trid = p.trid; r = p.r; c = p.c; tr = p.tr; tc = p.tc; ro = p.ro; return *this; } }; // sort into descending order (for use in corner responce ranking). inline bool operator<(const Shx &a, const Shx &b) { if( a.ro == b.ro) { if( a.r == b.r ) { return a.c < b.c; } return a.r < b.r; } return a.ro < b.ro; }; struct Dupex { long id; double r,c; Dupex() { r=c=0; id=-1; } // added by A.Balakin 21 April 2014 -- uninitialised variable Dupex(double a, double b) : id(-1), r(a), c(b) {} Dupex(double a, double b, long x) : id(x), r(a), c(b) {} Dupex(const Dupex &p) : id(p.id), r(p.r), c(p.c) {} Dupex &operator=(const Dupex &p) { id = p.id; r = p.r; c = p.c; return *this; } }; // sort into descending order (for use in corner responce ranking). inline bool operator<(const Dupex &a, const Dupex &b) { if( a.r == b.r) return a.c < b.c; return a.r < b.r; }; // from s_hull.C long s_hull_pro( std::vector &pts, std::vector &triads); void circle_cent2(double r1,double c1, double r2,double c2, double r3,double c3,double &r,double &c, double &ro2); void circle_cent4(double r1,double c1, double r2,double c2, double r3,double c3,double &r,double &c, double &ro2); void write_Shx(std::vector &pts, char * fname); void write_Triads(std::vector &ts, char * fname); long Cline_Renka_test(double &Ax, double &Ay, double &Bx, double &By, double &Cx, double &Cy, double &Dx, double &Dy); long T_flip_pro( std::vector &pts, std::vector &triads, std::vector &slump, long numt, long start, std::set &ids); long T_flip_pro_idx( std::vector &pts, std::vector &triads, std::vector &slump, std::set &ids); long read_Shx(std::vector &pts, char * fname); long de_duplicate( std::vector &pts, std::vector &outx, Dupex epsilon = Dupex(std::numeric_limits::epsilon(),std::numeric_limits::epsilon()) ); long de_duplicateX( std::vector &pts, std::vector &outx,std::vector &pts2 ); long test_center(Shx &pt0, Shx &pt1,Shx &pt2); long T_flip_edge( std::vector &pts, std::vector &triads, std::vector &slump, long numt, long start, std::set &ids); #endif mathgl-2.4.4/src/s_hull/COPYING.txt0000644000175000017500000000431413513030041017075 0ustar alastairalastairS-hull, Copyright (c) 2010 Dr David SInclair Cambridge, UK email david@s-hull.org The software includes the S-hull programs. S-hull is copyrighted as above. S-hull is free software and may be obtained from www.s-hull.org. It may be freely copied, modified, and redistributed under the following conditions: S-hull is free software and may be obtained from www.s-hull.org. It may be freely copied, modified, and redistributed under the following conditions which might loosely be termed a contribtors beerware license: 1. All copyright notices must remain intact in all files. 2. A copy of this text file must be distributed along with any copies of S-hull that you redistribute; this includes copies that you have modified, or copies of programs or other software products that include S-hull where distributed as source. 3. If you modify S-hull, you must include a notice giving the name of the person performing the modification, the date of modification, and the reason for such modification. 4. If you are distributing a binary or compiled version of s-hull it is not necessary to include any acknowledgement or reference to s-hull. 5. There is no warranty or other guarantee of fitness for S-hull, it is provided solely "as is". Bug reports or fixes may be sent to bugs@s-hull.org; the authors may or may not act on them as they desire. 6. By copying or compliing the code for S-hull you explicitly indemnify the copyright holder against any liability he may incur as a result of you copying the code. 7. If you meet any of the contributors to the code you used from s-hull.org in a pub or a bar, and you think the source code they contributed to is worth it, you can buy them a beer. If your principles run against beer a bacon-double-cheeseburger would do just as nicely or you could email david@s-hull.org and arrange to make a donation of 10 of your local currancy units to support s-hull.org. ------------------- This is permission to use s-hull-pro mathgl as long as the routines retain my copyright notice. I an happy for it to be included in an LGPL product and I am happy for the source to be bundled with mathgl under whatever license you use for that. mathgl-2.4.4/src/s_hull/s_hull_pro.cpp0000644000175000017500000011277013513030041020104 0ustar alastairalastair#include //#include //#include #include #include #include #include #include #include #include #include "s_hull_pro.h" using namespace std; /* copyright 2012 Dr David Sinclair david@s-hull.org program to compute Delaunay triangulation of a set of points. this code may not be published or distributed without the concent of the copyright holder. */ // Global replace int->long by A.Balakin 21 April 2014 -- 64bit version can handle huge data arrays void circle_cent2(double r1,double c1, double r2,double c2, double r3,double c3, double &r,double &c, double &ro2) { /* * function to return the center of a circle and its radius * degenerate case should never be passed to this routine!!!!!!!!!!!!! * but will return r0 = -1 if it is. */ double a1 = (r1+r2)/2.0; double a2 = (c1+c2)/2.0; double b1 = (r3+r2)/2.0; double b2 = (c3+c2)/2.0; double e2 = r1-r2; double e1 = -c1+c2; double q2 = r3-r2; double q1 = -c3+c2; r=0; c=0; ro2=-1; if( e1*-q2 + e2*q1 == 0 ) return; double beta = (-e2*(b1-a1) + e1*(b2-a2))/( e2*q1-e1*q2); r = b1 + q1*beta; c = b2 + q2*beta; ro2 = (r1-r)*(r1-r) + (c1-c)*(c1-c); return; } /* read an ascii file of (r,c) point pairs. the first line of the points file should contain "NUMP 2 points" if it does not have the word points in it the first line is interpretted as a point pair. */ long read_Shx(std::vector &pts, char * fname) { char s0[513]; long nump =0; double p1,p2; Shx pt; std::string line; std::string points_str("points"); std::ifstream myfile; myfile.open(fname); if (myfile.is_open()) { getline (myfile,line); //long numc = line.length(); // check string for the string "points" long n = (long) line.find( points_str); if( n > 0) { while ( myfile.good() ) { getline (myfile,line); if( line.length() <= 512) { copy( line.begin(), line.end(), s0); s0[line.length()] = 0; long v = sscanf( s0, "%lg %lg", &p1,&p2); if( v>0 ) { pt.id = nump; nump++; pt.r = p1; pt.c = p2; pts.push_back(pt); } } } } else // assume all number pairs on a line are points { if( line.length() <= 512) { copy( line.begin(), line.end(), s0); s0[line.length()] = 0; long v = sscanf( s0, "%lg %lg", &p1,&p2); if( v>0 ) { pt.id = nump; nump++; pt.r = p1; pt.c = p2; pts.push_back(pt); } } while ( myfile.good() ) { getline (myfile,line); if( line.length() <= 512) { copy( line.begin(), line.end(), s0); s0[line.length()] = 0; long v = sscanf( s0, "%lg %lg", &p1,&p2); if( v>0 ) { pt.id = nump; nump++; pt.r = p1; pt.c = p2; pts.push_back(pt); } } } } myfile.close(); } nump = (long) pts.size(); return(nump); } /* write out a set of points to disk */ void write_Shx(std::vector &pts, char * fname) { std::ofstream out(fname, ios::out); long nr = (long) pts.size(); out << nr << " 2 points" << endl; for (long r = 0; r < nr; r++) { out << pts[r].r << ' ' << pts[r].c << endl; } out.close(); return; } /* write out triangle ids to be compatible with matlab/octave array numbering. */ void write_Triads(std::vector &ts, char * fname) { std::ofstream out(fname, ios::out); long nr = (long) ts.size(); out << nr << " 6 point-ids (1,2,3) adjacent triangle-ids ( limbs ab ac bc )" << endl; for (long r = 0; r < nr; r++) { out << ts[r].a+1 << ' ' << ts[r].b+1 <<' ' << ts[r].c+1 <<' ' << ts[r].ab+1 <<' ' << ts[r].ac+1 <<' ' << ts[r].bc+1 << endl; //" " << ts[r].ro << endl; } out.close(); return; } /* version in which the ids of the triangles associated with the sides of the hull are tracked. */ long s_hull_pro( std::vector &pts, std::vector &triads) { long nump = (long) pts.size(); if( nump < 3 ) { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "less than 3 points, aborting " << endl; return(-1); } double r = pts[0].r; double c = pts[0].c; for( long k=0; k 0 ) { mid = k; romin2 = ro2; R = r; C = c; } else if( romin2 *4 < pts[k].ro ) k=nump; k++; } if( mid < 0 ) { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "linear structure, aborting " << endl; return(-2); } Shx pt0 = pts[0]; Shx pt1 = pts[1]; Shx pt2 = pts[mid]; pts.erase(pts.begin() + mid); // necessary for round off reasons:(((((( pts.erase(pts.begin() ); pts.erase(pts.begin() ); for( long k=0; k slump; slump.resize(nump); for( long k=0; k hull; r = (pts[0].r + pts[1].r + pts[2].r )/(double) 3.0; c = (pts[0].c + pts[1].c + pts[2].c )/(double) 3.0; double dr0 = pts[0].r - r, dc0 = pts[0].c - c; double tr01 = pts[1].r - pts[0].r, tc01 = pts[1].c - pts[0].c; double df = -tr01* dc0 + tc01*dr0; if( df < 0 ) // [ 0 1 2 ] { pt0.tr = pt1.r-pt0.r; pt0.tc = pt1.c-pt0.c; pt0.trid = 0; hull.push_back( pt0 ); pt1.tr = pt2.r-pt1.r; pt1.tc = pt2.c-pt1.c; pt1.trid = 0; hull.push_back( pt1 ); pt2.tr = pt0.r-pt2.r; pt2.tc = pt0.c-pt2.c; pt2.trid = 0; hull.push_back( pt2 ); Triad tri(pt0.id,pt1.id,pt2.id); tri.ro = romin2; tri.R = R; tri.C = C; triads.push_back(tri); } else // [ 0 2 1 ] as anti-clockwise turning is the work of the devil.... { pt0.tr = pt2.r-pt0.r; pt0.tc = pt2.c-pt0.c; pt0.trid = 0; hull.push_back( pt0 ); pt2.tr = pt1.r-pt2.r; pt2.tc = pt1.c-pt2.c; pt2.trid = 0; hull.push_back( pt2 ); pt1.tr = pt0.r-pt1.r; pt1.tc = pt0.c-pt1.c; pt1.trid = 0; hull.push_back( pt1 ); Triad tri(pt0.id,pt2.id,pt1.id); tri.ro = romin2; tri.R = R; tri.C = C; triads.push_back(tri); } // add new points into hull (removing obscured ones from the chain) // and creating triangles.... // that will need to be flipped. double dr, dc, rx,cx; Shx ptx; long numt=0; // added by A.Balakin 21 April 2014 -- uninitialised variable for( long k=3; k pidx, tridx; long hidx; // new hull point location within hull..... double df = -dc* hull[0].tr + dr*hull[0].tc; // visibility test vector. if( df < 0 ) // starting with a visible hull facet !!! { // long e1 = 1, e2 = numh; // commented by A.Balakin 21 April 2014 -- unused variable hidx = 0; // check to see if segment numh is also visible df = -dc* hull[numh-1].tr + dr*hull[numh-1].tc; //cerr << df << ' ' ; if( df < 0 ) // visible. { pidx.push_back(hull[numh-1].id); tridx.push_back(hull[numh-1].trid); for( long h=0; h0; h--) { // if segment h is visible delete h + 1 dr = rx- hull[h].r; dc = cx- hull[h].c; df = -dc* hull[h].tr + dr*hull[h].tc; if( df < 0 ) // h is visible { pidx.insert(pidx.begin(), hull[h].id); tridx.insert(tridx.begin(), hull[h].trid); hull.erase(hull.begin() + h+1); // erase end of chain } else { h = (long) hull.size()-1; hull[h].tr = -hull[h].r + ptx.r; // points at start of chain. hull[h].tc = -hull[h].c + ptx.c; break; } } df = 9; } else { // cerr << df << ' ' << endl; hidx = 1; // keep pt hull[0] tridx.push_back(hull[0].trid); pidx.push_back(hull[0].id); for( long h=1; h 0 ) // first invisible segment. { e2 = h; break; } } } if (e1 < 0) { // Cannot find visible point - it might be caused by numerical issues on some kind of datasets return (-5); } // triangle pidx starts at e1 and ends at e2 (inclusive). if( e2 < numh ) { for( long e=e1; e<=e2; e++) { pidx.push_back(hull[e].id); tridx.push_back(hull[e].trid); } } else { for( long e=e1; e 0 ) hull[hidx-1].trid = numt; else { numh = (long) hull.size(); hull[numh-1].trid = numt; } triads.push_back( trx ); numt++; } else { trx.ab = -1; for(long p=0; p 0 ) trx.ab = numt-1; trx.ac = numt+1; // index back into the triads. Triad &txx = triads[tridx[p]]; if( ( trx.b == txx.a && trx.c == txx.b) |( trx.b == txx.b && trx.c == txx.a)) { txx.ab = numt; } else if( ( trx.b == txx.a && trx.c == txx.c) |( trx.b == txx.c && trx.c == txx.a)) { txx.ac = numt; } else if( ( trx.b == txx.b && trx.c == txx.c) |( trx.b == txx.c && trx.c == txx.b)) { txx.bc = numt; } triads.push_back( trx ); numt++; } triads[numt-1].ac=-1; hull[hidx].trid = numt-1; if( hidx > 0 ) hull[hidx-1].trid = T0; else { numh = (long) hull.size(); hull[numh-1].trid = T0; } } } // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "of triangles " << triads.size() << " to be flipped. "<< endl; // write_Triads(triads, "tris0.mat"); std::set ids; long tf = T_flip_pro( pts, triads, slump, numt, 0, ids); if( tf < 0 ) { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "cannot triangualte this set " << endl; return(-3); } // write_Triads(triads, "tris1.mat"); long nits = (long) ids.size(), nit=1; while( nits > 0 && nit < 50) { tf = T_flip_pro_idx( pts, triads, slump, ids); nits = (long) ids.size(); nit ++; if( tf < 0 ) { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "cannot triangualte this set " << endl; return(-4); } } ids.clear(); nits = T_flip_edge( pts, triads, slump, numt, 0, ids); nit=0; while( nits > 0 && nit < 100) { tf = T_flip_pro_idx( pts, triads, slump, ids); nits = (long) ids.size(); // cerr << "flipping cycle " << nit << " active triangles " << nits << endl; nit ++; if( tf < 0 ) { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "cannot triangualte this set " << endl; return(-4); } } return(1); } void circle_cent4(double r1,double c1, double r2,double c2, double r3,double c3, double &r,double &c, double &ro2) { /* * function to return the center of a circle and its radius * degenerate case should never be passed to this routine!!!!!!!!!!!!! * but will return r0 = -1 if it is. */ double rd, cd; double v1 = 2*(r2-r1), v2 = 2*(c2-c1), v3 = r2*r2 - r1*r1 + c2*c2 - c1*c1; double v4 = 2*(r3-r1), v5 = 2*(c3-c1), v6 = r3*r3 - r1*r1 + c3*c3 - c1*c1, v7 = v2*v4 - v1*v5; if( v7 == 0 ) { r=0; c=0; ro2 = -1; return; } cd = (v4*v3 - v1*v6)/v7; if( v1 != 0 ) rd = (v3 - c*v2)/v1; else rd = (v6 - c*v5)/v4; ro2 = (double) ( (rd-r1)*(rd-r1) + (cd-c1)*(cd-c1) ); r = (double) rd; c = (double) cd; return; } namespace { /** * Rounds the value given to the nearest multiple of the epsilon given */ double coarsen(const double value, const double epsilon) { const double minimal_epsilon = std::numeric_limits::epsilon() * value; return (epsilon < minimal_epsilon) ? value : floor(value / epsilon + 0.5) * epsilon; } } /* test a set of points for duplicates. erase duplicate points, do not change point ids. */ long de_duplicate( std::vector &pts, std::vector &outx, const Dupex epsilon ) { long nump = (long) pts.size(); std::vector dpx; Dupex d; for( long k=0; k=0; k--) { pts.erase(pts.begin()+outx[k]); } return(nx); } /* flip pairs of triangles that are not valid delaunay triangles the Cline-Renka test is used rather than the less stable circum circle center computation test of s-hull. or the more expensive determinant test. */ long T_flip_pro( std::vector &pts, std::vector &triads, std::vector &slump, long numt, long start, std::set &ids) { double r3,c3; long pa,pb,pc, pd, D, L1, L2, L3, L4, T2; Triad tx, tx2; for( long t=start; t= 0 ) { pa = slump[tri.a]; pb = slump[tri.b]; pc = slump[tri.c]; T2 = tri.bc; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.b == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.b == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.b == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-5); } // Commented by A.Balakin 21 April 2014 -- unused variable // if( pd < 0 || pd > 100) // long dfx = 9; r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3 ); if( XX < 0 ) { L1 = tri.ab; L2 = tri.ac; if( L1 != L3 && L2 != L4 ) // need this check for stability. { tx.a = tri.a; tx.b = tri.b; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.a; tx2.b = tri.c; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids.insert(t); ids.insert(T2); t2 = tx2; tri = tx; flipped = 1; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } if( flipped == 0 && tri.ab >= 0 ) { pc = slump[tri.c]; pb = slump[tri.b]; pa = slump[tri.a]; T2 = tri.ab; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.a == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.a == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.a == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-5); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pc].r, pts[pc].c, pts[pb].r, pts[pb].c, pts[pa].r, pts[pa].c,r3, c3); if( XX < 0) { L1 = tri.ac; L2 = tri.bc; if( L1 != L3 && L2 != L4 ) // need this check for stability. { tx.a = tri.c; tx.b = tri.a; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.c; tx2.b = tri.b; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids.insert(t); ids.insert(T2); t2 = tx2; tri = tx; flipped = 1; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } if( flipped == 0 && tri.ac >= 0 ) { pc = slump[tri.c]; pb = slump[tri.b]; pa = slump[tri.a]; T2 = tri.ac; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.a == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.a == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.a == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-5); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pb].r, pts[pb].c, pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c,r3, c3); if( XX < 0 ) { L1 = tri.ab; // .ac shared limb L2 = tri.bc; if( L1 != L3 && L2 != L4 ) // need this check for stability. { tx.a = tri.b; tx.b = tri.a; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.b; tx2.b = tri.c; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids.insert(t); ids.insert(T2); t2 = tx2; tri = tx; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } } return(1); } /* minimum angle cnatraint for circum circle test. due to Cline & Renka A -- B | / | C -- D */ long Cline_Renka_test(double &Ax, double &Ay, double &Bx, double &By, double &Cx, double &Cy, double &Dx, double &Dy) { double v1x = Bx-Ax, v1y = By-Ay, v2x = Cx-Ax, v2y = Cy-Ay, v3x = Bx-Dx, v3y = By-Dy, v4x = Cx-Dx, v4y = Cy-Dy; double cosA = v1x*v2x + v1y*v2y; double cosD = v3x*v4x + v3y*v4y; if( cosA < 0 && cosD < 0 ) // two obtuse angles return(-1); // double ADX = Ax-Dx, ADy = Ay-Dy; // commented by A.Balakin 21 April 2014 -- unused variable if( cosA > 0 && cosD > 0 ) // two acute angles return(1); double sinA = fabs(v1x*v2y - v1y*v2x); double sinD = fabs(v3x*v4y - v3y*v4x); if( cosA*sinD + sinA*cosD < 0 ) return(-1); return(1); } // same again but with set of triangle ids to be iterated over. long T_flip_pro_idx( std::vector &pts, std::vector &triads, std::vector &slump, std::set &ids) { double r3,c3; long pa,pb,pc, pd, D, L1, L2, L3, L4, T2; Triad tx, tx2; std::set ids2; ids2.clear(); std::set :: const_iterator x=ids.begin(); while(x != ids.end() ) { long t = *x; x++; Triad &tri = triads[t]; // test all 3 neighbours of tri long flipped = 0; if( tri.bc >= 0 ) { pa = slump[tri.a]; pb = slump[tri.b]; pc = slump[tri.c]; T2 = tri.bc; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.b == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.b == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.b == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << " T2: " << T2<< endl; return(-6); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c,r3, c3); if( XX < 0 ) { L1 = tri.ab; L2 = tri.ac; if( L1 != L3 && L2 != L4 ) // need this check for stability. { tx.a = tri.a; tx.b = tri.b; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.a; tx2.b = tri.c; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids2.insert(t); ids2.insert(T2); t2 = tx2; tri = tx; flipped = 1; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } if( flipped == 0 && tri.ab >= 0 ) { pc = slump[tri.c]; pb = slump[tri.b]; pa = slump[tri.a]; T2 = tri.ab; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.a == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.a == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.a == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-6); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pc].r, pts[pc].c, pts[pb].r, pts[pb].c, pts[pa].r, pts[pa].c,r3, c3); if( XX < 0 ) { L1 = tri.ac; L2 = tri.bc; if( L1 != L3 && L2 != L4 ) // need this check for stability. { tx.a = tri.c; tx.b = tri.a; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.c; tx2.b = tri.b; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids2.insert(t); ids2.insert(T2); t2 = tx2; tri = tx; flipped = 1; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } if( flipped == 0 && tri.ac >= 0 ) { pc = slump[tri.c]; pb = slump[tri.b]; pa = slump[tri.a]; T2 = tri.ac; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.a == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.a == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.a == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-6); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, pts[pa].r, pts[pa].c,r3, c3); if( XX < 0 ) { L1 = tri.ab; // .ac shared limb L2 = tri.bc; if( L1 != L3 && L2 != L4 ) // need this check for stability. { tx.a = tri.b; tx.b = tri.a; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.b; tx2.b = tri.c; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids2.insert(t); ids2.insert(T2); t2 = tx2; tri = tx; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } } ids.clear(); ids.insert(ids2.begin(), ids2.end()); return(1); } /* test the seed configuration to see if the center of the circum circle lies inside the seed triangle. if not issue a warning. */ long test_center(Shx &pt0, Shx &pt1,Shx &pt2) { double r01 = pt1.r - pt0.r; double c01 = pt1.c - pt0.c; double r02 = pt2.r - pt0.r; double c02 = pt2.c - pt0.c; double r21 = pt1.r - pt2.r; double c21 = pt1.c - pt2.c; double v = r01*r02 + c01*c02; if( v < 0 ) return(-1); v = r21*r02 + c21*c02; if( v > 0 ) return(-1); v = r01*r21 + c01*c21; if( v < 0 ) return(-1); return(1); } long de_duplicateX( std::vector &pts, std::vector &outx,std::vector &pts2 ) { long nump = (long) pts.size(); std::vector dpx; Dupex d; for( long k=0; k &pts, std::vector &triads, std::vector &slump, long numt, long start, std::set &ids) { double r3,c3; long pa,pb,pc, pd, D, L1, L2, L3, L4, T2; Triad tx, tx2; for( long t=start; t= 0 && (tri.ac < 0 || tri.ab < 0) ) { pa = slump[tri.a]; pb = slump[tri.b]; pc = slump[tri.c]; T2 = tri.bc; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.b == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.b == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.b == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-5); } // Commented by A.Balakin 21 April 2014 -- unused variable // if( pd < 0 || pd > 100) // long dfx = 9; r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3 ); if( XX < 0 ) { L1 = tri.ab; L2 = tri.ac; // if( L1 != L3 && L2 != L4 ){ // need this check for stability. tx.a = tri.a; tx.b = tri.b; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.a; tx2.b = tri.c; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids.insert(t); ids.insert(T2); t2 = tx2; tri = tx; flipped = 1; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } // } } } if( flipped == 0 && tri.ab >= 0 && (tri.ac < 0 || tri.bc < 0)) { pc = slump[tri.c]; pb = slump[tri.b]; pa = slump[tri.a]; T2 = tri.ab; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.a == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.a == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.a == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-5); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pc].r, pts[pc].c, pts[pb].r, pts[pb].c, pts[pa].r, pts[pa].c,r3, c3); if( XX < 0) { L1 = tri.ac; L2 = tri.bc; // if( L1 != L3 && L2 != L4 ){ // need this check for stability. tx.a = tri.c; tx.b = tri.a; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.c; tx2.b = tri.b; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids.insert(t); ids.insert(T2); t2 = tx2; tri = tx; flipped = 1; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } if( flipped == 0 && tri.ac >= 0 && (tri.bc < 0 || tri.ab < 0) ) { pc = slump[tri.c]; pb = slump[tri.b]; pa = slump[tri.a]; T2 = tri.ac; Triad &t2 = triads[T2]; // find relative orientation (shared limb). if( t2.ab == t ) { D = t2.c; pd = slump[t2.c]; if( tri.a == t2.a) { L3 = t2.ac; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ac; } } else if( t2.ac == t ) { D = t2.b; pd = slump[t2.b]; if( tri.a == t2.a) { L3 = t2.ab; L4 = t2.bc; } else { L3 = t2.bc; L4 = t2.ab; } } else if( t2.bc == t ) { D = t2.a; pd = slump[t2.a]; if( tri.a == t2.b) { L3 = t2.ab; L4 = t2.ac; } else { L3 = t2.ac; L4 = t2.ab; } } else { // Commented by A.Balakin 21 April 2014 -- library shouldn't print anything // cerr << "triangle flipping error. " << t << endl; return(-5); } r3 = pts[pd].r; c3 = pts[pd].c; long XX = Cline_Renka_test( pts[pb].r, pts[pb].c, pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c,r3, c3); if( XX < 0 ) { L1 = tri.ab; // .ac shared limb L2 = tri.bc; // if( L1 != L3 && L2 != L4 ){ // need this check for stability. tx.a = tri.b; tx.b = tri.a; tx.c = D; tx.ab = L1; tx.ac = T2; tx.bc = L3; // triangle 2; tx2.a = tri.b; tx2.b = tri.c; tx2.c = D; tx2.ab = L2; tx2.ac = t; tx2.bc = L4; ids.insert(t); ids.insert(T2); t2 = tx2; tri = tx; // change knock on triangle labels. if( L3 >= 0 ) { Triad &t3 = triads[L3]; if( t3.ab == T2 ) t3.ab = t; else if( t3.bc == T2 ) t3.bc = t; else if( t3.ac == T2 ) t3.ac = t; } if(L2 >= 0 ) { Triad &t4 = triads[L2]; if( t4.ab == t ) t4.ab = T2; else if( t4.bc == t ) t4.bc = T2; else if( t4.ac == t ) t4.ac = T2; } } } } return(1); } mathgl-2.4.4/src/eval.cpp0000644000175000017500000010075513513030041015377 0ustar alastairalastair/*************************************************************************** * eval.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mgl2/data.h" #include "mgl2/eval.h" #if MGL_HAVE_GSL #include #include #include #include #endif //----------------------------------------------------------------------------- // constants for expression parsing enum{ EQ_NUM=0, // a variable substitution EQ_RND, // random number EQ_A, // numeric constant // normal functions of 2 arguments EQ_LT, // comparison xy EQ_EQ, // comparison x=y EQ_OR, // comparison x|y EQ_AND, // comparison x&y EQ_ADD, // addition x+y EQ_SUB, // substraction x-y EQ_MUL, // multiplication x*y EQ_DIV, // division x/y EQ_IPOW, // power x^n for integer n EQ_POW, // power x^y EQ_MOD, // x modulo y EQ_LOG, // logarithm of x on base a, log_a(x) = ln(x)/ln(a) EQ_ARG, // argument of complex number arg(x,y) = atan2(x,y) EQ_HYPOT, // sqrt(x^2+y^2)=hypot(x,y) EQ_MAX, // maximum of x and y EQ_MIN, // minimum of x and y // special functions of 2 arguments EQ_BESJ, // regular cylindrical Bessel function of fractional order EQ_BESY, // irregular cylindrical Bessel function of fractional order EQ_BESI, // regular modified Bessel function of fractional order EQ_BESK, // irregular modified Bessel function of fractional order EQ_ELE, // elliptic integral E(\phi,k) = \int_0^\phi dt \sqrt((1 - k^2 \sin^2(t))) EQ_ELF, // elliptic integral F(\phi,k) = \int_0^\phi dt 1/\sqrt((1 - k^2 \sin^2(t))) EQ_LP, // Legendre polynomial P_l(x), (|x|<=1, l>=0) EQ_BETA, // beta function B(x,y) = Gamma(x)*Gamma(y)/Gamma(x+y) EQ_GAMMA_INC, // incomplete gamma function Gamma(a,x) = \int_x^\infty dt t^{a-1} \exp(-t) for x>=0. // normal functions of 1 argument EQ_SIN, // sine function \sin(x). !!! MUST BE FIRST 1-PLACE FUNCTION EQ_COS, // cosine function \cos(x). EQ_TAN, // tangent function \tan(x). EQ_ASIN, // inverse sine function \sin(x). EQ_ACOS, // inverse cosine function \sin(x). EQ_ATAN, // inverse tangent function \tan(x). EQ_SINH, // hyperbolic sine function \sin(x). EQ_COSH, // hyperbolic cosine function \sin(x). EQ_TANH, // hyperbolic tangent function \tan(x). EQ_ASINH, // inverse hyperbolic sine function \sin(x). EQ_ACOSH, // inverse hyperbolic cosine function \sin(x). EQ_ATANH, // inverse hyperbolic tangent function \tan(x). EQ_SQRT, // square root function \sqrt(x) EQ_EXP, // exponential function \exp(x) EQ_LN, // logarithm of x, ln(x) EQ_LG, // decimal logarithm of x, lg(x) = ln(x)/ln(10) EQ_SIGN, // sign of number EQ_STEP, // step function EQ_INT, // integer part [x] EQ_ABS, // absolute value of x // special functions of 1 argument EQ_LI2, // dilogarithm for a real argument Li2(x) = - \Re \int_0^x ds \log(1-s)/s. EQ_ELLE, // complete elliptic integral is denoted by E(k) = E(\pi/2, k). EQ_ELLK, // complete elliptic integral is denoted by K(k) = F(\pi/2, k). EQ_AI, // Airy function Ai(x) EQ_BI, // Airy function Bi(x) EQ_ERF, // error function erf(x) = (2/\sqrt(\pi)) \int_0^x dt \exp(-t^2). EQ_EI3, // exponential integral Ei_3(x) = \int_0^x dt \exp(-t^3) for x >= 0. EQ_EI, // exponential integral Ei(x), Ei(x) := - PV(\int_{-x}^\infty dt \exp(-t)/t), where PV denotes the principal value of the integral. EQ_E1, // exponential integral E_1(x), E_1(x) := Re \int_1^\infty dt \exp(-xt)/t. EQ_E2, // exponential integral E_2(x), E_2(x) := Re \int_1^\infty dt \exp(-xt)/t^2. EQ_SI, // Sine integral Si(x) = \int_0^x dt \sin(t)/t. EQ_CI, // Cosine integral Ci(x) = \int_0^x dt \cos(t)/t. EQ_GAMMA, // Gamma function \Gamma(x) = \int_0^\infty dt t^{x-1} \exp(-t) EQ_PSI, // digamma function \psi(x) = \Gamma'(x)/\Gamma(x) for general x, x \ne 0. EQ_W0, // principal branch of the Lambert W function, W_0(x). Functions W(x), are defined to be solutions of the equation W\exp(W) = x. EQ_W1, // secondary real-valued branch of the Lambert W function, W_{-1}(x). Functions W(x), are defined to be solutions of the equation W\exp(W) = x. EQ_SINC, // compute \sinc(x) = \sin(\pi x) / (\pi x) for any value of x. EQ_ZETA, // Riemann zeta function \zeta(s) = \sum_{k=1}^\infty k^{-s}for arbitrary s, s \ne 1. EQ_ETA, // eta function \eta(s) = (1-2^{1-s}) \zeta(s) for arbitrary s. EQ_AID, // Derivative of Airy function Ai(x) EQ_BID, // Derivative of Airy function Bi(x) EQ_Z, // Dawson function \exp(-x^2) \int_0^x dt \exp(t^2) // Jacoby functions of 2 arguments EQ_SN, // Jacobian elliptic function sn(u|m) // !!! MUST BE FIRST NON 1-PLACE FUNCTION EQ_SC, // Jacobian elliptic function sn(u|m)/cn(u|m) EQ_SD, // Jacobian elliptic function sn(u|m)/dn(u|m) EQ_NS, // Jacobian elliptic function 1/sn(u|m) EQ_NC, // Jacobian elliptic function 1/cn(u|m) EQ_ND, // Jacobian elliptic function 1/dn(u|m) EQ_CN, // Jacobian elliptic function cn(u|m) EQ_CS, // Jacobian elliptic function cn(u|m)/sn(u|m) EQ_CD, // Jacobian elliptic function cn(u|m)/dn(u|m) EQ_DN, // Jacobian elliptic function dn(u|m) EQ_DS, // Jacobian elliptic function dn(u|m)/sn(u|m) EQ_DC, // Jacobian elliptic function dn(u|m)/cn(u|m) // MUST BE LAST ELLIPTIC FUNCTION // not-ready EQ_EN, EQ_CL // Clausen function }; //----------------------------------------------------------------------------- #ifndef M_PI #define M_PI 3.14159265358979323846 #endif //----------------------------------------------------------------------------- int mglFormula::Error=0; bool MGL_LOCAL_PURE mglCheck(char *str,int n); int MGL_LOCAL_PURE mglFindInText(const char *str, const char *lst); //----------------------------------------------------------------------------- #if MGL_HAVE_GSL MGL_NO_EXPORT gsl_rng *mgl_rng=0; // NOTE: should be deleted by gsl_rng_free() but I don't know where :( #endif void MGL_EXPORT mgl_srnd(long seed) { #if MGL_HAVE_GSL if(mgl_rng==0) { gsl_rng_env_setup(); mgl_rng = gsl_rng_alloc(gsl_rng_default); } gsl_rng_set(mgl_rng, seed); #else srand(seed); #endif } void MGL_EXPORT mgl_srnd_(int *seed) { mgl_srnd(*seed); } //----------------------------------------------------------------------------- double MGL_EXPORT_CONST mgl_hypot(double x, double y) { return hypot(x,y); } //----------------------------------------------------------------------------- #if MGL_HAVE_PTHREAD extern pthread_mutex_t mutexRnd; #endif double MGL_EXPORT mgl_rnd() { #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexRnd); #endif double res; #pragma omp critical(rnd) { #if MGL_HAVE_GSL if(mgl_rng==0) { gsl_rng_env_setup(); mgl_rng = gsl_rng_alloc(gsl_rng_default); gsl_rng_set(mgl_rng, time(0)); } res = gsl_rng_uniform(mgl_rng); // gsl_rng_free(r); #else res = rand()/(RAND_MAX-1.); #endif } #if MGL_HAVE_PTHREAD pthread_mutex_unlock(&mutexRnd); #endif return res; } double MGL_EXPORT mgl_rnd_() { return mgl_rnd(); } //----------------------------------------------------------------------------- mglFormula::~mglFormula() { if(tmp) delete tmp; if(Left) delete Left; if(Right) delete Right; } //----------------------------------------------------------------------------- // Formula constructor (automatically parse and "compile" formula) mglFormula::mglFormula(const char *string) { dat = tmp = NULL; dx1=dy1=dz1=0; dx2=dy2=dz2=1; #if MGL_HAVE_GSL gsl_set_error_handler_off(); #endif Error=0; Left=Right=0; Res=0; Kod=0; if(!string) { Kod = EQ_NUM; Res = 0; return; } char *str = new char[strlen(string)+1]; strcpy(str,string); long n,len; mgl_strtrim(str); mgl_strlwr(str); len=strlen(str); if(str[0]==0) { delete []str; return; } if(str[0]=='(' && mglCheck(str+1,len-2)) // remove braces { memmove(str,str+1,len); len-=2; str[len]=0; } len=strlen(str); if(str[0]==':' && str[1]!=0) // this data file for interpolation { double sx1,sx2,sy1,sy2,sz1,sz2; char *buf = strchr(str+1,':'); if(buf && *buf) { *buf = 0; int r = sscanf(buf+1,"%lg:%lg:%lg:%lg:%lg:%lg",&sx1,&sx2,&sy1,&sy2,&sz1,&sz2); if(r>1 && sx1!=sx2) { dx1=sx1; dx2=sx2; } if(r>3 && sy1!=sy2) { dy1=sy1; dy2=sy2; } if(r>5 && sz1!=sz2) { dz1=sz1; dz2=sz2; } } dat = tmp = new mglData(str+1); delete []str; return; } n=mglFindInText(str,"&|"); // lowest priority -- logical if(n>=0) { if(str[n]=='|') Kod=EQ_OR; else Kod=EQ_AND; str[n]=0; Left=new mglFormula(str); Right=new mglFormula(str+n+1); delete []str; return; } n=mglFindInText(str,"<>="); // low priority -- conditions if(n>=0) { if(str[n]=='<') Kod=EQ_LT; else if(str[n]=='>') Kod=EQ_GT; else Kod=EQ_EQ; str[n]=0; Left=new mglFormula(str); Right=new mglFormula(str+n+1); delete []str; return; } n=mglFindInText(str,"+-"); // normal priority -- additions if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2])))) { if(str[n]=='+') Kod=EQ_ADD; else Kod=EQ_SUB; str[n]=0; Left=new mglFormula(str); Right=new mglFormula(str+n+1); delete []str; return; } n=mglFindInText(str,"*/%"); // high priority -- multiplications if(n>=0) { if(str[n]=='*') Kod=EQ_MUL; else if(str[n]=='/') Kod=EQ_DIV; else Kod=EQ_MOD; str[n]=0; Left=new mglFormula(str); Right=new mglFormula(str+n+1); delete []str; return; } n=mglFindInText(str,"^"); // highest priority -- power if(n>=0) { Kod=EQ_IPOW; str[n]=0; Left=new mglFormula(str); Right=new mglFormula(str+n+1); delete []str; return; } for(n=0;n=len) // this is number or variable { Kod = EQ_NUM; // Left = Right = 0; if(str[1]==0 && str[0]>='a' && str[0]<='z') // available variables { Kod=EQ_A; Res = str[0]-'a'; } else if(!strcmp(str,"rnd")) Kod=EQ_RND; else if(!strcmp(str,"pi")) Res=M_PI; else if(!strcmp(str,"inf")) Res=INFINITY; else Res=atof(str); // this is number } else { char name[128]; mgl_strncpy(name,str,128); name[127]=name[n]=0; memmove(str,str+n+1,len-n); len=strlen(str); str[--len]=0; if(!strncmp(name,"jacobi_",7)) memmove(name,name+7,(strlen(name+7)+1)*sizeof(char)); if(name[0]=='a') { if(!strcmp(name+1,"sin")) Kod=EQ_ASIN; else if(!strcmp(name+1,"cos")) Kod=EQ_ACOS; else if(!strcmp(name+1,"tan")) Kod=EQ_ATAN; else if(!strcmp(name+1,"sinh")) Kod=EQ_ASINH; else if(!strcmp(name+1,"cosh")) Kod=EQ_ACOSH; else if(!strcmp(name+1,"tanh")) Kod=EQ_ATANH; else if(!strcmp(name+1,"rg")) Kod=EQ_ARG; else if(!strcmp(name+1,"bs")) Kod=EQ_ABS; else if(!strcmp(name+1,"i")) Kod=EQ_AI; else if(!strcmp(name+1,"iry_ai")) Kod=EQ_AI; else if(!strcmp(name+1,"iry_bi")) Kod=EQ_BI; else if(!strcmp(name+1,"iry_dai")) Kod=EQ_AID; else if(!strcmp(name+1,"iry_dbi")) Kod=EQ_BID; } else if(name[0]=='b') { if(!strcmp(name+1,"i")) Kod=EQ_BI; else if(!strcmp(name+1,"essel_j")) Kod=EQ_BESJ; else if(!strcmp(name+1,"essel_i")) Kod=EQ_BESI; else if(!strcmp(name+1,"essel_k")) Kod=EQ_BESK; else if(!strcmp(name+1,"essel_y")) Kod=EQ_BESY; else if(!strcmp(name+1,"eta")) Kod=EQ_BETA; } else if(name[0]=='c') { if(!strcmp(name+1,"os")) Kod=EQ_COS; else if(!strcmp(name+1,"osh")) Kod=EQ_COSH; else if(!strcmp(name+1,"h")) Kod=EQ_COSH; else if(!strcmp(name+1,"i")) Kod=EQ_CI; else if(!strcmp(name+1,"n")) Kod=EQ_CN; else if(!strcmp(name+1,"s")) Kod=EQ_CS; else if(!strcmp(name+1,"d")) Kod=EQ_CD; else if(!strcmp(name+1,"l")) Kod=EQ_CL; } else if(name[0]=='d') { if(!strcmp(name+1,"n")) Kod=EQ_DN; else if(!strcmp(name+1,"s")) Kod=EQ_DS; else if(!strcmp(name+1,"c")) Kod=EQ_DC; else if(!strcmp(name+1,"ilog")) Kod=EQ_LI2; } else if(name[0]=='e') { if(!strcmp(name+1,"xp")) Kod=EQ_EXP; else if(!strcmp(name+1,"rf")) Kod=EQ_ERF; else if(!strcmp(name+1,"n")) Kod=EQ_EN; else if(!strcmp(name+1,"e")) Kod=EQ_ELLE; else if(!strcmp(name+1,"k")) Kod=EQ_ELLK; else if(name[0]==0) Kod=EQ_ELE; else if(!strcmp(name+1,"i")) Kod=EQ_EI; else if(!strcmp(name+1,"1")) Kod=EQ_E1; else if(!strcmp(name+1,"2")) Kod=EQ_E2; else if(!strcmp(name+1,"ta")) Kod=EQ_ETA; else if(!strcmp(name+1,"i3")) Kod=EQ_EI3; else if(!strcmp(name+1,"lliptic_e")) Kod=EQ_ELE; else if(!strcmp(name+1,"lliptic_f")) Kod=EQ_ELF; else if(!strcmp(name+1,"lliptic_ec")) Kod=EQ_ELLE; else if(!strcmp(name+1,"lliptic_kc")) Kod=EQ_ELLK; } else if(name[0]=='l') { if(!strcmp(name+1,"og")) Kod=EQ_LOG; else if(!strcmp(name+1,"g")) Kod=EQ_LG; else if(!strcmp(name+1,"n")) Kod=EQ_LN; else if(!strcmp(name+1,"i2")) Kod=EQ_LI2; else if(!strcmp(name+1,"egendre")) Kod=EQ_LP; } else if(name[0]=='s') { if(!strcmp(name+1,"qrt")) Kod=EQ_SQRT; else if(!strcmp(name+1,"in")) Kod=EQ_SIN; else if(!strcmp(name+1,"tep")) Kod=EQ_STEP; else if(!strcmp(name+1,"ign")) Kod=EQ_SIGN; else if(!strcmp(name+1,"inh")) Kod=EQ_SINH; else if(!strcmp(name+1,"h")) Kod=EQ_SINH; else if(!strcmp(name+1,"i")) Kod=EQ_SI; else if(!strcmp(name+1,"n")) Kod=EQ_SN; else if(!strcmp(name+1,"c")) Kod=EQ_SC; else if(!strcmp(name+1,"d")) Kod=EQ_SD; else if(!strcmp(name+1,"inc")) Kod=EQ_SINC; } else if(name[0]=='t') { if(!strcmp(name+1,"g")) Kod=EQ_TAN; else if(!strcmp(name+1,"an")) Kod=EQ_TAN; else if(!strcmp(name+1,"anh")) Kod=EQ_TANH; else if(!strcmp(name+1,"h")) Kod=EQ_TANH; } else if(name[0]=='m') { if(!strcmp(name+1,"od")) Kod=EQ_MOD; else if(!strcmp(name+1,"ax")) Kod=EQ_MAX; else if(!strcmp(name+1,"in")) Kod=EQ_MIN; } else if(!strcmp(name,"hypot")) Kod=EQ_HYPOT; else if(!strcmp(name,"pow")) Kod=EQ_POW; else if(!strcmp(name,"i")) Kod=EQ_BESI; else if(!strcmp(name,"int")) Kod=EQ_INT; else if(!strcmp(name,"j")) Kod=EQ_BESJ; else if(!strcmp(name,"k")) Kod=EQ_BESK; else if(!strcmp(name,"y")) Kod=EQ_BESY; else if(!strcmp(name,"f")) Kod=EQ_ELF; else if(!strcmp(name,"gamma")) Kod=EQ_GAMMA; else if(!strcmp(name,"gamma_inc")) Kod=EQ_GAMMA_INC; else if(!strcmp(name,"ns")) Kod=EQ_NS; else if(!strcmp(name,"nc")) Kod=EQ_NC; else if(!strcmp(name,"nd")) Kod=EQ_ND; else if(!strcmp(name,"w0")) Kod=EQ_W0; else if(!strcmp(name,"w1")) Kod=EQ_W1; else if(!strcmp(name,"psi")) Kod=EQ_PSI; else if(!strcmp(name,"zeta")) Kod=EQ_ZETA; else if(!strcmp(name,"z")) Kod=EQ_Z; else { delete []str; return; } // unknown function n=mglFindInText(str,","); if(n>=0) { str[n]=0; Left=new mglFormula(str); Right=new mglFormula(str+n+1); } else Left=new mglFormula(str); } delete []str; } //----------------------------------------------------------------------------- // evaluate formula for 'x'='r', 'y'='n'='v', 't'='z', 'u'='a' variables mreal mglFormula::Calc(mreal x,mreal y,mreal t,mreal u) const { Error=0; mreal a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(mreal)); a1['a'-'a'] = a1['c'-'a'] = a1['u'-'a'] = u; a1['x'-'a'] = a1['r'-'a'] = x; a1['y'-'a'] = a1['n'-'a'] = a1['v'-'a'] = y; a1['z'-'a'] = a1['t'-'a'] = t; mreal b = CalcIn(a1); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate formula for 'x'='r', 'y'='n', 't'='z', 'u'='a', 'v'='b', 'w'='c' variables mreal mglFormula::Calc(mreal x,mreal y,mreal t,mreal u,mreal v,mreal w) const { Error=0; mreal a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(mreal)); a1['c'-'a'] = a1['w'-'a'] = w; a1['b'-'a'] = a1['v'-'a'] = v; a1['a'-'a'] = a1['u'-'a'] = u; a1['x'-'a'] = a1['r'-'a'] = x; a1['y'-'a'] = a1['n'-'a'] = y; a1['z'-'a'] = a1['t'-'a'] = t; mreal b = CalcIn(a1); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate formula for arbitrary set of variables mreal mglFormula::Calc(const mreal var[MGL_VS]) const { Error=0; mreal b = CalcIn(var); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate formula for 'x'='r', 'y'='n'='v', 't'='z', 'u'='a' variables mreal mglFormula::CalcD(char diff,mreal x,mreal y,mreal t,mreal u) const { Error=0; mreal a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(mreal)); a1['a'-'a'] = a1['c'-'a'] = a1['u'-'a'] = u; a1['x'-'a'] = a1['r'-'a'] = x; a1['y'-'a'] = a1['n'-'a'] = a1['v'-'a'] = y; a1['z'-'a'] = a1['t'-'a'] = t; mreal b = CalcDIn(diff-'a', a1); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate formula for 'x'='r', 'y'='n', 't'='z', 'u'='a', 'v'='b', 'w'='c' variables mreal mglFormula::CalcD(char diff,mreal x,mreal y,mreal t,mreal u,mreal v,mreal w) const { Error=0; mreal a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(mreal)); a1['c'-'a'] = a1['w'-'a'] = w; a1['b'-'a'] = a1['v'-'a'] = v; a1['a'-'a'] = a1['u'-'a'] = u; a1['x'-'a'] = a1['r'-'a'] = x; a1['y'-'a'] = a1['n'-'a'] = y; a1['z'-'a'] = a1['t'-'a'] = t; mreal b = CalcDIn(diff-'a', a1); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate derivate of formula respect to 'diff' variable for arbitrary set of other variables mreal mglFormula::CalcD(const mreal var[MGL_VS], char diff) const { Error=0; mreal b = CalcDIn(diff-'a', var); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- double MGL_LOCAL_CONST cand(double a,double b) {return a&&b?1:0;} double MGL_LOCAL_CONST cor(double a,double b) {return a||b?1:0;} double MGL_LOCAL_CONST ceq(double a,double b) {return a==b?1:0;} double MGL_LOCAL_CONST clt(double a,double b) {return ab?1:0;} double MGL_LOCAL_CONST add(double a,double b) {return a+b;} double MGL_LOCAL_CONST sub(double a,double b) {return a-b;} double MGL_LOCAL_CONST mul(double a,double b) {return a&&b?a*b:0;} double MGL_LOCAL_CONST del(double a,double b) {return b?a/b:NAN;} double MGL_LOCAL_CONST ipw(double a,double b) {return fabs(b-int(b))<1e-5 ? mgl_ipow(a,int(b)) : pow(a,b);} double MGL_LOCAL_CONST llg(double a,double b) {return log(a)/log(b);} #if MGL_HAVE_GSL double MGL_LOCAL_CONST gslEllE(double a,double b) {return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslEllF(double a,double b) {return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslLegP(double a,double b) {return gsl_sf_legendre_Pl(int(a),b);} double MGL_LOCAL_CONST gslEllEc(double a) {return gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslEllFc(double a) {return gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslAi(double a) {return gsl_sf_airy_Ai(a,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslBi(double a) {return gsl_sf_airy_Bi(a,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslAi_d(double a) {return gsl_sf_airy_Ai_deriv(a,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslBi_d(double a) {return gsl_sf_airy_Bi_deriv(a,GSL_PREC_SINGLE);} #endif double MGL_LOCAL_CONST sgn(double a) {return a<0 ? -1:(a>0?1:0);} double MGL_LOCAL_CONST stp(double a) {return a>0 ? 1:0;} double MGL_LOCAL_CONST arg(double a,double b) { return atan2(b,a); } double MGL_LOCAL_CONST mgz1(double) {return NAN;} // NOTE I think NAN value is more correct here than 0 double MGL_LOCAL_CONST mgz2(double,double) {return NAN;} // NOTE I think NAN value is more correct here than 0 double MGL_LOCAL_CONST mgl_asinh(double x) { return log(x+sqrt(x*x+1.)); } double MGL_LOCAL_CONST mgl_acosh(double x) { return x>1 ? log(x+sqrt(x*x-1.)) : NAN; } double MGL_LOCAL_CONST mgl_atanh(double x) { return fabs(x)<1 ? log((1.+x)/(1.-x))/2 : NAN; } double MGL_LOCAL_CONST mgl_fmin(double a,double b) { return a > b ? b : a; } double MGL_LOCAL_CONST mgl_fmax(double a,double b) { return a > b ? a : b; } //----------------------------------------------------------------------------- typedef double (*func_1)(double); typedef double (*func_2)(double, double); //----------------------------------------------------------------------------- static const mreal z2[EQ_SIN-EQ_LT] = {3,3,3,3,0,3,3,0,0,0,0,0,NAN,3,3,3,3 #if MGL_HAVE_GSL ,3,NAN, 3,NAN, 0,0,3,1,3 #else ,0,0,0,0,0,0,0,0,0 #endif }; static const func_2 f2[EQ_SIN-EQ_LT] = {clt,cgt,ceq,cor,cand,add,sub,mul,del,ipw,pow,fmod,llg,arg,hypot,mgl_fmax,mgl_fmin #if MGL_HAVE_GSL ,gsl_sf_bessel_Jnu,gsl_sf_bessel_Ynu, gsl_sf_bessel_Inu,gsl_sf_bessel_Knu, gslEllE,gslEllF,gslLegP,gsl_sf_beta,gsl_sf_gamma_inc #else ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2 #endif }; static const func_1 f1[EQ_SN-EQ_SIN] = {sin,cos,tan,asin,acos,atan,sinh,cosh,tanh, mgl_asinh,mgl_acosh,mgl_atanh,sqrt,exp,log,log10,sgn,stp,floor,fabs #if MGL_HAVE_GSL ,gsl_sf_dilog,gslEllEc,gslEllFc,gslAi,gslBi,gsl_sf_erf, gsl_sf_expint_3,gsl_sf_expint_Ei,gsl_sf_expint_E1,gsl_sf_expint_E2, gsl_sf_Si,gsl_sf_Ci,gsl_sf_gamma,gsl_sf_psi,gsl_sf_lambert_W0, gsl_sf_lambert_Wm1,gsl_sf_sinc,gsl_sf_zeta,gsl_sf_eta,gslAi_d,gslBi_d, gsl_sf_dawson #else ,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1, mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1 #endif }; //----------------------------------------------------------------------------- // evaluation of embedded (included) expressions mreal mglFormula::CalcIn(const mreal *a1) const { if(dat) { mreal x = (a1['x'-'a']-dx1)*(dat->GetNx()-1)/(dx2-dx1); mreal y = (a1['y'-'a']-dy1)*(dat->GetNy()-1)/(dy2-dy1); mreal z = (a1['z'-'a']-dz1)*(dat->GetNz()-1)/(dz2-dz1); return mgl_data_spline(dat,x,y,z); } if(KodCalcIn(a1); if(mgl_isfin(a)) { if(KodCalcIn(a1)):NAN; } else if(KodCalcIn(a1), &sn, &cn, &dn); switch(Kod) { case EQ_SN: return sn; case EQ_SC: return sn/cn; case EQ_SD: return sn/dn; case EQ_CN: return cn; case EQ_CS: return cn/sn; case EQ_CD: return cn/dn; case EQ_DN: return dn; case EQ_DS: return dn/sn; case EQ_DC: return dn/cn; case EQ_NS: return 1./sn; case EQ_NC: return 1./cn; case EQ_ND: return 1./dn; } } #endif } return NAN; } //----------------------------------------------------------------------------- double MGL_LOCAL_CONST mgzz(double,double) {return 0;} double MGL_LOCAL_CONST mgp(double ,double ) {return 1;} double MGL_LOCAL_CONST mgm(double ,double ) {return -1;} double MGL_LOCAL_CONST mul1(double ,double b) {return b;} double MGL_LOCAL_CONST mul2(double a,double ) {return a;} double MGL_LOCAL_CONST div1(double ,double b) {return b?1/b:NAN;} double MGL_LOCAL_CONST div2(double a,double b) {return b?-a/(b*b):NAN;} double MGL_LOCAL_CONST ipw1(double a,double b) {return b*(fabs(b-int(b))<1e-5 ? mgl_ipow(a,int(b-1)) : pow(a,b-1));} double MGL_LOCAL_CONST pow1(double a,double b) {return b*pow(a,b-1);} double MGL_LOCAL_CONST pow2(double a,double b) {return log(a)*pow(a,b);} double MGL_LOCAL_CONST llg1(double a,double b) {return 1/(a*log(b));} double MGL_LOCAL_CONST llg2(double a,double b) {return -log(a)/(b*log(b)*log(b));} double MGL_LOCAL_CONST cos_d(double a) {return -sin(a);} double MGL_LOCAL_CONST tan_d(double a) {return 1./(cos(a)*cos(a));} double MGL_LOCAL_CONST asin_d(double a) {return 1./sqrt(1.-a*a);} double MGL_LOCAL_CONST acos_d(double a) {return -1./sqrt(1.-a*a);} double MGL_LOCAL_CONST atan_d(double a) {return 1./(1.+a*a);} double MGL_LOCAL_CONST tanh_d(double a) {return 1./(cosh(a)*cosh(a));} double MGL_LOCAL_CONST atanh_d(double a){return 1./(1.-a*a);} double MGL_LOCAL_CONST asinh_d(double a){return 1./sqrt(1.+a*a);} double MGL_LOCAL_CONST acosh_d(double a){return 1./sqrt(a*a-1.);} double MGL_LOCAL_CONST sqrt_d(double a) {return 0.5/sqrt(a);} double MGL_LOCAL_CONST log10_d(double a){return M_LN10/a;} double MGL_LOCAL_CONST log_d(double a) {return 1./a;} double MGL_LOCAL_CONST erf_d(double a) {return 2*exp(-a*a)/sqrt(M_PI);} double MGL_LOCAL_CONST dilog_d(double a){return log(a)/(1.-a);} double MGL_LOCAL_CONST ei_d(double a) {return exp(a)/a;} double MGL_LOCAL_CONST si_d(double a) {return a?sin(a)/a:1;} double MGL_LOCAL_CONST ci_d(double a) {return cos(a)/a;} double MGL_LOCAL_CONST exp3_d(double a) {return exp(-a*a*a);} double MGL_LOCAL_CONST e1_d(double a) {return exp(-a)/a;} double MGL_LOCAL_CONST sinc_d(double a) {return a ? (cos(M_PI*a)/a-sin(M_PI*a)/(M_PI*a*a)) : 0;} #if MGL_HAVE_GSL double MGL_LOCAL_CONST e2_d(double a) {return -gsl_sf_expint_E1(a);} double MGL_LOCAL_CONST gslJnuD(double a,double b) {return 0.5*(gsl_sf_bessel_Jnu(a-1,b)-gsl_sf_bessel_Jnu(a+1,b));} double MGL_LOCAL_CONST gslYnuD(double a,double b) {return 0.5*(gsl_sf_bessel_Ynu(a-1,b)-gsl_sf_bessel_Ynu(a+1,b));} double MGL_LOCAL_CONST gslKnuD(double a,double b) {return -(a*gsl_sf_bessel_Knu(a,b)/b +gsl_sf_bessel_Knu(a-1,b));} double MGL_LOCAL_CONST gslInuD(double a,double b) {return -(a*gsl_sf_bessel_Inu(a,b)/b -gsl_sf_bessel_Inu(a-1,b));} double MGL_LOCAL_CONST gslEllE1(double a,double b) {return sqrt(1.-sin(a)*sin(a)*b);} double MGL_LOCAL_CONST gslEllE2(double a,double b) {return (gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE) - gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE))/(2.*b);} double MGL_LOCAL_CONST gslEllF1(double a,double b) {return 1./sqrt(1.-sin(a)*sin(a)*b);} double MGL_LOCAL_CONST gslEllF2(double a,double b) {return (gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE) - gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE)*(1.-b))/(2*b*(1.-b)) - sin(2.*a)/(sqrt(1.-sin(a)*sin(a)*b)*2.*(1.-b));} double MGL_LOCAL_CONST gslE_d(double a) {return (gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE) - gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE))/(2.*a);} double MGL_LOCAL_CONST gslK_d(double a) {return (gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE) - (1.-a)*gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE))/(2.*a*(1.-a));} double MGL_LOCAL_CONST gamma_d(double a) {return gsl_sf_psi(a)*gsl_sf_gamma(a);} #endif double MGL_LOCAL_CONST ginc_d(double a, double x) {return -exp(-x)*pow(x,a-1);} //----------------------------------------------------------------------------- static const func_2 f21[EQ_SIN-EQ_LT] = {mgzz,mgzz,mgzz, mgzz,mgzz,mgp, mgp,mul1,div1, ipw1,pow1,mgp,llg1, mgz2,mgzz,mgzz #if MGL_HAVE_GSL ,mgz2,mgz2,mgz2, mgz2,gslEllE1,gslEllF1, mgz2,mgz2,mgz2 #else ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2 #endif }; static const func_2 f22[EQ_SIN-EQ_LT] = {mgzz,mgzz,mgzz,mgzz,mgzz,mgp,mgm,mul2,div2,pow2,pow2,mgz2,llg2, mgz2,mgzz,mgzz #if MGL_HAVE_GSL ,gslJnuD,gslYnuD,gslInuD,gslKnuD,gslEllE2,gslEllF2,mgz2/*gslLegP*/,mgz2,ginc_d #else ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2 #endif }; static const func_1 f11[EQ_SN-EQ_SIN] = {cos,cos_d,tan_d,asin_d,acos_d,atan_d,cosh,sinh,tanh_d, asinh_d,acosh_d,atanh_d,sqrt_d,exp,log_d,log10_d,mgz1,mgz1,mgz1,sgn #if MGL_HAVE_GSL ,dilog_d,gslE_d,gslK_d,gslAi_d,gslBi_d,erf_d,exp3_d,ei_d,e1_d,e2_d, si_d,ci_d,gamma_d,gsl_sf_psi_1,mgz1,mgz1,sinc_d,mgz1,mgz1,mgz1,mgz1,mgz1 #else ,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1, mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1 #endif }; //----------------------------------------------------------------------------- // evaluation of derivative of embedded (included) expressions mreal mglFormula::CalcDIn(int id, const mreal *a1) const { if(dat) { mreal x = (a1['x'-'a']-dx1)*(dat->GetNx()-1)/(dx2-dx1); mreal y = (a1['y'-'a']-dy1)*(dat->GetNy()-1)/(dy2-dy1); mreal z = (a1['z'-'a']-dz1)*(dat->GetNz()-1)/(dz2-dz1); mreal dx,dy,dz, res=0; mgl_data_spline_ext(dat,x,y,z,&dx,&dy,&dz); if(id=='x'-'a') res = dx/(dat->GetNx()-1)*(dx2-dx1); if(id=='y'-'a') res = dy/(dat->GetNy()-1)*(dy2-dy1); if(id=='z'-'a') res = dz/(dat->GetNz()-1)*(dz2-dz1); return res; } if(Kod==EQ_A && id==(int)Res) return 1; else if(KodCalcIn(a1), d = Left->CalcDIn(id,a1); if(mgl_isfin(a) && mgl_isfin(d)) { if(KodCalcIn(a1):NAN; double c = Right?Right->CalcDIn(id,a1):NAN; // return mgl_isfin(b) ? (f21[Kod-EQ_LT](a,b)*d + f22[Kod-EQ_LT](a,b)*c) : NAN; return mgl_isfin(b) ? (d?f21[Kod-EQ_LT](a,b)*d:0) + (c?f22[Kod-EQ_LT](a,b)*c:0) : NAN; } // else if(KodCalcIn(a1); if(mgl_isbad(b)) return NAN; gsl_sf_elljac_e(a,b, &sn, &cn, &dn); switch(Kod) // At this moment parse only differentiation or argument NOT mu !!! { case EQ_SN: return cn*dn*d; case EQ_SC: return dn*d/(cn*cn); case EQ_SD: return cn*d/(dn*dn); case EQ_CN: return -dn*sn*d; case EQ_CS: return dn*d/(sn*sn); case EQ_CD: return (b-1)*d*sn/(dn*dn); case EQ_DN: return -b*d*cn*sn; case EQ_DS: return -cn*d/(sn*sn); case EQ_DC: return (1-b)*sn*d/(cn*cn); case EQ_NS: return -cn*dn*d/(sn*sn); case EQ_NC: return dn*sn*d/(cn*cn); case EQ_ND: return b*cn*sn*d/(dn*dn); } } #endif } return NAN; } //----------------------------------------------------------------------------- // Check braces correctness bool MGL_LOCAL_PURE mglCheck(char *str,int n) { long s = 0; for(long i=0;i=0;i--) { if(str[i]=='(') l++; if(str[i]==')') r++; if(l==r && strchr(lst,str[i])) return i; } return -1; } //----------------------------------------------------------------------------- HMEX MGL_EXPORT mgl_create_expr(const char *expr) { return new mglFormula(expr); } void MGL_EXPORT mgl_delete_expr(HMEX ex) { if(ex) delete ex; } double MGL_EXPORT_PURE mgl_expr_eval(HMEX ex, double x, double y,double z) { return ex->Calc(x,y,z); } double MGL_EXPORT_PURE mgl_expr_eval_v(HMEX ex, mreal *var) { return ex->Calc(var); } double MGL_EXPORT_PURE mgl_expr_diff(HMEX ex, char dir, double x, double y,double z) { return ex->CalcD(dir,x,y,z); } double MGL_EXPORT_PURE mgl_expr_diff_v(HMEX ex, char dir, mreal *var) { return ex->CalcD(var, dir); } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_create_expr_(const char *expr, int l) { char *s=new char[l+1]; memcpy(s,expr,l); s[l]=0; uintptr_t res = uintptr_t(mgl_create_expr(s)); delete []s; return res; } void MGL_EXPORT mgl_delete_expr_(uintptr_t *ex) { mgl_delete_expr((HMEX)ex); } double MGL_EXPORT_PURE mgl_expr_eval_(uintptr_t *ex, mreal *x, mreal *y, mreal *z) { return mgl_expr_eval((HMEX) ex, *x,*y,*z); } double MGL_EXPORT_PURE mgl_expr_diff_(uintptr_t *ex, const char *dir, mreal *x, mreal *y, mreal *z, int) { return mgl_expr_diff((HMEX) ex, *dir,*x,*y,*z); } //----------------------------------------------------------------------------- mathgl-2.4.4/src/data_png.cpp0000644000175000017500000002540113513030041016217 0ustar alastairalastair/*************************************************************************** * data_png.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/base.h" #include "mgl2/data.h" #if MGL_HAVE_PNG #include #endif #if MGL_HAVE_JPEG #include #endif //----------------------------------------------------------------------------- unsigned MGL_LOCAL_PURE mgl_col_dif(unsigned char *c1,unsigned char *c2) { unsigned d1=abs(int(c1[0])-c2[0]), d2=abs(int(c1[1])-c2[1]), d3=abs(int(c1[2])-c2[2]); d2 = d2>d3?d2:d3; d2 = d2>d1?d2:d1; return d2; } //----------------------------------------------------------------------------- MGL_NO_EXPORT unsigned char *mgl_create_scheme(const char *scheme,long &num) { unsigned char *c=0,*cc=new unsigned char[3*strlen(scheme)+3],*c1,*c2; size_t nc=1,np=0,l=strlen(scheme); mglColor col; for(size_t i=0;iw) wi = w; if(hi>h) hi = h; } else { w = wi; h = hi; *g = new unsigned char[4*w*h]; } if(type==PNG_COLOR_TYPE_RGB_ALPHA) #pragma omp parallel for for(long i=0;ih) hi = h; if(wi>w) wi = w; } else { w = wi; h = hi; *g = new unsigned char[4*w*h]; } for(long i=0;i=v2) return; unsigned char *g = 0; int w=0, h=0; if(!mgl_read_image(&g,w,h,fname)) return; #ifdef OLD_IMPORT const mglTexture c(scheme,1); if(c.n<2) return; d->Create(w,h,1); float *ll = new float[3*c.n-1]; mglColor *lc = new mglColor[c.n-1]; const mglColor *c0=c.c0; for(long i=0;iny-i-1)+4*j); float pos=NAN, mval=256; for(long k=0;k=0 && u<=1) { pos=u*du+u0;mval=0; break; } // else if(u>-v && u<0){ pos=u0; mval=0; break; } // else if(u<1+v) { pos=du+u0; mval=0; break; } } else if(v=0 && u<=1) { pos=u*du+u0; mval=v; } // else if(u>-v && u<0){ pos=u0; mval=v; } // else if(u<1+v) { pos=du+u0; mval=v; } } } long K=c.n-2; float uF = (mglColor(cc-c0[0])*lc[0])*ll[0]; float uL = (mglColor(cc-c0[2*K])*lc[K])*ll[3*K]; if(mgl_isnan(pos) && uF<0) pos = 0; if(mgl_isnan(pos) && uL>1) pos = 1; d->a[j+d->nx*i] = v1 + pos*(v2-v1); } printf("\n"); delete []g; delete []ll; delete []lc; #else long num=0; unsigned char *c = mgl_create_scheme(scheme,num); if(num<2) return; d->Create(w,h,1); #pragma omp parallel for collapse(2) for(long i=0;iny-i-1)+4*j; for(long k=0;ka[j+d->nx*i] = v1 + pos*(v2-v1)/(num-1); } delete []c; delete []g; #endif } //----------------------------------------------------------------------------- int MGL_NO_EXPORT mgl_png_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_bmp_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_tga_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_jpeg_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_bps_save(const char *fname, int w, int h, unsigned char **p); void MGL_EXPORT mgl_data_export(HCDT dd, const char *fname, const char *scheme, double v1, double v2, long ns) { long nx=dd->GetNx(), ny=dd->GetNy(), nz=dd->GetNz(); if(v1>v2) return; if(ns<0 || ns>=nz) ns=0; if(v1==v2) { v1 = INFINITY; v2=-INFINITY; for(long i=0;ivthr(i); if(vvv2) v2=vv; } } if(v1==v2) return; long num=0; unsigned char *c = mgl_create_scheme(scheme,num); if(num<2) { delete []c; return; } unsigned char **p = new unsigned char*[ny]; unsigned char *d = new unsigned char[3*nx*ny]; #pragma omp parallel for for(long i=0;iv(j,i,ns)-v1)/(v2-v1)); if(k<0) k=0; if(k>=num) k=num-1; memcpy(d+3*(j+i*nx),c+3*k,3); } delete []c; int len=strlen(fname); if(!strcmp(fname+len-4,".jpg") || !strcmp(fname+len-5,".jpeg")) mgl_jpeg_save(fname, nx,ny,p); if(!strcmp(fname+len-4,".bmp")) mgl_bmp_save(fname, nx,ny,p); if(!strcmp(fname+len-4,".png")) mgl_png_save(fname, nx,ny,p); if(!strcmp(fname+len-4,".eps") || !strcmp(fname+len-4,".bps")) mgl_bps_save(fname, nx,ny,p); delete []p; delete []d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_export_(uintptr_t *d, const char *fname, const char *scheme,mreal *v1,mreal *v2,int *ns,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,scheme,n); f[n]=0; mgl_data_export(_DT_,s,f,*v1,*v2,*ns); delete []s; delete []f; } void MGL_EXPORT mgl_data_import_(uintptr_t *d, const char *fname, const char *scheme,mreal *v1,mreal *v2,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,scheme,n); f[n]=0; mgl_data_import(_DT_,s,f,*v1,*v2); delete []s; delete []f; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/obj.cpp0000644000175000017500000006760513513030041015230 0ustar alastairalastair/*************************************************************************** * obj.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/canvas.h" #include "mgl2/canvas_cf.h" #undef _GR_ #define _GR_ ((mglCanvas *)(*gr)) #define _Gr_ ((mglCanvas *)(gr)) int MGL_NO_EXPORT mgl_tga_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_pnga_save(const char *fname, int w, int h, unsigned char **p); void MGL_NO_EXPORT mgl_printf(void *fp, bool gz, const char *str, ...); //----------------------------------------------------------------------------- #include #include #include #include #include #include #include /* Size prefixes for printf/scanf for size_t and ptrdiff_t */ #ifdef _MSC_VER # define PRIuS "Iu" /* printf size_t */ # define PRIdS "Id" /* printf ptrdiff_t */ #else # define PRIuS "zu" /* printf size_t */ # define PRIdS "zd" /* printf ptrdiff_t */ #endif //----------------------------------------------------------------------------- void mglTexture::GetRGBAOBJ(unsigned char *f) const { const size_t bw = 128; //border width for(size_t i=0;i<256;i++) { mglColor c1 = col[2*i], c2 = col[2*i+1], c; for(size_t j=0;j<512;j++) { size_t i0 = 4*(j+512*(255-i)); if (j511-bw) c = c2; else c = c1 + (c2-c1)*((j-bw)/(255.)); f[i0] = int(255*c.r); f[i0+1] = int(255*c.g); f[i0+2] = int(255*c.b); f[i0+3] = int(255*c.a); } } } //----------------------------------------------------------------------------- struct ObjUV { ObjUV() : u(0.0), v(0.0) {} ObjUV(mreal U, mreal V) : u(U), v(V) {} mreal u; mreal v; void Set(mreal U, mreal V) { u = U; v = V; } bool operator==(const ObjUV &c) const { return u==c.u && v==c.v; } bool operator!=(const ObjUV &c) const { return !(u==c.u && v==c.v); } bool operator<(const ObjUV &c) const { if(u!=c.u) return (u texturecoords; FILE* const fp; ObjUVs(FILE *f) : fp(f) {} size_t addTextureCoords(mreal ta, mreal c, size_t ntxt) { const mreal gap = 1./512; const mreal u = 0.25+0.5*(ta*(1-2*gap)+gap); const mreal v = ((c-floor(c))*(1-2*gap) + gap + floor(c))/ntxt; const ObjUV point(u, v); std::map::iterator pPoint = texturecoords.find(point); if(pPoint!=texturecoords.end()) return pPoint->second; else { const size_t point_index = texturecoords.size()+1; texturecoords.insert(std::make_pair(point,point_index)); fprintf(fp,"vt %.15g %.15g\n",u,v); return point_index; } } }; class ObjXYZ { public : mreal x; mreal y; mreal z; ObjXYZ() : x(0), y(0), z(0) {} ObjXYZ(mreal fx, mreal fy, mreal fz) : x(fx), y(fy), z(fz) {} void Set(mreal fx, mreal fy, mreal fz) { x = fx; y = fy; z = fz; } mreal Dot(const ObjXYZ & sPt) const { return(x*sPt.x)+(y*sPt.y)+(z*sPt.z); } mreal LengthSquared() { return(x*x+y*y+z*z); } friend ObjXYZ operator + (const ObjXYZ& a, const ObjXYZ& b) { return ObjXYZ(a.x+b.x,a.y+b.y,a.z+b.z); } friend ObjXYZ operator - (const ObjXYZ& a) { return ObjXYZ(-a.x,-a.y,-a.z); } friend ObjXYZ operator - (const ObjXYZ& a, const ObjXYZ& b) { return ObjXYZ(a.x-b.x,a.y-b.y,a.z-b.z); } friend ObjXYZ operator * (const ObjXYZ& a, const mreal d) { return ObjXYZ(a.x*d,a.y*d,a.z*d); } friend ObjXYZ operator * (const mreal d, const ObjXYZ& a) { return ObjXYZ(a.x*d,a.y*d,a.z*d); } friend ObjXYZ operator / (const ObjXYZ& a, const mreal d) { return ObjXYZ(a.x/d,a.y/d,a.z/d); } friend ObjXYZ operator * (const ObjXYZ& a, const ObjXYZ& b) { return ObjXYZ((a.y*b.z)-(a.z*b.y), (a.z*b.x)-(a.x*b.z), (a.x*b.y)-(a.y*b.x)); } mreal Length() { return sqrt(x*x+y*y+z*z); } bool Normalize() { mreal fLength=Length(); if(fLength < FLT_EPSILON) return false; mreal factor=1.0/fLength; x *= factor; y *= factor; z *= factor; return true; } bool operator==(const ObjXYZ &v) const { return x==v.x && y==v.y && z==v.z; } bool operator!=(const ObjXYZ &v) const { return !(x==v.x && y==v.y && z==v.z); } bool operator<(const ObjXYZ &v) const { if(x!=v.x) return (x vertexcoords; FILE* const fp; ObjXYZs(FILE *f) : fp(f) {} size_t addVertexCoords(mreal x, mreal y, mreal z) { const ObjXYZ point(x,y,z); std::map::iterator pPoint = vertexcoords.find(point); if(pPoint!=vertexcoords.end()) return pPoint->second; else { const size_t point_index = vertexcoords.size()+1; vertexcoords.insert(std::make_pair(point,point_index)); fprintf(fp,"v %.15g %.15g %.15g\n",x,y,z); return point_index; } } }; struct ObjTriangle { size_t p1, p2, p3; size_t t1, t2, t3; ObjTriangle() : p1(0), p2(0), p3(0), t1(0), t2(0), t3(0) {} ObjTriangle(size_t P1, size_t T1, size_t P2, size_t T2, size_t P3, size_t T3) : p1(P1), p2(P2), p3(P3), t1(T1), t2(T2), t3(T3) {} }; struct ObjLine { size_t p1, p2; ObjLine() : p1(0), p2(0) {} ObjLine(size_t P1, size_t P2) : p1(P1), p2(P2) {} }; struct ObjGroup { std::deque triangles; mglColor commoncolor; bool samecolor; std::map > lines; std::map > points; FILE* const fp; ObjXYZs &vertexcoords; ObjGroup(FILE *f,ObjXYZs& v) : commoncolor(NC), samecolor(true), fp(f), vertexcoords(v) {} // const HMGL gr; // ObjGroup(const HMGL g) : samecolor(true), gr(g) {} void addSegment(size_t m, size_t p1, size_t p2) { lines[m].push_back(ObjLine(p1,p2)); } void addLines(size_t m, size_t n, const size_t* p) { for (size_t i=0; i >::const_iterator pm = lines.begin(); pm != lines.end(); pm++) { fprintf(fp,"usemtl Material%" PRIuS "\n", pm->first); for(std::deque::const_iterator pl = pm->second.begin(); pl != pm->second.end(); pl++) fprintf(fp,"l %" PRIuS " %" PRIuS "\n", pl->p1, pl->p2); } } void writePoints() { for(std::map >::const_iterator pm = points.begin(); pm != points.end(); pm++) { fprintf(fp,"usemtl Material%" PRIuS "\n", pm->first); for(std::deque::const_iterator pp = pm->second.begin(); pp != pm->second.end(); pp++) fprintf(fp,"p %" PRIuS "\n", *pp); } } void writeTriangles() { for(std::deque::const_iterator pt = triangles.begin(); pt != triangles.end(); pt++) fprintf(fp,"f %" PRIuS " %" PRIuS " %" PRIuS "\n", pt->p1, pt->p2, pt->p3); } void writeTexturedTriangles() { for(std::deque::const_iterator pt = triangles.begin(); pt != triangles.end(); pt++) fprintf(fp,"f %" PRIuS "/%" PRIuS " %" PRIuS "/%" PRIuS " %" PRIuS "/%" PRIuS "\n", pt->p1,pt->t1, pt->p2,pt->t2, pt->p3,pt->t3); } }; struct lt_mglColor { bool operator()(const mglColor& c1, const mglColor& c2) const { if(c1.r!=c2.r) return (c1.r colormap; struct ObjMaterials { colormap materialmap; FILE* const fp; ObjMaterials(FILE *f) : fp(f) {} size_t addColor(const mglColor& color) { colormap::iterator pc = materialmap.find(color); if(pc!=materialmap.end()) return pc->second; else { const size_t color_index = materialmap.size(); materialmap.insert(std::make_pair(color,color_index)); fprintf(fp,"newmtl Material%" PRIuS "\n", color_index); fprintf(fp,"Ka 0.1 0.1 0.1\n"); fprintf(fp,"Kd %g %g %g\n", color.r, color.g, color.b); fprintf(fp,"Ks 0.0 0.0 0.0\n"); fprintf(fp,"d %g\nillum 2\nNs 15.0\n",color.a); return color_index; } } size_t addColor(mreal r, mreal g, mreal b, mreal a) { const mglColor color(r,g,b,a); return addColor(color); } size_t addColorInfo(const mglPnt& p) { return addColor(p.r,p.g,p.b,p.a); } }; size_t MGL_LOCAL_CONST power_of_two(size_t input) { size_t value = 1; while ( value < input ) value <<= 1; return value; } void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int use_png) { mglCanvas *gg = dynamic_cast(gr); if(!gg || gr->GetPrmNum()==0) return; // nothing to do { long mmin=0,mmax=0,m; for(size_t i=0;iGrp.size();i++) // prepare array of indirect indexing { m = gr->Grp[i].Id; if(mmmax) mmax=m; } long *ng = new long[mmax-mmin+1]; for(size_t i=0;iGrp.size();i++) ng[gr->Grp[i].Id-mmin] = i; for(size_t i=0;iGetPrmNum());i++) // collect data for groups // it is rather expensive (extra 4b per primitive) but need for export to 3D { m = gr->GetPrm(i,false).id-mmin; if(m>=0 && mGrp[ng[m]].p.push_back(i); } delete []ng; } const size_t len=strlen(fname); const size_t ntxt=gr->GetTxtNum(); const size_t Ntxt=power_of_two(ntxt); const size_t pntnum = gr->GetPntNum(); char *tname = new char[len+5]; strcpy(tname,fname); FILE *fp=fopen(fname,"wt"); ObjXYZs vertexcoords(fp); std::vector vcs(pntnum); // vertex coord ids ObjUVs texturecoords(fp); std::vector tcs(pntnum); // texture coord ids // center point mglPnt p0; const mreal width = gg->GetWidth(); const mreal height = gg->GetHeight(); const mreal depth = sqrt(width*height); p0.x = width/2.; p0.y = height/2.; p0.z = (1.f-sqrt(width*height)/(2*depth))*depth; // vertices definition fprintf(fp,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); for(size_t i=0;iGetPnt(i); vcs[i] = vertexcoords.addVertexCoords(pp.x-p0.x, pp.y-p0.y, pp.z-p0.z); tcs[i] = texturecoords.addTextureCoords(pp.ta, pp.c, Ntxt); } // prepare MTL file tname[len-4]='.'; tname[len-3]='m'; tname[len-2]='t'; tname[len-1]='l'; FILE *fpmat=fopen(tname,"wt"); tname[len-4]='\0'; fprintf(fpmat,"newmtl Material\n"); fprintf(fpmat,"Ka 0.0 0.0 0.0\n"); fprintf(fpmat,"Kd 1.0 1.0 1.0\n"); fprintf(fpmat,"Ks 0.0 0.0 0.0\n"); fprintf(fpmat,"d 1.0\nillum 2\n"); if(use_png) fprintf(fpmat,"map_Kd %s_txt.png\n",tname); else fprintf(fpmat,"map_Kd %s_txt.tga\n",tname); if(use_png) strcat(tname,"_txt.png"); else strcat(tname,"_txt.tga"); // prepare texture file (TGA or PNG) const size_t txtwidth = 512; unsigned char *buf = new unsigned char[4*256*txtwidth*Ntxt]; unsigned char **pbuf= (unsigned char **)malloc(256*Ntxt*sizeof(unsigned char *)); for(size_t i=0;i<256*Ntxt;i++) pbuf[i] = buf+4*txtwidth*i; for(size_t i=0;iGetTxt(i).GetRGBAOBJ(buf+(Ntxt-1-i)*256*txtwidth*4); for(size_t i=ntxt;iGrp.size();i++) { std::vector &p = gr->Grp[i].p; ObjGroup grp(fp, vertexcoords); for(size_t j=0;jGetPrm(p[j],false); long n1=q.n1,n2=q.n2,n3=q.n3,n4=q.n4; switch(q.type) { case 0: if (gr->GetPnt(q.n1).a > mgl_min_a) { const mglPnt p = gr->GetPnt(q.n1) - p0; const mreal size = q.s; const char type = q.n4; mreal ss=size; const mglColor c(p.r, p.g, p.b, p.a); if(!strchr("xsSoO",type)) ss *= 1.1; if(type=='.' || ss==0) { const size_t m = materials.addColor(c); grp.addPoint(m, vcs[n1]); } else switch(type) { case 'P': { const size_t m = materials.addColor(c); const mreal P[5][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z }, { p.x-ss,p.y+ss,p.z }, { p.x-ss,p.y-ss,p.z } }; grp.addLines(m, 5, P); } case '+': { const size_t m = materials.addColor(c); const mreal P1[2][3] = { { p.x-ss,p.y,p.z }, { p.x+ss,p.y,p.z } }; grp.addLines(m, 2, P1); const mreal P2[2][3] = { { p.x,p.y-ss,p.z }, { p.x,p.y+ss,p.z } }; grp.addLines(m, 2, P2); } break; case 'X': { const size_t m = materials.addColor(c); const mreal P[5][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z }, { p.x-ss,p.y+ss,p.z }, { p.x-ss,p.y-ss,p.z } }; grp.addLines(m, 5, P); const mreal P1[2][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z } }; grp.addLines(m, 2, P1); const mreal P2[2][3] = { { p.x+ss,p.y-ss,p.z }, { p.x-ss,p.y+ss,p.z } }; grp.addLines(m, 2, P2); } break; case 'x': { const size_t m = materials.addColor(c); const mreal P1[2][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z } }; grp.addLines(m, 2, P1); const mreal P2[2][3] = { { p.x+ss,p.y-ss,p.z }, { p.x-ss,p.y+ss,p.z } }; grp.addLines(m, 2, P2); } break; case 'S': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t pi1 = vertexcoords.addVertexCoords(p.x-ss,p.y-ss,p.z); const size_t pi2 = vertexcoords.addVertexCoords(p.x+ss,p.y-ss,p.z); const size_t pi3 = vertexcoords.addVertexCoords(p.x-ss,p.y+ss,p.z); const size_t pi4 = vertexcoords.addVertexCoords(p.x+ss,p.y+ss,p.z); grp.addTriangle(pi1, ti, pi2, ti, pi3, ti); grp.addTriangle(pi4, ti, pi3, ti, pi2, ti); } break; case 's': { const size_t m = materials.addColor(c); const mreal P[5][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z }, { p.x-ss,p.y+ss,p.z }, { p.x-ss,p.y-ss,p.z } }; grp.addLines(m, 5, P); } break; case 'D': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t pi1 = vertexcoords.addVertexCoords(p.x,p.y-ss,p.z); const size_t pi2 = vertexcoords.addVertexCoords(p.x+ss,p.y,p.z); const size_t pi3 = vertexcoords.addVertexCoords(p.x-ss,p.y,p.z); const size_t pi4 = vertexcoords.addVertexCoords(p.x,p.y+ss,p.z); grp.addTriangle(pi1, ti, pi2, ti, pi3, ti); grp.addTriangle(pi4, ti, pi3, ti, pi2, ti); } break; case 'd': { const size_t m = materials.addColor(c); const mreal P[5][3] = { { p.x,p.y-ss,p.z }, { p.x+ss,p.y,p.z }, { p.x,p.y+ss,p.z }, { p.x-ss,p.y,p.z }, { p.x,p.y-ss,p.z } }; grp.addLines(m, 5, P); } break; case 'Y': { const size_t m = materials.addColor(c); const mreal P1[3][3] = { { p.x, p.y-ss, p.z }, { p.x, p.y, p.z }, { p.x+0.8*ss,p.y+0.6*ss,p.z } }; grp.addLines(m, 3, P1); const mreal P2[2][3] = { { p.x, p.y, p.z }, { p.x-0.8*ss,p.y+0.6*ss,p.z } }; grp.addLines(m, 2, P2); } break; case '*': { const size_t m = materials.addColor(c); const mreal P1[2][3] = { { p.x-ss,p.y,p.z }, { p.x+ss,p.y,p.z } }; grp.addLines(m, 2, P1); const mreal P2[2][3] = { { p.x-0.6*ss,p.y-0.8*ss,p.z }, { p.x+0.6*ss,p.y+0.8*ss,p.z } }; grp.addLines(m, 2, P2); const mreal P3[2][3] = { { p.x-0.6*ss,p.y+0.8*ss,p.z }, { p.x+0.6*ss,p.y-0.8*ss,p.z } }; grp.addLines(m, 2, P3); } break; case 'T': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t pi1 = vertexcoords.addVertexCoords(p.x-ss,p.y-ss/2,p.z); const size_t pi2 = vertexcoords.addVertexCoords(p.x+ss,p.y-ss/2,p.z); const size_t pi3 = vertexcoords.addVertexCoords(p.x,p.y+ss,p.z); grp.addTriangle(pi1, ti, pi2, ti, pi3, ti); } break; case '^': { const size_t m = materials.addColor(c); const mreal P[4][3] = { { p.x-ss,p.y-ss/2,p.z }, { p.x+ss,p.y-ss/2,p.z }, { p.x, p.y+ss, p.z }, { p.x-ss,p.y-ss/2,p.z } }; grp.addLines(m, 4, P); } break; case 'V': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t pi1 = vertexcoords.addVertexCoords(p.x-ss,p.y+ss/2,p.z); const size_t pi2 = vertexcoords.addVertexCoords(p.x,p.y-ss,p.z); const size_t pi3 = vertexcoords.addVertexCoords(p.x+ss,p.y+ss/2,p.z); grp.addTriangle(pi1, ti, pi2, ti, pi3, ti); } break; case 'v': { const size_t m = materials.addColor(c); const mreal P[4][3] = { { p.x-ss,p.y+ss/2,p.z }, { p.x+ss,p.y+ss/2,p.z }, { p.x, p.y-ss, p.z }, { p.x-ss,p.y+ss/2,p.z } }; grp.addLines(m, 4, P); } break; case 'L': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t pi1 = vertexcoords.addVertexCoords(p.x+ss/2,p.y+ss,p.z); const size_t pi2 = vertexcoords.addVertexCoords(p.x-ss, p.y, p.z); const size_t pi3 = vertexcoords.addVertexCoords(p.x+ss/2,p.y-ss,p.z); grp.addTriangle(pi1, ti, pi2, ti, pi3, ti); } break; case '<': { const size_t m = materials.addColor(c); const mreal P[4][3] = { { p.x+ss/2,p.y+ss,p.z }, { p.x+ss/2,p.y-ss,p.z }, { p.x-ss, p.y, p.z }, { p.x+ss/2,p.y+ss,p.z } }; grp.addLines(m, 4, P); } break; case 'R': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t pi1 = vertexcoords.addVertexCoords(p.x-ss/2,p.y+ss,p.z); const size_t pi2 = vertexcoords.addVertexCoords(p.x-ss/2,p.y-ss,p.z); const size_t pi3 = vertexcoords.addVertexCoords(p.x+ss, p.y, p.z); grp.addTriangle(pi1, ti, pi2, ti, pi3, ti); } break; case '>': { const size_t m = materials.addColor(c); const mreal P[4][3] = { { p.x-ss/2,p.y+ss,p.z }, { p.x-ss/2,p.y-ss,p.z }, { p.x+ss, p.y, p.z }, { p.x-ss/2,p.y+ss,p.z } }; grp.addLines(m, 4, P); } break; case 'O': { const size_t ti = tcs[n1]; grp.addColourInfo(p); const size_t cpi=vertexcoords.addVertexCoords(p.x, p.y, p.z); size_t pnti[21]; for(size_t k=0;k<=20;k++) pnti[k]=vertexcoords.addVertexCoords(p.x+ss*cos(k*M_PI/10),p.y+ss*sin(k*M_PI/10),p.z); for(size_t k=0;k<20;k++) { grp.addTriangle(pnti[k], ti, pnti[k+1], ti, cpi, ti); } } break; case 'C': { const size_t m = materials.addColor(c); grp.addPoint(m, vcs[n1]); } case 'o': { const size_t m = materials.addColor(c); mreal P[21][3]; for(size_t k=0;k<=20;k++) { P[k][0] = p.x+ss*cos(k*M_PI/10); P[k][1] = p.y+ss*sin(k*M_PI/10); P[k][2] = p.z; } grp.addLines(m, 21, P); } break; } } break; case 1: if (gr->GetPnt(q.n1).a > mgl_min_a || gr->GetPnt(q.n2).a > mgl_min_a) { const mglPnt& p1 = gr->GetPnt(q.n1); const mglPnt& p2 = gr->GetPnt(q.n2); const size_t m = materials.addColor((p1.r+p2.r)/2, (p1.g+p2.g)/2, (p1.b+p2.b)/2, (p1.a+p2.a)/2); grp.addSegment(m, vcs[n1], vcs[n2]); } break; case 2: if (gr->GetPnt(q.n1).a > mgl_min_a || gr->GetPnt(q.n2).a > mgl_min_a || gr->GetPnt(q.n3).a > mgl_min_a) { grp.addTriangle(vcs[n1],tcs[n1], vcs[n2],tcs[n2], vcs[n3],tcs[n3]); grp.addColourInfo(gr->GetPnt(n1)); grp.addColourInfo(gr->GetPnt(n2)); grp.addColourInfo(gr->GetPnt(n3)); } break; case 3: if (gr->GetPnt(q.n1).a > mgl_min_a || gr->GetPnt(q.n2).a > mgl_min_a || gr->GetPnt(q.n3).a > mgl_min_a || gr->GetPnt(q.n4).a > mgl_min_a) { grp.addTriangle(vcs[n1],tcs[n1], vcs[n2],tcs[n2], vcs[n3],tcs[n3]); grp.addTriangle(vcs[n2],tcs[n2], vcs[n4],tcs[n4], vcs[n3],tcs[n3]); grp.addColourInfo(gr->GetPnt(n1)); grp.addColourInfo(gr->GetPnt(n2)); grp.addColourInfo(gr->GetPnt(n3)); grp.addColourInfo(gr->GetPnt(n4)); } break; case 4: { const mglPnt p = gr->GetPnt(q.n1) - p0; const mreal f = q.p/2, dx=p.u/2, dy=p.v/2; const mreal c=q.s*cos(q.w*M_PI/180), s=-q.s*sin(q.w*M_PI/180); const double b[4] = {c,-s, s,c}; long ik,il=0; const mglGlyph &g = gr->GetGlf(q.n4); const mreal dd = 0.004; if(q.n3&8) { const size_t p_4 = vertexcoords.addVertexCoords(p.x+b[0]*dx+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z); const size_t p_3 = vertexcoords.addVertexCoords(p.x+b[0]*dx+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z); const size_t p_2 = vertexcoords.addVertexCoords(p.x+b[0]*(dx+f)+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z); const size_t p_1 = vertexcoords.addVertexCoords(p.x+b[0]*(dx+f)+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z); if(!(q.n3&4)) // glyph_line(p,f,true, d); { const size_t ti = tcs[n1]; grp.addColourInfo(p); grp.addMonoTriangle(ti, p_1, p_3, p_2); grp.addMonoTriangle(ti, p_4, p_2, p_3); } else // glyph_line(p,f,false, d); { const size_t m = materials.addColor(p.r, p.g, p.b, p.a); grp.addSegment(m, p_1, p_2); grp.addSegment(m, p_3, p_4); grp.addSegment(m, p_1, p_3); grp.addSegment(m, p_2, p_4); } } else { if(!(q.n3&4)) // glyph_fill(p,f,g, d); { for(ik=0;ikGrp[i].Lbl.c_str()); if (!grp.triangles.empty()) { if (grp.samecolor) { fprintf(fp,"usemtl Material%" PRIuS "\n", materials.addColor(grp.commoncolor)); grp.writeTriangles(); } else { fprintf(fp,"usemtl Material\n"); grp.writeTexturedTriangles(); } } grp.writeLines(); grp.writePoints(); gr->Grp[i].p.clear(); // we don't need indexes anymore } fclose(fp); fclose(fpmat); delete []tname; } void MGL_EXPORT mgl_write_obj_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]='\0'; char *d=new char[n+1]; memcpy(d,descr,n); d[n]='\0'; mgl_write_obj(_GR_,s,d,*use_png); delete []s; delete []d; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/complex_io.cpp0000644000175000017500000010276113513030041016605 0ustar alastairalastair/*************************************************************************** * data_io.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #ifndef WIN32 #include #endif #include "mgl2/datac.h" #include "mgl2/evalc.h" #include "mgl2/thread.h" #if MGL_HAVE_HDF5 #define H5_USE_16_API #include #endif inline bool isn(char ch) {return ch=='\n';} MGL_NO_EXPORT char *mgl_read_gz(gzFile fp); HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector &head); //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_create_datac() { return new mglDataC; } HADT MGL_EXPORT mgl_create_datac_size(long nx, long ny, long nz){ return new mglDataC(nx,ny,nz); } HADT MGL_EXPORT mgl_create_datac_file(const char *fname) { return new mglDataC(fname); } void MGL_EXPORT mgl_delete_datac(HADT d) { if(d) delete d; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_create_datac_() { return uintptr_t(new mglDataC()); } uintptr_t MGL_EXPORT mgl_create_datac_size_(int *nx, int *ny, int *nz) { return uintptr_t(new mglDataC(*nx,*ny,*nz)); } uintptr_t MGL_EXPORT mgl_create_datac_file_(const char *fname,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; uintptr_t r = uintptr_t(new mglDataC(s)); delete []s; return r; } void MGL_EXPORT mgl_delete_datac_(uintptr_t *d) { if(_DC_) delete _DC_; } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_atoc(const char *s, int adv) { double re=0,im=0; size_t ll=strlen(s); while(s[ll]<=' ') ll--; if(adv && *s=='(') sscanf(s,"(%lg,%lg)",&re,&im); else if(*s=='i') { re=0; im=atof(s+1); } else if(adv && *s=='[') sscanf(s,"[%lg,%lg]",&re,&im); else if(adv && *s=='{') sscanf(s,"{%lg,%lg}",&re,&im); else if(s[ll]=='i') { double a,b; //s[ll] = 0; int s1=sscanf(s,"%lg+%lg",&re,&im); int s2=sscanf(s,"%lg-%lg",&a,&b); if(s1<2) { if(s2==2) { re=a; im=-b; } else { im=atof(s); re=0; } } } else { double a,b; int s1=sscanf(s,"%lg+i%lg",&re,&im); int s2=sscanf(s,"%lg-i%lg",&a,&b); if(s1<2) { if(s2==2) { re=a; im=-b; } else { re=atof(s); im=0; } } } return mdual(re,im); } //----------------------------------------------------------------------------- void mglFromStr(HADT d,char *buf,long NX,long NY,long NZ) { if(NX<1 || NY <1 || NZ<1) return; mgl_datac_create(d, NX,NY,NZ); const std::string loc = setlocale(LC_NUMERIC, "C"); std::vector lines; std::vector > numbs; while(*buf && *buf<=' ') buf++; lines.push_back(buf); for(char *s=buf; *s; s++) if(isn(*s)) { lines.push_back(s+1); *s = 0; s++; } numbs.resize(lines.size()); long nl = long(lines.size()); #pragma omp parallel for for(long k=0;k=nb) break; if(b[j]=='#') { std::string id; if(j='a' && b[i]<='z') id.push_back(b[i]); d->SetColumnId(id.c_str()); break; } char *s=b+j; long sk=0; while(j' ' && ((b[j]!=',' && b[j]!=' ') || sk!=0) && b[j]!=';') { if(strchr("[{(",b[j])) sk++; if(strchr("]})",b[j])) sk--; j++; } b[j]=0; numbs[k].push_back(mgl_atoc(s,true)); } } long i=0, n=NX*NY*NZ; for(long k=0;k &vals = numbs[k]; long c = vals.size(); if(c>n-i) c = n-i; memcpy(d->a+i,&(vals[0]),c*sizeof(dual)); i += c; } setlocale(LC_NUMERIC, loc.c_str()); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set(HADT d, HCDT a) { if(!a) return; const mglDataC *dd = dynamic_cast(a); // faster for mglData mgl_datac_create(d, a->GetNx(), a->GetNy(), a->GetNz()); if(dd) // this one should be much faster memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(dual)); else // very inefficient!!! { for(long k=0;knz;k++) for(long j=0;jny;j++) for(long i=0;inx;i++) d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k); } } void MGL_EXPORT mgl_datac_set_(uintptr_t *d, uintptr_t *a) { mgl_datac_set(_DC_,_DA_(a)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_values(HADT d, const char *v,long NX,long NY,long NZ) { if(NX<1 || NY <1 || NZ<1) return; long n=strlen(v)+1; char *buf = new char[n]; memcpy(buf,v,n); mglFromStr(d,buf,NX,NY,NZ); delete []buf; } void MGL_EXPORT mgl_datac_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l) { char *s=new char[l+1]; memcpy(s,val,l); s[l]=0; mgl_datac_set_values(_DC_,s,*nx,*ny,*nz); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_vector(HADT d, gsl_vector *v) { #if MGL_HAVE_GSL if(!v || v->size<1) return; mgl_datac_create(d, v->size,1,1); for(long i=0;inx;i++) d->a[i] = v->data[i*v->stride]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_matrix(HADT d, gsl_matrix *m) { #if MGL_HAVE_GSL if(!m || m->size1<1 || m->size2<1) return; mgl_datac_create(d, m->size1,m->size2,1); for(long j=0;jny;j++) for(long i=0;inx;i++) d->a[i+j*d->nx] = m->data[i * m->tda + j]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_float(HADT d, const float *A,long NX,long NY,long NZ) { if(NX<=0 || NY<=0 || NZ<=0) return; mgl_datac_create(d, NX,NY,NZ); if(!A) return; #pragma omp parallel for for(long i=0;ia[i] = A[i]; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_double(HADT d, const double *A,long NX,long NY,long NZ) { if(NX<=0 || NY<=0 || NZ<=0) return; mgl_datac_create(d, NX,NY,NZ); if(!A) return; #pragma omp parallel for for(long i=0;ia[i] = A[i]; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_complex(HADT d, const mdual *A,long NX,long NY,long NZ) { if(NX<=0 || NY<=0 || NZ<=0) return; mgl_datac_create(d, NX,NY,NZ); if(!A) return; memcpy(d->a,reinterpret_cast(A),NX*NY*NZ*sizeof(float)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_float_(uintptr_t *d, const float *A,int *NX,int *NY,int *NZ) { mgl_datac_set_float(_DC_,A,*NX,*NY,*NZ); } void MGL_EXPORT mgl_datac_set_double_(uintptr_t *d, const double *A,int *NX,int *NY,int *NZ) { mgl_datac_set_double(_DC_,A,*NX,*NY,*NZ); } void MGL_EXPORT mgl_datac_set_complex_(uintptr_t *d, const mdual *A,int *NX,int *NY,int *NZ) { mgl_datac_set_complex(_DC_,A,*NX,*NY,*NZ); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_rearrange(HADT d, long mx,long my,long mz) { if(mx<1) return; // wrong mx if(my<1) { my = d->nx*d->ny*d->nz/mx; mz = 1; } else if(mz<1) mz = (d->nx*d->ny*d->nz)/(mx*my); long m = mx*my*mz; if(m==0 || m>d->nx*d->ny*d->nz) return; // too high desired dimensions d->nx = mx; d->ny = my; d->nz = mz; d->NewId(); } void MGL_EXPORT mgl_datac_rearrange_(uintptr_t *d, int *mx, int *my, int *mz) { mgl_datac_rearrange(_DC_,*mx,*my,*mz); } //----------------------------------------------------------------------------- std::string MGL_EXPORT mgl_datac_to_string(HCDT d, long ns) { std::string out; const mglDataC *dd = dynamic_cast(d); if(!dd) { return mgl_data_to_string(d,ns); } long nx=dd->nx, ny=dd->ny, nz=dd->nz; const std::string loc = setlocale(LC_NUMERIC, "C"); if(ns<0 || (ns>=nz && nz>1)) for(long k=0;k(d); if(dc) { std::string id = dc->GetColumnId(); if(!id.empty()) out += "## "+id+'\n'; } for(long i=0;ia[j+nx*(i+ny*k)])+'\t'; out+=mgl_str_num(dd->a[nx-1+nx*(i+ny*k)])+'\n'; } out += "\n"; } else { // save selected slice if(nz>1) for(long i=0;ia[j+nx*(i+ny*ns)])+'\t'; out+=mgl_str_num(dd->a[nx-1+nx*(i+ny*ns)])+'\n'; } else if(nsa[j+nx*ns])+'\t'; } setlocale(LC_NUMERIC, loc.c_str()); return out; } void MGL_EXPORT mgl_datac_save(HCDT d, const char *fname,long ns) { FILE *fp = fopen(fname,"w"); if(fp) { fprintf(fp,"%s",mgl_datac_to_string(d,ns).c_str()); fclose(fp); } } void MGL_EXPORT mgl_datac_save_(uintptr_t *d, const char *fname,int *ns,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; mgl_datac_save(_DC_,s,*ns); delete []s; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read(HADT d, const char *fname) { long l=1,m=1,k=1,sk=0; long nb,i; gzFile fp = gzopen(fname,"r"); if(!fp) { if(!d->a) mgl_datac_create(d, 1,1,1); return 0; } char *buf = mgl_read_gz(fp), *tbuf=buf; while(*buf && *buf<=' ') buf++; // remove leading spaces nb = strlen(buf); gzclose(fp); bool first=false; // space is not allowed delimiter for file with complex numbers for(i=nb-1;i>=0;i--) if(buf[i]>' ') break; buf[i+1]=0; nb = i+1; // remove tailing spaces for(i=0;i' ' && !first) first=true; if(strchr("[{(",ch)) sk++; if(strchr("]})",ch)) sk--; if(first && buf[i+1]>' ' && (ch=='\t' || ch==';' || ((ch==' '||ch==',') && sk==0) )) k++; } first = false; for(i=0;inx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1; if(d->a && !d->link) delete [](d->a); d->a = new dual[d->nx*d->ny*d->nz]; d->NewId(); d->link=false; memset(d->a,0,d->nx*d->ny*d->nz*sizeof(dual)); } void MGL_EXPORT mgl_datac_create_(uintptr_t *d, int *nx,int *ny,int *nz) { mgl_datac_create(_DC_,*nx,*ny,*nz); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_link(HADT d, mdual *A, long mx,long my,long mz) { if(!A) return; if(!d->link && d->a) delete [](d->a); d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1; d->link=true; d->a=reinterpret_cast(A); d->NewId(); } void MGL_EXPORT mgl_datac_link_(uintptr_t *d, mdual *A, int *nx,int *ny,int *nz) { mgl_datac_link(_DC_,A,*nx,*ny,*nz); } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read_dim(HADT d, const char *fname,long mx,long my,long mz) { if(mx<=0 || my<=0 || mz<=0) return 0; gzFile fp = gzopen(fname,"r"); if(!fp) return 0; char *buf = mgl_read_gz(fp); gzclose(fp); mglFromStr(d,buf,mx,my,mz); free(buf); return 1; } int MGL_EXPORT mgl_datac_read_dim_(uintptr_t *d, const char *fname,int *mx,int *my,int *mz,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; int r = mgl_datac_read_dim(_DC_,s,*mx,*my,*mz); delete []s; return r; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read_mat(HADT d, const char *fname, long dim) { if(dim<=0 || dim>3) return 0; gzFile fp = gzopen(fname,"r"); if(!fp) return 0; long nx=1, ny=1, nz=1; char *buf = mgl_read_gz(fp); long nb = strlen(buf); gzclose(fp); long j=0; if(buf[j]=='#') while(!isn(buf[j])) j++; // skip comment while(j' ') j++; } else if(dim==2) { sscanf(buf+j,"%ld%ld",&nx,&ny); while(j' ' && !first) first=true; if(first && (ch=='\t' || ch==';') && b[i+1]!='\t') nx++; } } } else if(dim==3) { sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz); while(jp[0],ny=t->p[1]; dual *b=t->a, x1=t->b[0], dx=t->b[1]; char dir = t->s[0]; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { if(dir=='x') b[i0] = x1+dx*mreal(i0%nx); else if(dir=='y') b[i0] = x1+dx*mreal((i0/nx)%ny); else if(dir=='z') b[i0] = x1+dx*mreal(i0/(nx*ny)); } return 0; } void MGL_EXPORT mgl_datac_fill(HADT d, mdual x1, mdual x2,char dir) { if(mgl_isnan(x2)) x2=x1; if(dir<'x' || dir>'z') dir='x'; long par[2]={d->nx,d->ny}; dual b[2]={x1,dual(x2)-dual(x1)}; if(dir=='x') b[1] *= d->nx>1 ? 1./(d->nx-1):0; if(dir=='y') b[1] *= d->ny>1 ? 1./(d->ny-1):0; if(dir=='z') b[1] *= d->nz>1 ? 1./(d->nz-1):0; mglStartThreadC(mgl_cfill_x,0,d->nx*d->ny*d->nz,d->a,b,0,par,0,0,0,&dir); } void MGL_EXPORT mgl_datac_fill_(uintptr_t *d, mdual *x1, mdual *x2, const char *dir,int) { mgl_datac_fill(_DC_,*x1,*x2,*dir); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_squeeze(HADT d, long rx,long ry,long rz,long smooth) { long kx,ky,kz, nx=d->nx, ny=d->ny, nz=d->nz; dual *b; // simple checking if(rx>=nx) rx=nx-1; if(rx<1) rx=1; if(ry>=ny) ry=ny-1; if(ry<1) ry=1; if(rz>=nz) rz=nz-1; if(rz<1) rz=1; // new sizes kx = 1+(nx-1)/rx; ky = 1+(ny-1)/ry; kz = 1+(nz-1)/rz; b = new dual[kx*ky*kz]; if(!smooth) #pragma omp parallel for collapse(3) for(long k=0;ka[i*rx+nx*(j*ry+ny*rz*k)]; else #pragma omp parallel for collapse(3) for(long k=0;ka[i1+nx*(j1+ny*k1)]; b[i+kx*(j+ky*k)] = s/mreal(dx*dy*dz); } if(!d->link) delete [](d->a); d->a=b; d->nx = kx; d->ny = ky; d->nz = kz; d->NewId(); d->link=false; } void MGL_EXPORT mgl_datac_squeeze_(uintptr_t *d, int *rx,int *ry,int *rz,int *smooth) { mgl_datac_squeeze(_DC_,*rx,*ry,*rz,*smooth); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_extend(HADT d, long n1, long n2) { long nx=d->nx, ny=d->ny, nz=d->nz; if(nz>2 || n1==0) return; long mx, my, mz; dual *b=0; if(n1>0) // extend to higher dimension(s) { n2 = n2>0 ? n2:1; mx = nx; my = ny>1?ny:n1; mz = ny>1 ? n1 : n2; b = new dual[mx*my*mz]; if(ny>1) #pragma omp parallel for for(long i=0;ia, nx*ny*sizeof(dual)); else #pragma omp parallel for for(long i=0;ia, nx*sizeof(dual)); } else { mx = -n1; my = n2<0 ? -n2 : nx; mz = n2<0 ? nx : ny; if(n2>0 && ny==1) mz = n2; b = new dual[mx*my*mz]; if(n2<0) #pragma omp parallel for collapse(2) for(long j=0;ja[j]; else #pragma omp parallel for collapse(2) for(long j=0;ja[j]; if(n2>0 && ny==1) #pragma omp parallel for for(long i=0;ia, mx*my*sizeof(dual)); } if(!d->link) delete [](d->a); d->a=b; d->nx=mx; d->ny=my; d->nz=mz; d->NewId(); d->link=false; } void MGL_EXPORT mgl_datac_extend_(uintptr_t *d, int *n1, int *n2) { mgl_datac_extend(_DC_,*n1,*n2); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_transpose(HADT d, const char *dim) { long nx=d->nx, ny=d->ny, nz=d->nz, n; dual *b=new dual[nx*ny*nz], *a=d->a; if(!strcmp(dim,"xyz")) memcpy(b,a,nx*ny*nz*sizeof(dual)); else if(!strcmp(dim,"xzy") || !strcmp(dim,"zy")) { #pragma omp parallel for collapse(3) for(long j=0;jnx; d->nx=nx; d->ny=ny; d->nz=nz; if(nx!=n) d->NewId(); } void MGL_EXPORT mgl_datac_transpose_(uintptr_t *d, const char *dim,int l) { char *s=new char[l+1]; memcpy(s,dim,l); s[l]=0; mgl_datac_transpose(_DC_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_cmodify(void *par) { mglThreadC *t=(mglThreadC *)par; const mglFormulaC *f = (const mglFormulaC *)(t->v); long nx=t->p[0],ny=t->p[1],nz=t->p[2]; dual *b=t->a; mreal dx,dy,dz; const dual *v=t->b, *w=t->c; dx=nx>1?1/(nx-1.):0; dy=ny>1?1/(ny-1.):0; dz=nz>1?1/(nz-1.):0; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny); b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v[i0]:dual(0,0), w?w[i0]:dual(0,0)); } return 0; } void MGL_EXPORT mgl_datac_modify(HADT d, const char *eq,long dim) { long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz}; if(dim<=0) mgl_datac_modify_vw(d,eq,0,0); // fastest variant for whole array mglFormulaC f(eq); if(nz>1) // 3D array { par[2] -= dim; if(par[2]<0) par[2]=0; mglStartThreadC(mgl_cmodify,0,nx*ny*par[2],d->a+nx*ny*dim,0,0,par,&f); } else // 2D or 1D array { par[1] -= dim; if(par[1]<0) par[1]=0; mglStartThreadC(mgl_cmodify,0,nx*par[1],d->a+nx*dim,0,0,par,&f); } } void MGL_EXPORT mgl_datac_modify_(uintptr_t *d, const char *eq,int *dim,int l) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; mgl_datac_modify(_DC_,s,*dim); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_modify_vw(HADT d, const char *eq,HCDT vdat,HCDT wdat) { std::wstring s = d->Name(); d->Name(L"u"); mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.Name(L"x"); mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.Name(L"y"); mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.Name(L"z"); mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i"); mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j"); mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k"); mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl"); mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w"); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(d); list.push_back(&v); list.push_back(&w); list.push_back(&r); list.push_back(&i); list.push_back(&j); list.push_back(&k); d->Move(mglFormulaCalcC(eq,list)); d->Name(s.c_str()); } void MGL_EXPORT mgl_datac_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; mgl_datac_modify_vw(_DC_,s,_DA_(v),_DA_(w)); delete []s; } //----------------------------------------------------------------------------- static bool mgl_add_file(long &kx,long &ky, long &kz, dual *&b, mglDataC *d,bool as_slice) { if(as_slice && d->nz==1) { if(kx==d->nx && d->ny==1) { b = (dual *)realloc(b,kx*(ky+1)*sizeof(dual)); memcpy(b+kx*ky,d->a,kx*sizeof(dual)); ky++; } else if(kx==d->nx && ky==d->ny) { b = (dual *)realloc(b,kx*ky*(kz+1)*sizeof(dual)); memcpy(b+kx*ky*kz,d->a,kx*ky*sizeof(dual)); kz++; } else return false; } else { if(d->ny*d->nz==1 && ky*kz==1) { b = (dual *)realloc(b,(kx+d->nx)*sizeof(dual)); memcpy(b+kx,d->a,d->nx*sizeof(dual)); kx+=d->nx; } else if(kx==d->nx && kz==1 && d->nz==1) { b = (dual *)realloc(b,kx*(ky+d->ny)*sizeof(dual)); memcpy(b+kx*ky,d->a,kx*d->ny*sizeof(dual)); ky+=d->ny; } else if(kx==d->nx && ky==d->ny) { b = (dual *)realloc(b,kx*kx*(kz+d->nz)*sizeof(dual)); memcpy(b+kx*ky*kz,d->a,kx*ky*d->nz*sizeof(dual)); kz+=d->nz; } else return false; } return true; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read_range(HADT dat, const char *templ, double from, double to, double step, int as_slice) { mglDataC d; double t = from; dual *b; long kx,ky,kz,n=strlen(templ)+20; char *fname = new char[n]; //read first file do{ snprintf(fname,n,templ,t); fname[n-1]=0; t+= step; } while(!mgl_datac_read(&d,fname) && t<=to); if(t>to) { delete []fname; return 0; } kx = d.nx; ky = d.ny; kz = d.nz; b = (dual *)malloc(kx*ky*kz*sizeof(dual)); memcpy(b,d.a,kx*ky*kz*sizeof(dual)); // read other files for(;t<=to;t+=step) { snprintf(fname,n,templ,t); fname[n-1]=0; if(mgl_datac_read(&d,fname)) if(!mgl_add_file(kx,ky,kz,b,&d,as_slice)) { delete []fname; free(b); return 0; } } dat->Set(b,kx,ky,kz); delete []fname; free(b); return 1; } int MGL_EXPORT mgl_datac_read_range_(uintptr_t *d, const char *fname, mreal *from, mreal *to, mreal *step, int *as_slice,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; int r = mgl_datac_read_range(_DC_,s,*from,*to,*step,*as_slice); delete []s; return r; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read_all(HADT dat, const char *templ, int as_slice) { #ifndef WIN32 mglDataC d; glob_t res; size_t i; dual *b; long kx,ky,kz; glob (templ, GLOB_TILDE, NULL, &res); //read first file for(i=0;i=res.gl_pathc) { globfree (&res); return 0; } kx = d.nx; ky = d.ny; kz = d.nz; b = (dual *)malloc(kx*ky*kz*sizeof(dual)); memcpy(b,d.a,kx*ky*kz*sizeof(dual)); for(;iSet(b,kx,ky,kz); globfree (&res); free(b); return 1; #else return 0; #endif } int MGL_EXPORT mgl_datac_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; int r = mgl_datac_read_all(_DC_,s,*as_slice); delete []s; return r; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_real(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast(d); if(dd) #pragma omp parallel for for(long i=0;ia[i] = real(dd->a[i]); else r->Set(d); return r; } uintptr_t MGL_EXPORT mgl_datac_real_(uintptr_t *d) { return uintptr_t(mgl_datac_real(_DC_)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_imag(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast(d); if(dd) #pragma omp parallel for for(long i=0;ia[i] = imag(dd->a[i]); return r; } uintptr_t MGL_EXPORT mgl_datac_imag_(uintptr_t *d) { return uintptr_t(mgl_datac_imag(_DC_)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_norm(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast(d); if(dd) #pragma omp parallel for for(long i=0;ia[i] = norm(dd->a[i]); else #pragma omp parallel for for(long i=0;ia[i] = mgl_ipow(d->vthr(i),2); return r; } uintptr_t MGL_EXPORT mgl_datac_norm_(uintptr_t *d) { return uintptr_t(mgl_datac_norm(_DC_)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_abs(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast(d); if(dd) #pragma omp parallel for for(long i=0;ia[i] = abs(dd->a[i]); else #pragma omp parallel for for(long i=0;ia[i] = fabs(d->vthr(i)); return r; } uintptr_t MGL_EXPORT mgl_datac_abs_(uintptr_t *d) { return uintptr_t(mgl_datac_abs(_DC_)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_arg(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast(d); if(dd) #pragma omp parallel for for(long i=0;ia[i] = arg(dd->a[i]); return r; } uintptr_t MGL_EXPORT mgl_datac_arg_(uintptr_t *d) { return uintptr_t(mgl_datac_arg(_DC_)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_ri(HADT d, HCDT re, HCDT im) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); d->Create(nx,ny,nz); #pragma omp parallel for for(long i=0;ia[i] = dual(re->vthr(i),im->vthr(i)); } void MGL_EXPORT mgl_datac_set_ri_(uintptr_t *d, uintptr_t *re, uintptr_t *im) { mgl_datac_set_ri(_DC_,_DA_(re),_DA_(im)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_ap(HADT d, HCDT a, HCDT p) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); d->Create(nx,ny,nz); #pragma omp parallel for for(long i=0;ivthr(i), pp=p->vthr(i); d->a[i] = dual(aa*cos(pp), aa*sin(pp)); } } void MGL_EXPORT mgl_datac_set_ap_(uintptr_t *d, uintptr_t *a, uintptr_t *p) { mgl_datac_set_ap(_DC_,_DA_(a),_DA_(p)); } //----------------------------------------------------------------------------- #if MGL_HAVE_HDF5 void MGL_EXPORT mgl_datac_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite) { const mglDataC *d = dynamic_cast(dat); if(!d) { mgl_data_save_hdf(dat,fname,data,rewrite); return; } hid_t hf,hd,hs; hsize_t dims[4]; long rank = 3, res; H5Eset_auto(0,0); res=H5Fis_hdf5(fname); if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT); else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if(hf<0) return; if(d->nz==1 && d->ny == 1) { rank=2; dims[0]=d->nx; dims[1]=2; } else if(d->nz==1) { rank=3; dims[0]=d->ny; dims[1]=d->nx; dims[2]=2; } else { rank=4; dims[0]=d->nz; dims[1]=d->ny; dims[2]=d->nx; dims[3]=2; } hs = H5Screate_simple(rank, dims, 0); #if MGL_USE_DOUBLE hid_t mem_type_id = H5T_NATIVE_DOUBLE; #else hid_t mem_type_id = H5T_NATIVE_FLOAT; #endif hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT); H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, d->a); H5Dclose(hd); H5Sclose(hs); H5Fclose(hf); } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read_hdf(HADT d,const char *fname,const char *data) { hid_t hf,hd,hs; hsize_t dims[4]; long rank, res = H5Fis_hdf5(fname); if(res<=0) return 0; hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); if(hf<0) return 0; hd = H5Dopen(hf,data); if(hd<0) return 0; hs = H5Dget_space(hd); rank = H5Sget_simple_extent_ndims(hs); if(rank>0 && rank<=4) { H5Sget_simple_extent_dims(hs,dims,0); if(dims[rank-1]==2) { if(rank==1) { dims[2]=dims[0]=dims[1]=1; } else if(rank==2) { dims[2]=dims[0]; dims[0]=dims[1]=1; } else if(rank==3) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; } mgl_datac_create(d,dims[2],dims[1],dims[0]); #if MGL_USE_DOUBLE H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a); #else H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a); #endif } else if(rank<=3) { if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; } else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; } mgl_datac_create(d,dims[2],dims[1],dims[0]); long nn = dims[2]*dims[1]*dims[0]; mreal *a = new mreal[nn]; #if MGL_USE_DOUBLE H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, a); #else H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, a); #endif for(long i=0;ia[i] = a[i]; delete []a; } } H5Sclose(hs); H5Dclose(hd); H5Fclose(hf); return 1; } //----------------------------------------------------------------------------- #else void MGL_EXPORT mgl_datac_save_hdf(HCDT ,const char *,const char *,int ) { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); } int MGL_EXPORT mgl_datac_read_hdf(HADT ,const char *,const char *) { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;} #endif //----------------------------------------------------------------------------- int MGL_EXPORT mgl_datac_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *t=new char[n+1]; memcpy(t,data,n); t[n]=0; int r = mgl_datac_read_hdf(_DC_,s,t); delete []s; delete []t; return r; } void MGL_EXPORT mgl_datac_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *t=new char[n+1]; memcpy(t,data,n); t[n]=0; mgl_datac_save_hdf(_DC_,s,t,*rewrite); delete []s; delete []t; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_limit(HADT d, mreal v) { long n = d->GetNN(); dual *a = d->a; #pragma omp parallel for for(long i=0;iv) a[i] *= v/b; } } void MGL_EXPORT mgl_datac_limit_(uintptr_t *d, mreal *v) { mgl_datac_limit(_DC_, *v); } //----------------------------------------------------------------------------- mathgl-2.4.4/src/cont.hpp0000644000175000017500000000505613513030041015416 0ustar alastairalastair/*************************************************************************** * cont.cpp is part of Math Graphic Library * Copyright (C) 2007-2014 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ //----------------------------------------------------------------------------- struct mglSegment { mglPoint p1,p2; // edges std::list pp; bool set(mreal u1,mreal v1,mreal u2,mreal v2,long i,long j,long k,HCDT x, HCDT y, HCDT z) { bool res=(v1>=0 && v1<=MGL_FEPSILON && u1>=0 && u1<=MGL_FEPSILON && v2>=0 && v2<=MGL_FEPSILON && u2>=0 && u2<=MGL_FEPSILON); if(v1==v2 && u1==u2) res=false; // NOTE: shouldn't be here never if(res) { p1.Set(mgl_data_linear(x,i+u1,j+v1,k), mgl_data_linear(y,i+u1,j+v1,k), mgl_data_linear(z,i+u1,j+v1,k)); p2.Set(mgl_data_linear(x,i+u2,j+v2,k), mgl_data_linear(y,i+u2,j+v2,k), mgl_data_linear(z,i+u2,j+v2,k)); } return res; } void before(const mglPoint &p) { p1 = p; pp.push_front(p); } void after(const mglPoint &p) { p2 = p; pp.push_back(p); } }; //----------------------------------------------------------------------------- std::vector MGL_EXPORT mgl_get_curvs(HMGL gr, std::vector lines); void MGL_NO_EXPORT mgl_draw_curvs(HMGL gr, mreal val, mreal c, int text, const std::vector &curvs); //----------------------------------------------------------------------------- mathgl-2.4.4/src/prc/0000755000175000017500000000000013513030041014520 5ustar alastairalastairmathgl-2.4.4/src/prc/oPRCFile.cc0000644000175000017500000025704613513030041016450 0ustar alastairalastair/************ * * This file is part of a tool for producing 3D content in the PRC format. * Copyright (C) 2008 Orest Shardt * with enhancements contributed by Michail Vidiassov. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * *************/ #include "oPRCFile.h" #include #include #include #include #include #include #include #include #define WriteUnsignedInteger( value ) out << (uint32_t)(value); #define WriteInteger( value ) out << (int32_t)(value); #define WriteDouble( value ) out << (double)(value); #define WriteString( value ) out << (value); #define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value)); #define WriteUncompressedBlock( value, count ) out.write((char *)(value),(count)); #define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out); #define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(out); #define SerializeContentPRCBase write(out); #define SerializeRgbColor( value ) (value).serializeRgbColor(out); #define SerializePicture( value ) (value)->serializePicture(out); #define SerializeTextureDefinition( value ) (value)->serializeTextureDefinition(out); #define SerializeMarkup( value ) (value)->serializeMarkup(out); #define SerializeAnnotationEntity( value ) (value)->serializeAnnotationEntity(out); #define SerializeFontKeysSameFont( value ) (value).serializeFontKeysSameFont(out); #define SerializeMaterial( value ) (value)->serializeMaterial(out); #define SerializeUserData UserData(0,0).write(out); #define SerializeEmptyContentPRCBase ContentPRCBase(PRC_TYPE_ROOT_PRCBase).serializeContentPRCBase(out); #define SerializeCategory1LineStyle( value ) (value)->serializeCategory1LineStyle(out); #define SerializeCoordinateSystem( value ) (value)->serializeCoordinateSystem(out); #define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(out); #define SerializePartDefinition( value ) (value)->serializePartDefinition(out); #define SerializeProductOccurrence( value ) (value)->serializeProductOccurrence(out); #define SerializeContextAndBodies( value ) (value)->serializeContextAndBodies(out); #define SerializeGeometrySummary( value ) (value)->serializeGeometrySummary(out); #define SerializeContextGraphics( value ) (value)->serializeContextGraphics(out); #define SerializeStartHeader serializeStartHeader(out); #define SerializeUncompressedFile( value ) (value)->serializeUncompressedFile(out); #define SerializeUncompressedFiles serializeUncompressedFiles(out); #define SerializeModelFileData serializeModelFileData(modelFile_out); modelFile_out.compress(); #define SerializeUnit( value ) (value).serializeUnit(out); using std::string; using namespace std; // Map [0,1] to [0,255] inline uint8_t toByte(double r) { if(r < 0.0) r=0.0; else if(r > 1.0) r=1.0; int a=(int)(256.0*r); if(a == 256) a=255; return a; } void PRCFileStructure::serializeFileStructureGlobals(PRCbitStream &out) { // even though this is technically not part of this section, // it is handled here for convenience const uint32_t number_of_schema = 0; WriteUnsignedInteger (number_of_schema) WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGlobals) PRCSingleAttribute sa((int32_t)PRCVersion); PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion"); a.addKey(sa); ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase); cb.addAttribute(a); cb.serializeContentPRCBase(out); WriteUnsignedInteger (number_of_referenced_file_structures) // SerializeFileStructureInternalGlobalData WriteDouble (tessellation_chord_height_ratio) WriteDouble (tessellation_angle_degree) // SerializeMarkupSerializationHelper WriteString (default_font_family_name) const uint32_t number_of_fonts = font_keys_of_font.size(); WriteUnsignedInteger (number_of_fonts) for (uint32_t i=0;iunit_information.unit_from_CAD_file = true; product_occurrences[i]->unit_information.unit = unit; SerializeProductOccurrence (product_occurrences[i]) } // SerializeFileStructureInternalData WriteUnsignedInteger (PRC_TYPE_ASM_FileStructure) SerializeEmptyContentPRCBase const uint32_t next_available_index = makePRCID(); WriteUnsignedInteger (next_available_index) const uint32_t index_product_occurence = number_of_product_occurrences; // Asymptote (oPRCFile) specific - we write the root product last WriteUnsignedInteger (index_product_occurence) SerializeUserData } void PRCFileStructure::serializeFileStructureTessellation(PRCbitStream &out) { WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTessellation) SerializeEmptyContentPRCBase const uint32_t number_of_tessellations = tessellations.size(); WriteUnsignedInteger (number_of_tessellations) for (uint32_t i=0;iserializeBaseTessData(out); SerializeUserData } void PRCFileStructure::serializeFileStructureGeometry(PRCbitStream &out) { WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGeometry) SerializeEmptyContentPRCBase const uint32_t number_of_contexts = contexts.size(); WriteUnsignedInteger (number_of_contexts) for (uint32_t i=0;ifile_structure_uuid ) // index+1 out << (uint32_t)fileStructures[0]->product_occurrences.size(); // active out << true; out << (uint32_t)0; // index in model file SerializeUserData } void makeFileUUID(PRCUniqueId& UUID) { // make a UUID static uint32_t count = 0; ++count; // the minimum requirement on UUIDs is that all must be unique in the file UUID.id0 = 0x33595341; // some constant UUID.id1 = (uint32_t)time(NULL); // the time UUID.id2 = count; UUID.id3 = 0xa5a55a5a; // Something random, not seeded by the time, would be nice. But for now, a constant // maybe add something else to make it more unique // so multiple files can be combined // a hash of some data perhaps? } void makeAppUUID(PRCUniqueId& UUID) { UUID.id0 = UUID.id1 = UUID.id2 = UUID.id3 = 0; } void PRCStartHeader::serializeStartHeader(ostream &out) const { WriteUncompressedBlock ("PRC",3) WriteUncompressedUnsignedInteger (minimal_version_for_read) WriteUncompressedUnsignedInteger (authoring_version) SerializeFileStructureUncompressedUniqueId( file_structure_uuid ); SerializeFileStructureUncompressedUniqueId( application_uuid ); } void PRCStartHeader::serializeUncompressedFiles(ostream &out) const { const uint32_t number_of_uncompressed_files = uncompressed_files.size(); WriteUncompressedUnsignedInteger (number_of_uncompressed_files) for (uint32_t i=0; igetSize(); return size; } void PRCFileStructure::write(ostream &out) { // SerializeFileStructureHeader SerializeStartHeader SerializeUncompressedFiles globals_out.write(out); tree_out.write(out); tessellations_out.write(out); geometry_out.write(out); extraGeometry_out.write(out); } #define SerializeFileStructureGlobals serializeFileStructureGlobals(globals_out); globals_out.compress(); sizes[1]=globals_out.getSize(); #define SerializeFileStructureTree serializeFileStructureTree(tree_out); tree_out.compress(); sizes[2]=tree_out.getSize(); #define SerializeFileStructureTessellation serializeFileStructureTessellation(tessellations_out); tessellations_out.compress(); sizes[3]=tessellations_out.getSize(); #define SerializeFileStructureGeometry serializeFileStructureGeometry(geometry_out); geometry_out.compress(); sizes[4]=geometry_out.getSize(); #define SerializeFileStructureExtraGeometry serializeFileStructureExtraGeometry(extraGeometry_out); extraGeometry_out.compress(); sizes[5]=extraGeometry_out.getSize(); #define FlushSerialization resetGraphicsAndName(); void PRCFileStructure::prepare() { uint32_t size = 0; size += getStartHeaderSize(); size += sizeof(uint32_t); size += getUncompressedFilesSize(); sizes[0]=size; SerializeFileStructureGlobals FlushSerialization SerializeFileStructureTree FlushSerialization SerializeFileStructureTessellation FlushSerialization SerializeFileStructureGeometry FlushSerialization SerializeFileStructureExtraGeometry FlushSerialization } uint32_t PRCFileStructure::getSize() { uint32_t size = 0; for(size_t i=0; i<6; i++) size += sizes[i]; return size; } void PRCFileStructureInformation::write(ostream &out) { SerializeFileStructureUncompressedUniqueId( UUID ); WriteUncompressedUnsignedInteger (reserved) WriteUncompressedUnsignedInteger (number_of_offsets) for(uint32_t i = 0; i < number_of_offsets; ++i) { WriteUncompressedUnsignedInteger (offsets[i]) } } uint32_t PRCFileStructureInformation::getSize() { return (4+2+number_of_offsets)*sizeof(uint32_t); } void PRCHeader::write(ostream &out) { SerializeStartHeader WriteUncompressedUnsignedInteger (number_of_file_structures) for(uint32_t i = 0; i < number_of_file_structures; ++i) { fileStructureInformation[i].write(out); } WriteUncompressedUnsignedInteger (model_file_offset) WriteUncompressedUnsignedInteger (file_size) SerializeUncompressedFiles } uint32_t PRCHeader::getSize() { uint32_t size = getStartHeaderSize() + sizeof(uint32_t); for(uint32_t i = 0; i < number_of_file_structures; ++i) size += fileStructureInformation[i].getSize(); size += 3*sizeof(uint32_t); size += getUncompressedFilesSize(); return size; } void oPRCFile::doGroup(PRCgroup& group) { const string& name = group.name; PRCProductOccurrence*& product_occurrence = group.product_occurrence; PRCProductOccurrence*& parent_product_occurrence = group.parent_product_occurrence; PRCPartDefinition*& part_definition = group.part_definition; PRCPartDefinition*& parent_part_definition = group.parent_part_definition; if(group.options.tess) { if(!group.lines.empty()) { for(PRCtesslineMap::const_iterator wit=group.lines.begin(); wit!=group.lines.end(); wit++) { bool same_color = true; const PRCtesslineList& lines = wit->second; const PRCRgbColor &color = lines.front().color; for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++) if(color!=lit->color) { same_color = false; break; } map points; PRC3DWireTess *tess = new PRC3DWireTess(); if(!same_color) { tess->is_segment_color = true; tess->is_rgba = false; } for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++) { tess->wire_indexes.push_back(lit->point.size()); for(uint32_t i=0; ipoint.size(); i++) { map::iterator pPoint = points.find(lit->point[i]); if(pPoint!=points.end()) tess->wire_indexes.push_back(pPoint->second); else { const uint32_t point_index = tess->coordinates.size(); points.insert(make_pair(lit->point[i],point_index)); tess->wire_indexes.push_back(point_index); tess->coordinates.push_back(lit->point[i].x); tess->coordinates.push_back(lit->point[i].y); tess->coordinates.push_back(lit->point[i].z); } if(!same_color && i>0) { tess->rgba_vertices.push_back(toByte(lit->color.red)); tess->rgba_vertices.push_back(toByte(lit->color.green)); tess->rgba_vertices.push_back(toByte(lit->color.blue)); } } } const uint32_t tess_index = add3DWireTess(tess); PRCPolyWire *polyWire = new PRCPolyWire(); polyWire->index_tessellation = tess_index; if(same_color) polyWire->index_of_line_style = addColourWidth(RGBAColour(color.red,color.green,color.blue),wit->first); else polyWire->index_of_line_style = addColourWidth(RGBAColour(1,1,1),wit->first); part_definition->addPolyWire(polyWire); } } // make rectangles pairs of triangles in a tesselation if(!group.rectangles.empty()) { bool same_color = true; const uint32_t &style = group.rectangles.front().style; for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++) if(style!=rit->style) { same_color = false; break; } map points; PRC3DTess *tess = new PRC3DTess(); tess->crease_angle = group.options.crease_angle; PRCTessFace *tessFace = new PRCTessFace(); tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle; uint32_t triangles = 0; for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++) { const bool degenerate = (rit->vertices[0]==rit->vertices[1]); uint32_t vertex_indices[4]; for(size_t i = (degenerate?1:0); i < 4; ++i) { map::const_iterator pPoint = points.find(rit->vertices[i]); if(pPoint!=points.end()) vertex_indices[i] = pPoint->second; else { points.insert(make_pair(rit->vertices[i],(vertex_indices[i] = tess->coordinates.size()))); tess->coordinates.push_back(rit->vertices[i].x); tess->coordinates.push_back(rit->vertices[i].y); tess->coordinates.push_back(rit->vertices[i].z); } } if(degenerate) { tess->triangulated_index.push_back(vertex_indices[1]); tess->triangulated_index.push_back(vertex_indices[2]); tess->triangulated_index.push_back(vertex_indices[3]); triangles++; if(!same_color) tessFace->line_attributes.push_back(rit->style); } else { tess->triangulated_index.push_back(vertex_indices[0]); tess->triangulated_index.push_back(vertex_indices[2]); tess->triangulated_index.push_back(vertex_indices[3]); triangles++; if(!same_color) tessFace->line_attributes.push_back(rit->style); tess->triangulated_index.push_back(vertex_indices[3]); tess->triangulated_index.push_back(vertex_indices[1]); tess->triangulated_index.push_back(vertex_indices[0]); triangles++; if(!same_color) tessFace->line_attributes.push_back(rit->style); } } tessFace->sizes_triangulated.push_back(triangles); tess->addTessFace(tessFace); const uint32_t tess_index = add3DTess(tess); PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel(); polyBrepModel->index_tessellation = tess_index; polyBrepModel->is_closed = group.options.closed; if(same_color) polyBrepModel->index_of_line_style = style; part_definition->addPolyBrepModel(polyBrepModel); } } if(!group.quads.empty()) { map points; PRC3DTess *tess = new PRC3DTess(); tess->crease_angle = group.options.crease_angle; PRCTessFace *tessFace = new PRCTessFace(); tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle; uint32_t triangles = 0; tessFace->is_rgba = false; for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++) { const RGBAColour* C = qit->colours; if(C[0].A != 1.0 || C[1].A != 1.0 || C[2].A != 1.0 || C[3].A != 1.0) { tessFace->is_rgba = true; break; } } bool same_colour = true; const RGBAColour& colour = group.quads.front().colours[0]; for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++) { const RGBAColour* C = qit->colours; if(colour!=C[0] || colour!=C[1] || colour!=C[2] || colour!=C[3]) { same_colour = false; break; } } for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++) { const RGBAColour* C = qit->colours; const bool degenerate = (qit->vertices[0]==qit->vertices[1]); uint32_t vertex_indices[4]; for(size_t i = (degenerate?1:0); i < 4; ++i) { map::const_iterator pPoint = points.find(qit->vertices[i]); if(pPoint!=points.end()) vertex_indices[i] = pPoint->second; else { points.insert(make_pair(qit->vertices[i],(vertex_indices[i] = tess->coordinates.size()))); tess->coordinates.push_back(qit->vertices[i].x); tess->coordinates.push_back(qit->vertices[i].y); tess->coordinates.push_back(qit->vertices[i].z); } } if(degenerate) { tess->triangulated_index.push_back(vertex_indices[1]); tess->triangulated_index.push_back(vertex_indices[2]); tess->triangulated_index.push_back(vertex_indices[3]); triangles++; if(!same_colour) { tessFace->rgba_vertices.push_back(toByte(C[1].R)); tessFace->rgba_vertices.push_back(toByte(C[1].G)); tessFace->rgba_vertices.push_back(toByte(C[1].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[1].A)); tessFace->rgba_vertices.push_back(toByte(C[2].R)); tessFace->rgba_vertices.push_back(toByte(C[2].G)); tessFace->rgba_vertices.push_back(toByte(C[2].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[2].A)); tessFace->rgba_vertices.push_back(toByte(C[3].R)); tessFace->rgba_vertices.push_back(toByte(C[3].G)); tessFace->rgba_vertices.push_back(toByte(C[3].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[3].A)); } } else { tess->triangulated_index.push_back(vertex_indices[0]); tess->triangulated_index.push_back(vertex_indices[2]); tess->triangulated_index.push_back(vertex_indices[3]); triangles++; if(!same_colour) { tessFace->rgba_vertices.push_back(toByte(C[0].R)); tessFace->rgba_vertices.push_back(toByte(C[0].G)); tessFace->rgba_vertices.push_back(toByte(C[0].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[0].A)); tessFace->rgba_vertices.push_back(toByte(C[2].R)); tessFace->rgba_vertices.push_back(toByte(C[2].G)); tessFace->rgba_vertices.push_back(toByte(C[2].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[2].A)); tessFace->rgba_vertices.push_back(toByte(C[3].R)); tessFace->rgba_vertices.push_back(toByte(C[3].G)); tessFace->rgba_vertices.push_back(toByte(C[3].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[3].A)); } tess->triangulated_index.push_back(vertex_indices[3]); tess->triangulated_index.push_back(vertex_indices[1]); tess->triangulated_index.push_back(vertex_indices[0]); triangles++; if(!same_colour) { tessFace->rgba_vertices.push_back(toByte(C[3].R)); tessFace->rgba_vertices.push_back(toByte(C[3].G)); tessFace->rgba_vertices.push_back(toByte(C[3].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[3].A)); tessFace->rgba_vertices.push_back(toByte(C[1].R)); tessFace->rgba_vertices.push_back(toByte(C[1].G)); tessFace->rgba_vertices.push_back(toByte(C[1].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[1].A)); tessFace->rgba_vertices.push_back(toByte(C[0].R)); tessFace->rgba_vertices.push_back(toByte(C[0].G)); tessFace->rgba_vertices.push_back(toByte(C[0].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[0].A)); } } } tessFace->sizes_triangulated.push_back(triangles); tess->addTessFace(tessFace); const uint32_t tess_index = add3DTess(tess); PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel(); polyBrepModel->index_tessellation = tess_index; polyBrepModel->is_closed = group.options.closed; if(same_colour) polyBrepModel->index_of_line_style = addColour(colour); part_definition->addPolyBrepModel(polyBrepModel); } if(!group.points.empty()) { for(PRCpointsetMap::const_iterator pit=group.points.begin(); pit!=group.points.end(); pit++) { PRCPointSet *pointset = new PRCPointSet(); pointset->index_of_line_style = pit->first; pointset->point = pit->second; part_definition->addPointSet(pointset); } } if(!group.pointsets.empty()) { for(std::vector::iterator pit=group.pointsets.begin(); pit!=group.pointsets.end(); pit++) { part_definition->addPointSet(*pit); } } if(!group.polymodels.empty()) { for(std::vector::iterator pit=group.polymodels.begin(); pit!=group.polymodels.end(); pit++) { (*pit)->is_closed = group.options.closed; part_definition->addPolyBrepModel(*pit); } } if(!group.polywires.empty()) { for(std::vector::iterator pit=group.polywires.begin(); pit!=group.polywires.end(); pit++) { part_definition->addPolyWire(*pit); } } if(!group.wires.empty()) { PRCTopoContext *wireContext = NULL; const uint32_t context_index = getTopoContext(wireContext); for(PRCwireList::iterator wit=group.wires.begin(); wit!=group.wires.end(); wit++) { PRCWireEdge *wireEdge = new PRCWireEdge; wireEdge->curve_3d = wit->curve; PRCSingleWireBody *wireBody = new PRCSingleWireBody; wireBody->setWireEdge(wireEdge); const uint32_t wire_body_index = wireContext->addSingleWireBody(wireBody); PRCWire *wire = new PRCWire(); wire->index_of_line_style = wit->style; wire->context_id = context_index; wire->body_id = wire_body_index; if(wit->transform) wire->index_local_coordinate_system = addTransform(wit->transform); part_definition->addWire(wire); } } PRCfaceList &faces = group.faces; if(!faces.empty()) { bool same_color = true; const uint32_t style = faces.front().style; for(PRCfaceList::const_iterator fit=faces.begin(); fit!=faces.end(); fit++) if(style!=fit->style) { same_color = false; break; } PRCTopoContext *context = NULL; const uint32_t context_index = getTopoContext(context); context->granularity = group.options.granularity; // Acrobat 9 also does the following: // context->tolerance = group.options.granularity; // context->have_smallest_face_thickness = true; // context->smallest_thickness = group.options.granularity; PRCShell *shell = new PRCShell; for(PRCfaceList::iterator fit=faces.begin(); fit!=faces.end(); fit++) { if(fit->transform || group.options.do_break || (fit->transparent && !group.options.no_break)) { PRCShell *shell = new PRCShell; shell->addFace(fit->face); PRCConnex *connex = new PRCConnex; connex->addShell(shell); PRCBrepData *body = new PRCBrepData; body->addConnex(connex); const uint32_t body_index = context->addBrepData(body); PRCBrepModel *brepmodel = new PRCBrepModel(); brepmodel->index_of_line_style = fit->style; brepmodel->context_id = context_index; brepmodel->body_id = body_index; brepmodel->is_closed = group.options.closed; brepmodel->index_local_coordinate_system = addTransform(fit->transform); part_definition->addBrepModel(brepmodel); } else { if(!same_color) fit->face->index_of_line_style = fit->style; shell->addFace(fit->face); } } if(shell->face.empty()) { delete shell; } else { PRCConnex *connex = new PRCConnex; connex->addShell(shell); PRCBrepData *body = new PRCBrepData; body->addConnex(connex); const uint32_t body_index = context->addBrepData(body); PRCBrepModel *brepmodel = new PRCBrepModel(); if(same_color) brepmodel->index_of_line_style = style; brepmodel->context_id = context_index; brepmodel->body_id = body_index; brepmodel->is_closed = group.options.closed; part_definition->addBrepModel(brepmodel); } } PRCcompfaceList &compfaces = group.compfaces; if(!compfaces.empty()) { bool same_color = true; const uint32_t style = compfaces.front().style; for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++) if(style!=fit->style) { same_color = false; break; } PRCTopoContext *context = NULL; const uint32_t context_index = getTopoContext(context); PRCCompressedBrepData *body = new PRCCompressedBrepData; body->serial_tolerance=group.options.compression; body->brep_data_compressed_tolerance=0.1*group.options.compression; for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++) { if(group.options.do_break || (fit->transparent && !group.options.no_break)) { PRCCompressedBrepData *body = new PRCCompressedBrepData; body->face.push_back(fit->face); body->serial_tolerance=group.options.compression; body->brep_data_compressed_tolerance=2.8346456* group.options.compression; const uint32_t body_index = context->addCompressedBrepData(body); PRCBrepModel *brepmodel = new PRCBrepModel(); brepmodel->index_of_line_style = fit->style; brepmodel->context_id = context_index; brepmodel->body_id = body_index; brepmodel->is_closed = group.options.closed; part_definition->addBrepModel(brepmodel); } else { if(!same_color) fit->face->index_of_line_style = fit->style; body->face.push_back(fit->face); } } if(body->face.empty()) { delete body; } else { const uint32_t body_index = context->addCompressedBrepData(body); PRCBrepModel *brepmodel = new PRCBrepModel(); if(same_color) brepmodel->index_of_line_style = style; brepmodel->context_id = context_index; brepmodel->body_id = body_index; brepmodel->is_closed = group.options.closed; part_definition->addBrepModel(brepmodel); } } // Simplify and reduce to as simple entities as possible // products with named representation items can not be reduced to sets, since // outside references are already set bool nonamedparts = true; for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++) { if (!(*it)->name.empty()) { nonamedparts = false; break; } } lastgroupname.clear(); lastgroupnames.clear(); // First option - reduce to one element in parent if (parent_part_definition && product_occurrence->index_son_occurrence.empty() && part_definition->representation_item.size() == 1 && ( name.empty() || part_definition->representation_item.front()->name.empty() ) && ( !group.transform || part_definition->representation_item.front()->index_local_coordinate_system==m1) ) { if(part_definition->representation_item.front()->name.empty() ) part_definition->representation_item.front()->name = name; if(part_definition->representation_item.front()->index_local_coordinate_system==m1) part_definition->representation_item.front()->index_local_coordinate_system = addTransform(group.transform); lastgroupname = calculate_unique_name(part_definition->representation_item.front(), parent_product_occurrence); parent_part_definition->addRepresentationItem(part_definition->representation_item.front()); part_definition->representation_item.clear(); delete product_occurrence; product_occurrence = NULL; delete part_definition; part_definition = NULL; } // Second option - reduce to a set else if (parent_part_definition && product_occurrence->index_son_occurrence.empty() && !part_definition->representation_item.empty() && !group.options.do_break && nonamedparts) { PRCSet *set = new PRCSet(name); set->index_local_coordinate_system = addTransform(group.transform); lastgroupname = calculate_unique_name(set, parent_product_occurrence); for(PRCRepresentationItemList::iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++) { lastgroupnames.push_back(calculate_unique_name(*it, parent_product_occurrence)); set->addRepresentationItem(*it); } part_definition->representation_item.clear(); parent_part_definition->addSet(set); delete product_occurrence; product_occurrence = NULL; delete part_definition; part_definition = NULL; } // Third option - create product else if ( !product_occurrence->index_son_occurrence.empty() || !part_definition->representation_item.empty()) { // if everything is enclosed in one group - drop the root group if (parent_product_occurrence == NULL && group.transform == NULL && part_definition->representation_item.empty() && product_occurrence->index_son_occurrence.size()==1) { delete part_definition; part_definition = NULL; delete product_occurrence; product_occurrence = NULL; } else { lastgroupname = calculate_unique_name(product_occurrence, NULL); if (part_definition->representation_item.empty()) { delete part_definition; part_definition = NULL; } else { for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++) if ((*it)->name.empty()) lastgroupnames.push_back(calculate_unique_name(*it, product_occurrence)); product_occurrence->index_part = addPartDefinition(part_definition); } if (group.transform) { product_occurrence->location = group.transform; group.transform = NULL; } if (parent_product_occurrence) { parent_product_occurrence->index_son_occurrence.push_back(addProductOccurrence(product_occurrence)); } else { addProductOccurrence(product_occurrence); } } } // Last case - absolutely nothing to do else { delete product_occurrence; product_occurrence = NULL; delete part_definition; part_definition = NULL; } } std::string oPRCFile::calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence) { std::stringstream ss (std::stringstream::in | std::stringstream::out); uint8_t *serialization_buffer = NULL; PRCbitStream serialization(serialization_buffer,0u); const PRCFileStructure *pfile_structure = fileStructures[0]; const PRCUniqueId& uuid = pfile_structure->file_structure_uuid; // ConvertUniqueIdentifierToString (prc_entity) // SerializeCompressedUniqueId (file_structure) serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3; // WriteUnsignedInteger (type) serialization << prc_entity->getType(); // WriteUnsignedInteger (unique_identifier) serialization << prc_entity->getPRCID(); if (prc_occurence) { // serialization_buffer = Flush serialization (serialization) { const uint32_t size_serialization = serialization.getSize(); while(size_serialization == serialization.getSize()) serialization << false; } // ConvertUniqueIdentifierToString (prc_occurrence_unique_id) // SerializeCompressedUniqueId (file_structure) serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3; // WriteUnsignedInteger (type) serialization << (uint32_t)PRC_TYPE_ASM_ProductOccurence; // WriteUnsignedInteger (unique_identifier) serialization << prc_occurence->getPRCID(); } ss << (prc_entity->name.empty()?"node":prc_entity->name.c_str()) << '.'; const uint32_t size_serialization = serialization.getSize(); for(size_t j=0; jprepare(); SerializeModelFileData // create the header // fill out enough info so that sizes can be computed correctly header.number_of_file_structures = number_of_file_structures; header.fileStructureInformation = new PRCFileStructureInformation[number_of_file_structures]; for(uint32_t i = 0; i < number_of_file_structures; ++i) { header.fileStructureInformation[i].UUID = fileStructures[i]->file_structure_uuid; header.fileStructureInformation[i].reserved = 0; header.fileStructureInformation[i].number_of_offsets = 6; header.fileStructureInformation[i].offsets = new uint32_t[6]; } header.minimal_version_for_read = PRCVersion; header.authoring_version = PRCVersion; makeFileUUID(header.file_structure_uuid); makeAppUUID(header.application_uuid); header.file_size = getSize(); header.model_file_offset = header.file_size - modelFile_out.getSize(); uint32_t currentOffset = header.getSize(); for(uint32_t i = 0; i < number_of_file_structures; ++i) { for(size_t j=0; j<6; j++) { header.fileStructureInformation[i].offsets[j] = currentOffset; currentOffset += fileStructures[i]->sizes[j]; } } // write the data header.write(output); for(uint32_t i = 0; i < number_of_file_structures; ++i) { fileStructures[i]->write(output); } modelFile_out.write(output); output.flush(); for(uint32_t i = 0; i < number_of_file_structures; ++i) delete[] header.fileStructureInformation[i].offsets; delete[] header.fileStructureInformation; return true; } uint32_t oPRCFile::getSize() { uint32_t size = header.getSize(); for(uint32_t i = 0; i < number_of_file_structures; ++i) { size += fileStructures[i]->getSize(); } size += modelFile_out.getSize(); return size; } uint32_t PRCFileStructure::addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *p, uint32_t width, uint32_t height, string name) { uint8_t *data = NULL; if(size==0 || p==NULL) { cerr << "image not set" << endl; return m1; } if(format==KEPRCPicture_PNG || format==KEPRCPicture_JPG) { width = 0; // width and height are ignored for JPG and PNG pictures - but let us keep things clean height = 0; data = new uint8_t[size]; memcpy(data, p, size); } else { uint32_t components=0; switch(format) { case KEPRCPicture_BITMAP_RGB_BYTE: components = 3; break; case KEPRCPicture_BITMAP_RGBA_BYTE: components = 4; break; case KEPRCPicture_BITMAP_GREY_BYTE: components = 1; break; case KEPRCPicture_BITMAP_GREYA_BYTE: components = 2; break; default: { cerr << "unknown picture format" << endl; return m1; } } if(width==0 || height==0) { cerr << "width or height parameter not set" << endl; return m1; } if (size < width*height*components) { cerr << "image too small" << endl; return m1; } { uint32_t compressedDataSize = 0; const int CHUNK= 1024; // is this reasonable? z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK) { cerr << "Compression initialization failed" << endl; return m1; } unsigned int sizeAvailable = deflateBound(&strm,size); uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable); strm.avail_in = size; strm.next_in = (unsigned char*)p; strm.next_out = (unsigned char*)compressedData; strm.avail_out = sizeAvailable; int code; unsigned int chunks = 0; while((code = deflate(&strm,Z_FINISH)) == Z_OK) { ++chunks; // strm.avail_out should be 0 if we got Z_OK compressedDataSize = sizeAvailable - strm.avail_out; compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks); strm.next_out = (Bytef*)(compressedData + compressedDataSize); strm.avail_out += CHUNK; sizeAvailable += CHUNK; } compressedDataSize = sizeAvailable-strm.avail_out; if(code != Z_STREAM_END) { deflateEnd(&strm); free(compressedData); { cerr << "Compression error" << endl; return m1; } } deflateEnd(&strm); size = compressedDataSize; data = new uint8_t[compressedDataSize]; memcpy(data, compressedData, compressedDataSize); free(compressedData); } } uint32_t uncompressed_file_index = m1; { PRCUncompressedFile* uncompressed_file = new PRCUncompressedFile(size, data); uncompressed_file_index = addUncompressedFileUnique(uncompressed_file); delete[] data; } uint32_t picture_index = m1; { PRCPicture* picture = new PRCPicture(name); picture->format = format; picture->uncompressed_file_index = uncompressed_file_index; picture->pixel_width = width; picture->pixel_height = height; picture_index = addPictureUnique(picture); } return picture_index; } uint32_t oPRCFile::addColour(const RGBAColour &colour) { PRCcolourMap::const_iterator pColour = colourMap.find(colour); if(pColour!=colourMap.end()) return pColour->second; const uint32_t color_index = addRgbColorUnique(colour.R, colour.G, colour.B); PRCStyle *style = new PRCStyle(); style->line_width = 1.0; style->is_vpicture = false; style->line_pattern_vpicture_index = 0; style->is_material = false; style->color_material_index = color_index; style->is_transparency_defined = (colour.A < 1.0); style->transparency = (uint8_t)(colour.A * 256); style->additional = 0; const uint32_t style_index = addStyle(style); colourMap.insert(make_pair(colour,style_index)); return style_index; } uint32_t oPRCFile::addColourWidth(const RGBAColour &colour, double width) { const RGBAColourWidth colourwidth(colour.R, colour.G, colour.B, colour.A, width); PRCcolourwidthMap::const_iterator pColour = colourwidthMap.find(colourwidth); if(pColour!=colourwidthMap.end()) return pColour->second; const uint32_t color_index = addRgbColorUnique(colour.R, colour.G, colour.B); PRCStyle *style = new PRCStyle(); style->line_width = width; style->is_vpicture = false; style->line_pattern_vpicture_index = 0; style->is_material = false; style->color_material_index = color_index; style->is_transparency_defined = (colour.A < 1.0); style->transparency = (uint8_t)(colour.A * 256); style->additional = 0; const uint32_t style_index = addStyle(style); colourwidthMap.insert(make_pair(colourwidth,style_index)); return style_index; } uint32_t oPRCFile::addTransform(PRCGeneralTransformation3d*& transform) { if(!transform) return m1; PRCtransformMap::const_iterator pTransform = transformMap.find(*transform); if(pTransform!=transformMap.end()) return pTransform->second; PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem(); bool transform_replaced = false; if( transform->M(0,1)==0 && transform->M(0,2)==0 && transform->M(1,0)==0 && transform->M(1,2)==0 && transform->M(2,0)==0 && transform->M(2,1)==0 && transform->M(3,0)==0 && transform->M(3,1)==0 && transform->M(3,2)==0 && transform->M(3,3)==1 ) { transform_replaced = true; PRCCartesianTransformation3d *carttransform = new PRCCartesianTransformation3d; // if(transform->M(0,3)==0 && transform->M(1,3)==0 && transform->M(1,3)==0 && // transform->M(0,0)==1 && transform->M(1,1)==1 && transform->M(2,2)==1 ) // carttransform->behaviour = PRC_TRANSFORMATION_Identity; if(transform->M(0,3)!=0 || transform->M(1,3)!=0 || transform->M(2,3)!=0) { carttransform->behaviour |= PRC_TRANSFORMATION_Translate; carttransform->origin.Set(transform->M(0,3),transform->M(1,3),transform->M(2,3)); } if(transform->M(0,0)!=transform->M(1,1) || transform->M(0,0)!=transform->M(2,2)) { carttransform->behaviour |= PRC_TRANSFORMATION_NonUniformScale; carttransform->scale.Set(transform->M(0,0),transform->M(1,1),transform->M(2,2)); } else if(transform->M(0,0)!=1) { carttransform->behaviour |= PRC_TRANSFORMATION_Scale; carttransform->uniform_scale=transform->M(0,0); } coordinateSystem->axis_set = carttransform; } else coordinateSystem->axis_set = transform; const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem); transformMap.insert(make_pair(*transform,coordinate_system_index)); if(transform_replaced) delete transform; transform = NULL; return coordinate_system_index; } uint32_t oPRCFile::addTransform(const double* t) { if(!t) return m1; PRCGeneralTransformation3d* transform = new PRCGeneralTransformation3d(t); return addTransform(transform); } uint32_t oPRCFile::addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale) { PRCCartesianTransformation3d* transform = new PRCCartesianTransformation3d(origin, x_axis, y_axis, scale); if(transform->behaviour==PRC_TRANSFORMATION_Identity) { delete transform; return m1; } PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem(); coordinateSystem->axis_set = transform; const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem); return coordinate_system_index; } uint32_t oPRCFile::addMaterial(const PRCmaterial& m) { PRCmaterialMap::const_iterator pMaterial = materialMap.find(m); if(pMaterial!=materialMap.end()) return pMaterial->second; uint32_t material_index = m1; { PRCMaterialGeneric *materialGeneric = new PRCMaterialGeneric; materialGeneric->ambient = addRgbColorUnique(m.ambient.R, m.ambient.G, m.ambient.B); materialGeneric->diffuse = addRgbColorUnique(m.diffuse.R, m.diffuse.G, m.diffuse.B); materialGeneric->emissive = addRgbColorUnique(m.emissive.R, m.emissive.G, m.emissive.B); materialGeneric->specular = addRgbColorUnique(m.specular.R, m.specular.G, m.specular.B); materialGeneric->shininess = m.shininess; materialGeneric->ambient_alpha = m.ambient.A; materialGeneric->diffuse_alpha = m.diffuse.A; materialGeneric->emissive_alpha = m.emissive.A; materialGeneric->specular_alpha = m.specular.A; material_index = addMaterialGenericUnique(materialGeneric); } uint32_t style_index = m1; { PRCStyle *style = new PRCStyle; style->line_width = m.width; style->is_vpicture = false; style->line_pattern_vpicture_index = 0; style->is_material = true; style->is_transparency_defined = (m.alpha < 1.0); style->transparency = (uint8_t)(m.alpha * 256); style->additional = 0; style->color_material_index = material_index; style_index = addStyleUnique(style); } materialMap.insert(make_pair(m,style_index)); return style_index; } uint32_t oPRCFile::addTexturedMaterial(const PRCmaterial& m, uint32_t n, const PRCtexture* const tt[]) { uint32_t material_generic_index = m1; { PRCMaterialGeneric *materialGeneric = new PRCMaterialGeneric; materialGeneric->ambient = addRgbColorUnique(m.ambient.R, m.ambient.G, m.ambient.B); materialGeneric->diffuse = addRgbColorUnique(m.diffuse.R, m.diffuse.G, m.diffuse.B); materialGeneric->emissive = addRgbColorUnique(m.emissive.R, m.emissive.G, m.emissive.B); materialGeneric->specular = addRgbColorUnique(m.specular.R, m.specular.G, m.specular.B); materialGeneric->shininess = m.shininess; materialGeneric->ambient_alpha = m.ambient.A; materialGeneric->diffuse_alpha = m.diffuse.A; materialGeneric->emissive_alpha = m.emissive.A; materialGeneric->specular_alpha = m.specular.A; material_generic_index = addMaterialGenericUnique(materialGeneric); } uint32_t color_material_index = material_generic_index; uint32_t texture_application_index = m1; for (uint32_t i=n; i>0; i--) { const PRCtexture* t = tt[i-1]; if (t == NULL) { continue; } const uint32_t picture_index = addPicture(t->format, t->size, t->data, t->height, t->width); uint32_t texture_definition_index = m1; { PRCTextureDefinition *textureDefinition = new PRCTextureDefinition; textureDefinition->picture_index = picture_index; textureDefinition->texture_mapping_attribute = t->mapping; textureDefinition->texture_mapping_attribute_components = t->components; textureDefinition->texture_function = t->function; textureDefinition->texture_wrapping_mode_S = t->wrapping_mode_S; textureDefinition->texture_wrapping_mode_T = t->wrapping_mode_T; texture_definition_index = addTextureDefinitionUnique(textureDefinition); } { PRCTextureApplication *textureApplication = new PRCTextureApplication; textureApplication->material_generic_index=material_generic_index; textureApplication->texture_definition_index=texture_definition_index; textureApplication->next_texture_index = texture_application_index; texture_application_index = addTextureApplicationUnique(textureApplication); } color_material_index = texture_application_index; } uint32_t style_index = m1; { PRCStyle *style = new PRCStyle; style->line_width = 0.0; style->is_vpicture = false; style->line_pattern_vpicture_index = 0; style->is_material = true; style->is_transparency_defined = (m.alpha < 1.0); style->transparency = (uint8_t)(m.alpha * 256); style->additional = 0; style->color_material_index = color_material_index; style_index = addStyleUnique(style); } return style_index; } bool isid(const double* t) { return( t[0]==1 && t[4]==0 && t[ 8]==0 && t[12]==0 && t[1]==0 && t[5]==1 && t[ 9]==0 && t[13]==0 && t[2]==0 && t[6]==0 && t[10]==1 && t[14]==0 && t[3]==0 && t[7]==0 && t[11]==0 && t[15]==1 ); } void oPRCFile::begingroup(const char *name, const PRCoptions *options, const double* t) { const PRCgroup &parent_group = groups.top(); groups.push(PRCgroup()); PRCgroup &group = groups.top(); group.name=name; if(options) group.options=*options; if(t&&!isid(t)) group.transform = new PRCGeneralTransformation3d(t); group.product_occurrence = new PRCProductOccurrence(name); group.parent_product_occurrence = parent_group.product_occurrence; group.part_definition = new PRCPartDefinition; group.parent_part_definition = parent_group.part_definition; } void oPRCFile::endgroup() { if(groups.size()<2) { fputs("begingroup without matching endgroup",stderr); exit(1); } doGroup(groups.top()); groups.pop(); // std::cout << lastgroupname << std::endl; // for(std::vector::const_iterator it=lastgroupnames.begin(); it!=lastgroupnames.end(); it++) // std::cout << " " << *it << std::endl; } PRCgroup& oPRCFile::findGroup() { return groups.top(); } #define ADDWIRE(curvtype) \ PRCgroup &group = findGroup(); \ group.wires.push_back(PRCwire()); \ PRCwire &wire = group.wires.back(); \ curvtype *curve = new curvtype; \ wire.curve = curve; \ wire.style = addColour(c); #define ADDFACE(surftype) \ PRCgroup &group = findGroup(); \ group.faces.push_back(PRCface()); \ PRCface& face = group.faces.back(); \ surftype *surface = new surftype; \ face.face = new PRCFace; \ face.face->base_surface = surface; \ face.transparent = m.alpha < 1.0; \ face.style = addMaterial(m); #define ADDCOMPFACE \ PRCgroup &group = findGroup(); \ group.compfaces.push_back(PRCcompface()); \ PRCcompface& face = group.compfaces.back(); \ PRCCompressedFace *compface = new PRCCompressedFace; \ face.face = compface; \ face.transparent = m.alpha < 1.0; \ face.style = addMaterial(m); void oPRCFile::addPoint(const double P[3], const RGBAColour &c, double w) { PRCgroup &group = findGroup(); group.points[addColourWidth(c,w)].push_back(PRCVector3d(P[0],P[1],P[2])); } void oPRCFile::addPoint(double x, double y, double z, const RGBAColour &c, double w) { PRCgroup &group = findGroup(); group.points[addColourWidth(c,w)].push_back(PRCVector3d(x,y,z)); } void oPRCFile::addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w) { if(n==0 || P==NULL) return; PRCgroup &group = findGroup(); PRCPointSet *pointset = new PRCPointSet(); group.pointsets.push_back(pointset); pointset->index_of_line_style = addColourWidth(c,w); pointset->point.reserve(n); for(uint32_t i=0; ipoint.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2])); } void oPRCFile::addPoints(uint32_t n, const double P[][3], uint32_t style_index) { if(n==0 || P==NULL) return; PRCgroup &group = findGroup(); PRCPointSet *pointset = new PRCPointSet(); group.pointsets.push_back(pointset); pointset->index_of_line_style = style_index; pointset->point.reserve(n); for(uint32_t i=0; ipoint.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2])); } void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale) { PRCgroup &group = findGroup(); PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel(); polyBrepModel->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale); polyBrepModel->index_tessellation = tess_index; polyBrepModel->is_closed = group.options.closed; polyBrepModel->index_of_line_style = style_index; group.polymodels.push_back(polyBrepModel); } void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double* t) { PRCgroup &group = findGroup(); PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel(); polyBrepModel->index_local_coordinate_system = addTransform(t); polyBrepModel->index_tessellation = tess_index; polyBrepModel->is_closed = group.options.closed; polyBrepModel->index_of_line_style = style_index; group.polymodels.push_back(polyBrepModel); } void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale) { PRCgroup &group = findGroup(); PRCPolyWire *polyWire = new PRCPolyWire(); polyWire->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale); polyWire->index_tessellation = tess_index; polyWire->index_of_line_style = style_index; group.polywires.push_back(polyWire); } void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double* t) { PRCgroup &group = findGroup(); PRCPolyWire *polyWire = new PRCPolyWire(); polyWire->index_local_coordinate_system = addTransform(t); polyWire->index_tessellation = tess_index; polyWire->index_of_line_style = style_index; group.polywires.push_back(polyWire); } void oPRCFile::addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m, uint32_t nN, const double N[][3], const uint32_t NI[][3], uint32_t nT, const double T[][2], const uint32_t TI[][3], uint32_t nC, const RGBAColour C[], const uint32_t CI[][3], uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return; const uint32_t tess_index = createTriangleMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI, ca); useMesh(tess_index,m1); } uint32_t oPRCFile::createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const uint32_t style_index, uint32_t nN, const double N[][3], const uint32_t NI[][3], uint32_t nT, const double T[][2], const uint32_t TI[][3], uint32_t nC, const RGBAColour C[], const uint32_t CI[][3], uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return m1; const bool triangle_color = (nS != 0 && S != NULL && SI != NULL); const bool vertex_color = (nC != 0 && C != NULL && CI != NULL); const bool has_normals = (nN != 0 && N != NULL && NI != NULL); const bool textured = (nT != 0 && T != NULL && TI != NULL); PRC3DTess *tess = new PRC3DTess(); PRCTessFace *tessFace = new PRCTessFace(); tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle; tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0; tess->coordinates.reserve(3*nP); for(uint32_t i=0; icoordinates.push_back(P[i][0]); tess->coordinates.push_back(P[i][1]); tess->coordinates.push_back(P[i][2]); } if(has_normals) { tess->normal_coordinate.reserve(3*nN); for(uint32_t i=0; inormal_coordinate.push_back(N[i][0]); tess->normal_coordinate.push_back(N[i][1]); tess->normal_coordinate.push_back(N[i][2]); } } else tess->crease_angle = ca; if(textured) { tess->texture_coordinate.reserve(2*nT); for(uint32_t i=0; itexture_coordinate.push_back(T[i][0]); tess->texture_coordinate.push_back(T[i][1]); } } tess->triangulated_index.reserve(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI); for(uint32_t i=0; itriangulated_index.push_back(3*NI[i][0]); if(textured) tess->triangulated_index.push_back(2*TI[i][0]); tess->triangulated_index.push_back(3*PI[i][0]); if(has_normals) tess->triangulated_index.push_back(3*NI[i][1]); if(textured) tess->triangulated_index.push_back(2*TI[i][1]); tess->triangulated_index.push_back(3*PI[i][1]); if(has_normals) tess->triangulated_index.push_back(3*NI[i][2]); if(textured) tess->triangulated_index.push_back(2*TI[i][2]); tess->triangulated_index.push_back(3*PI[i][2]); } tessFace->sizes_triangulated.push_back(nI); if(triangle_color) { tessFace->line_attributes.reserve(nI); for(uint32_t i=0; iline_attributes.push_back(SI[i]); } else if (style_index != m1 ) { tessFace->line_attributes.push_back(style_index); } if(vertex_color) { tessFace->is_rgba=false; for(uint32_t i=0; iis_rgba=true; break; } tessFace->rgba_vertices.reserve((tessFace->is_rgba?4:3)*3*nI); for(uint32_t i=0; irgba_vertices.push_back(toByte(C[CI[i][0]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][0]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][0]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][0]].A)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].A)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].A)); } } tess->addTessFace(tessFace); const uint32_t tess_index = add3DTess(tess); return tess_index; } void oPRCFile::addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m, uint32_t nN, const double N[][3], const uint32_t NI[][4], uint32_t nT, const double T[][2], const uint32_t TI[][4], uint32_t nC, const RGBAColour C[], const uint32_t CI[][4], uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return; const uint32_t tess_index = createQuadMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI, ca); useMesh(tess_index,m1); } uint32_t oPRCFile::createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index, uint32_t nN, const double N[][3], const uint32_t NI[][4], uint32_t nT, const double T[][2], const uint32_t TI[][4], uint32_t nC, const RGBAColour C[], const uint32_t CI[][4], uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return m1; const bool triangle_color = (nS != 0 && S != NULL && SI != NULL); const bool vertex_color = (nC != 0 && C != NULL && CI != NULL); const bool has_normals = (nN != 0 && N != NULL && NI != NULL); const bool textured = (nT != 0 && T != NULL && TI != NULL); PRC3DTess *tess = new PRC3DTess(); PRCTessFace *tessFace = new PRCTessFace(); tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle; tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0; tess->coordinates.reserve(3*nP); for(uint32_t i=0; icoordinates.push_back(P[i][0]); tess->coordinates.push_back(P[i][1]); tess->coordinates.push_back(P[i][2]); } if(has_normals) { tess->normal_coordinate.reserve(3*nN); for(uint32_t i=0; inormal_coordinate.push_back(N[i][0]); tess->normal_coordinate.push_back(N[i][1]); tess->normal_coordinate.push_back(N[i][2]); } } else tess->crease_angle = ca; if(textured) { tess->texture_coordinate.reserve(2*nT); for(uint32_t i=0; itexture_coordinate.push_back(T[i][0]); tess->texture_coordinate.push_back(T[i][1]); } } tess->triangulated_index.reserve(2*(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI)); for(uint32_t i=0; itriangulated_index.push_back(3*NI[i][0]); if(textured) tess->triangulated_index.push_back(2*TI[i][0]); tess->triangulated_index.push_back(3*PI[i][0]); if(has_normals) tess->triangulated_index.push_back(3*NI[i][1]); if(textured) tess->triangulated_index.push_back(2*TI[i][1]); tess->triangulated_index.push_back(3*PI[i][1]); if(has_normals) tess->triangulated_index.push_back(3*NI[i][3]); if(textured) tess->triangulated_index.push_back(2*TI[i][3]); tess->triangulated_index.push_back(3*PI[i][3]); // second triangle if(has_normals) tess->triangulated_index.push_back(3*NI[i][1]); if(textured) tess->triangulated_index.push_back(2*TI[i][1]); tess->triangulated_index.push_back(3*PI[i][1]); if(has_normals) tess->triangulated_index.push_back(3*NI[i][2]); if(textured) tess->triangulated_index.push_back(2*TI[i][2]); tess->triangulated_index.push_back(3*PI[i][2]); if(has_normals) tess->triangulated_index.push_back(3*NI[i][3]); if(textured) tess->triangulated_index.push_back(2*TI[i][3]); tess->triangulated_index.push_back(3*PI[i][3]); } tessFace->sizes_triangulated.push_back(2*nI); if(triangle_color) { tessFace->line_attributes.reserve(2*nI); for(uint32_t i=0; iline_attributes.push_back(SI[i]); tessFace->line_attributes.push_back(SI[i]); } } else { tessFace->line_attributes.push_back(style_index); } if(vertex_color) { tessFace->is_rgba=false; for(uint32_t i=0; iis_rgba=true; break; } tessFace->rgba_vertices.reserve(2*(tessFace->is_rgba?4:3)*3*nI); for(uint32_t i=0; irgba_vertices.push_back(toByte(C[CI[i][0]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][0]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][0]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][0]].A)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].A)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].A)); // second triangle tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][1]].A)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][2]].A)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].R)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].G)); tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].B)); if(tessFace->is_rgba) tessFace->rgba_vertices.push_back(toByte(C[CI[i][3]].A)); } } tess->addTessFace(tessFace); const uint32_t tess_index = add3DTess(tess); return tess_index; } void oPRCFile::addQuad(const double P[][3], const RGBAColour C[]) { PRCgroup &group = findGroup(); group.quads.push_back(PRCtessquad()); PRCtessquad &quad = group.quads.back(); for(size_t i = 0; i < 4; i++) { quad.vertices[i].x = P[i][0]; quad.vertices[i].y = P[i][1]; quad.vertices[i].z = P[i][2]; quad.colours[i] = C[i]; } } /* void oPRCFile::addTriangle(const double P[][3], const double T[][2], uint32_t style_index) { PRCgroup &group = findGroup(); group.triangles.push_back(PRCtesstriangle()); PRCtesstriangle &triangle = group.triangles.back(); for(size_t i = 0; i < 3; i++) { triangle.vertices[i].x = P[i][0]; triangle.vertices[i].y = P[i][1]; triangle.vertices[i].z = P[i][2]; triangle.texcoords[i].x = T[i][0]; triangle.texcoords[i].y = T[i][1]; } triangle.style = style_index; } */ void oPRCFile::addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[], const RGBAColour& c, double w, bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return; const uint32_t tess_index = createLines(nP, P, nI, PI, segment_color, nC, C, nCI, CI); useLines(tess_index, c, w); } uint32_t oPRCFile::createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[], bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return m1; const bool vertex_color = (nC != 0 && C != NULL && CI != NULL); PRC3DWireTess *tess = new PRC3DWireTess(); tess->coordinates.reserve(3*nP); for(uint32_t i=0; icoordinates.push_back(P[i][0]); tess->coordinates.push_back(P[i][1]); tess->coordinates.push_back(P[i][2]); } tess->wire_indexes.reserve(nI); for(uint32_t i=0; iwire_indexes.push_back(PI[i]); const uint32_t ni = i+PI[i]+1; for(i++; iwire_indexes.push_back(3*PI[i]); } if(vertex_color) { tess->is_segment_color = segment_color; tess->is_rgba=false; for(uint32_t i=0; iis_rgba=true; break; } tess->rgba_vertices.reserve((tess->is_rgba?4:3)*nCI); for(uint32_t i=0; irgba_vertices.push_back(toByte(C[CI[i]].R)); tess->rgba_vertices.push_back(toByte(C[CI[i]].G)); tess->rgba_vertices.push_back(toByte(C[CI[i]].B)); if(tess->is_rgba) tess->rgba_vertices.push_back(toByte(C[CI[i]].A)); } } const uint32_t tess_index = add3DWireTess(tess); return tess_index; } uint32_t oPRCFile::createSegments(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][2], bool segment_color, uint32_t nC, const RGBAColour C[], const uint32_t CI[][2]) { if(nP==0 || P==NULL || nI==0 || PI==NULL) return m1; const bool vertex_color = (nC != 0 && C != NULL && CI != NULL); PRC3DWireTess *tess = new PRC3DWireTess(); tess->coordinates.reserve(3*nP); for(uint32_t i=0; icoordinates.push_back(P[i][0]); tess->coordinates.push_back(P[i][1]); tess->coordinates.push_back(P[i][2]); } tess->wire_indexes.reserve(3*nI); for(uint32_t i=0; iwire_indexes.push_back(2); tess->wire_indexes.push_back(3*PI[i][0]); tess->wire_indexes.push_back(3*PI[i][1]); } if(vertex_color) { tess->is_segment_color = segment_color; tess->is_rgba=false; for(uint32_t i=0; iis_rgba=true; break; } tess->rgba_vertices.reserve((tess->is_rgba?4:3)*(segment_color?1:2)*nI); for(uint32_t i=0; irgba_vertices.push_back(toByte(0.5*C[CI[i][0]].R+0.5*C[CI[i][1]].R)); tess->rgba_vertices.push_back(toByte(0.5*C[CI[i][0]].G+0.5*C[CI[i][1]].G)); tess->rgba_vertices.push_back(toByte(0.5*C[CI[i][0]].B+0.5*C[CI[i][1]].B)); if(tess->is_rgba) tess->rgba_vertices.push_back(toByte(0.5*C[CI[i][0]].A+0.5*C[CI[i][1]].A)); } else { tess->rgba_vertices.push_back(toByte(C[CI[i][0]].R)); tess->rgba_vertices.push_back(toByte(C[CI[i][0]].G)); tess->rgba_vertices.push_back(toByte(C[CI[i][0]].B)); if(tess->is_rgba) tess->rgba_vertices.push_back(toByte(C[CI[i][0]].A)); tess->rgba_vertices.push_back(toByte(C[CI[i][1]].R)); tess->rgba_vertices.push_back(toByte(C[CI[i][1]].G)); tess->rgba_vertices.push_back(toByte(C[CI[i][1]].B)); if(tess->is_rgba) tess->rgba_vertices.push_back(toByte(C[CI[i][1]].A)); } } } const uint32_t tess_index = add3DWireTess(tess); return tess_index; } void oPRCFile::addLine(uint32_t n, const double P[][3], const RGBAColour &c, double w) { PRCgroup &group = findGroup(); if(group.options.tess) { group.lines[w].push_back(PRCtessline()); PRCtessline& line = group.lines[w].back(); line.color.red = c.R; line.color.green = c.G; line.color.blue = c.B; for(uint32_t i=0; ipoint.resize(n); for(uint32_t i=0; ipoint[i].Set(P[i][0],P[i][1],P[i][2]); curve->interval.min = 0; curve->interval.max = curve->point.size()-1; } } void oPRCFile::addSegment(const double P1[3], const double P2[3], const RGBAColour &c, double w) { PRCgroup &group = findGroup(); if(group.options.tess) { group.lines[w].push_back(PRCtessline()); PRCtessline& line = group.lines[w].back(); line.color.red = c.R; line.color.green = c.G; line.color.blue = c.B; line.point.push_back(PRCVector3d(P1[0],P1[1],P1[2])); line.point.push_back(PRCVector3d(P2[0],P2[1],P2[2])); } else { ADDWIRE(PRCPolyLine) curve->point.resize(2); curve->point[0].Set(P1[0],P1[1],P1[2]); curve->point[1].Set(P2[0],P2[1],P2[2]); curve->interval.min = 0; curve->interval.max = curve->point.size()-1; } } void oPRCFile::addBezierCurve(uint32_t n, const double cP[][3], const RGBAColour &c) { ADDWIRE(PRCNURBSCurve) curve->is_rational = false; curve->degree = 3; const size_t NUMBER_OF_POINTS = n; curve->control_point.resize(NUMBER_OF_POINTS); for(size_t i = 0; i < NUMBER_OF_POINTS; ++i) curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]); curve->knot.resize(3+NUMBER_OF_POINTS+1); curve->knot[0] = 1; for(size_t i = 1; i < 3+NUMBER_OF_POINTS; ++i) curve->knot[i] = (i+2)/3; // integer division is intentional curve->knot[3+NUMBER_OF_POINTS] = (3+NUMBER_OF_POINTS+1)/3; } void oPRCFile::addCurve(uint32_t d, uint32_t n, const double cP[][3], const double *k, const RGBAColour &c, const double w[]) { ADDWIRE(PRCNURBSCurve) curve->is_rational = (w!=NULL); curve->degree = d; curve->control_point.resize(n); for(uint32_t i = 0; i < n; i++) if(w) curve->control_point[i].Set(cP[i][0]*w[i],cP[i][1]*w[i],cP[i][2]*w[i],w[i]); else curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]); curve->knot.resize(d+n+1); for(uint32_t i = 0; i < d+n+1; i++) curve->knot[i] = k[i]; } void oPRCFile::addRectangle(const double P[][3], const PRCmaterial &m) { PRCgroup &group = findGroup(); if(group.options.tess) { group.rectangles.push_back(PRCtessrectangle()); PRCtessrectangle &rectangle = group.rectangles.back(); rectangle.style = addMaterial(m); for(size_t i = 0; i < 4; i++) { rectangle.vertices[i].x = P[i][0]; rectangle.vertices[i].y = P[i][1]; rectangle.vertices[i].z = P[i][2]; } } else if(group.options.compression == 0.0) { ADDFACE(PRCNURBSSurface) surface->is_rational = false; surface->degree_in_u = 1; surface->degree_in_v = 1; surface->control_point.resize(4); for(size_t i = 0; i < 4; ++i) { surface->control_point[i].x = P[i][0]; surface->control_point[i].y = P[i][1]; surface->control_point[i].z = P[i][2]; } surface->knot_u.resize(4); surface->knot_v.resize(4); surface->knot_v[0] = surface->knot_u[0] = 1; surface->knot_v[1] = surface->knot_u[1] = 3; surface->knot_v[2] = surface->knot_u[2] = 4; surface->knot_v[3] = surface->knot_u[3] = 4; } else { ADDCOMPFACE compface->degree = 1; compface->control_point.resize(4); for(size_t i = 0; i < 4; ++i) { compface->control_point[i].x = P[i][0]; compface->control_point[i].y = P[i][1]; compface->control_point[i].z = P[i][2]; } } } void oPRCFile::addPatch(const double cP[][3], const PRCmaterial &m) { PRCgroup &group = findGroup(); if(group.options.compression == 0.0) { ADDFACE(PRCNURBSSurface) surface->is_rational = false; surface->degree_in_u = 3; surface->degree_in_v = 3; surface->control_point.resize(16); for(size_t i = 0; i < 16; ++i) { surface->control_point[i].x = cP[i][0]; surface->control_point[i].y = cP[i][1]; surface->control_point[i].z = cP[i][2]; } surface->knot_u.resize(8); surface->knot_v.resize(8); surface->knot_v[0] = surface->knot_u[0] = 1; surface->knot_v[1] = surface->knot_u[1] = 1; surface->knot_v[2] = surface->knot_u[2] = 1; surface->knot_v[3] = surface->knot_u[3] = 1; surface->knot_v[4] = surface->knot_u[4] = 2; surface->knot_v[5] = surface->knot_u[5] = 2; surface->knot_v[6] = surface->knot_u[6] = 2; surface->knot_v[7] = surface->knot_u[7] = 2; } else { ADDCOMPFACE compface->degree = 3; compface->control_point.resize(16); for(size_t i = 0; i < 16; ++i) { compface->control_point[i].x = cP[i][0]; compface->control_point[i].y = cP[i][1]; compface->control_point[i].z = cP[i][2]; } } } void oPRCFile::addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV, const double cP[][3], const double *kU, const double *kV, const PRCmaterial &m, const double w[]) { ADDFACE(PRCNURBSSurface) surface->is_rational = (w!=NULL); surface->degree_in_u = dU; surface->degree_in_v = dV; surface->control_point.resize(nU*nV); for(size_t i = 0; i < nU*nV; i++) if(w) surface->control_point[i]=PRCControlPoint(cP[i][0]*w[i],cP[i][1]*w[i],cP[i][2]*w[i],w[i]); else surface->control_point[i]=PRCControlPoint(cP[i][0],cP[i][1],cP[i][2]); surface->knot_u.insert(surface->knot_u.end(), kU, kU+(dU+nU+1)); surface->knot_v.insert(surface->knot_v.end(), kV, kV+(dV+nV+1)); } #define SETTRANSF \ if(t&&!isid(t)) \ face.transform = new PRCGeneralTransformation3d(t); \ if(origin) surface->origin.Set(origin[0],origin[1],origin[2]); \ if(x_axis) surface->x_axis.Set(x_axis[0],x_axis[1],x_axis[2]); \ if(y_axis) surface->y_axis.Set(y_axis[0],y_axis[1],y_axis[2]); \ surface->scale = scale; \ surface->geometry_is_2D = false; \ if(surface->origin!=PRCVector3d(0.0,0.0,0.0)) \ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Translate; \ if(surface->x_axis!=PRCVector3d(1.0,0.0,0.0)||surface->y_axis!=PRCVector3d(0.0,1.0,0.0)) \ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Rotate; \ if(surface->scale!=1) \ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Scale; \ surface->has_transformation = (surface->behaviour != PRC_TRANSFORMATION_Identity); #define PRCFACETRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale, const double* t void oPRCFile::addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCBlend01) SETTRANSF if(straight) { PRCPolyLine *center_curve = new PRCPolyLine; center_curve->point.resize(n); for(uint32_t i=0; ipoint[i].Set(cP[i][0],cP[i][1],cP[i][2]); center_curve->interval.min = 0; center_curve->interval.max = center_curve->point.size()-1; surface->center_curve = center_curve; PRCPolyLine *origin_curve = new PRCPolyLine; origin_curve->point.resize(n); for(uint32_t i=0; ipoint[i].Set(oP[i][0],oP[i][1],oP[i][2]); origin_curve->interval.min = 0; origin_curve->interval.max = origin_curve->point.size()-1; surface->origin_curve = origin_curve; surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 2*pi; surface->uv_domain.min.y = 0; surface->uv_domain.max.y = n-1; } else { PRCNURBSCurve *center_curve = new PRCNURBSCurve; center_curve->is_rational = false; center_curve->degree = 3; const uint32_t CENTER_NUMBER_OF_POINTS = n; center_curve->control_point.resize(CENTER_NUMBER_OF_POINTS); for(uint32_t i = 0; i < CENTER_NUMBER_OF_POINTS; ++i) center_curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]); center_curve->knot.resize(3+CENTER_NUMBER_OF_POINTS+1); center_curve->knot[0] = 1; for(uint32_t i = 1; i < 3+CENTER_NUMBER_OF_POINTS; ++i) center_curve->knot[i] = (i+2)/3; // integer division is intentional center_curve->knot[3+CENTER_NUMBER_OF_POINTS] = (3+CENTER_NUMBER_OF_POINTS+1)/3; surface->center_curve = center_curve; PRCNURBSCurve *origin_curve = new PRCNURBSCurve; origin_curve->is_rational = false; origin_curve->degree = 3; const uint32_t ORIGIN_NUMBER_OF_POINTS = n; origin_curve->control_point.resize(ORIGIN_NUMBER_OF_POINTS); for(uint32_t i = 0; i < ORIGIN_NUMBER_OF_POINTS; ++i) origin_curve->control_point[i].Set(oP[i][0],oP[i][1],oP[i][2]); origin_curve->knot.resize(3+ORIGIN_NUMBER_OF_POINTS+1); origin_curve->knot[0] = 1; for(size_t i = 1; i < 3+ORIGIN_NUMBER_OF_POINTS; ++i) origin_curve->knot[i] = (i+2)/3; // integer division is intentional origin_curve->knot[3+ORIGIN_NUMBER_OF_POINTS] = (3+ORIGIN_NUMBER_OF_POINTS+1)/3; surface->origin_curve = origin_curve; surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 2*pi; surface->uv_domain.min.y = 1; // first knot surface->uv_domain.max.y = (3+CENTER_NUMBER_OF_POINTS+1)/3; // last knot } } void oPRCFile::addHemisphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCSphere) SETTRANSF surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 2*pi; surface->uv_domain.min.y = 0; surface->uv_domain.max.y = 0.5*pi; surface->radius = radius; } void oPRCFile::addSphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCSphere) SETTRANSF surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 2*pi; surface->uv_domain.min.y =-0.5*pi; surface->uv_domain.max.y = 0.5*pi; surface->radius = radius; } void oPRCFile::addDisk(double radius, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCRuled) SETTRANSF PRCCircle *first_curve = new PRCCircle; first_curve->radius = radius; surface->first_curve = first_curve; PRCCircle *second_curve = new PRCCircle; second_curve->radius = 0; surface->second_curve = second_curve; surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 1; surface->uv_domain.min.y = 0; surface->uv_domain.max.y = 2*pi; surface->parameterization_on_v_coeff_a = -1; surface->parameterization_on_v_coeff_b = 2*pi; } void oPRCFile::addCylinder(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCCylinder) SETTRANSF surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 2*pi; surface->uv_domain.min.y = (height>0)?0:height; surface->uv_domain.max.y = (height>0)?height:0; surface->radius = radius; } void oPRCFile::addCone(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCCone) SETTRANSF surface->uv_domain.min.x = 0; surface->uv_domain.max.x = 2*pi; surface->uv_domain.min.y = (height>0)?0:height; surface->uv_domain.max.y = (height>0)?height:0; surface->bottom_radius = radius; surface->semi_angle = -atan(radius/height);; } void oPRCFile::addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial &m, PRCFACETRANSFORM) { ADDFACE(PRCTorus) SETTRANSF surface->uv_domain.min.x = (angle1/180)*pi; surface->uv_domain.max.x = (angle2/180)*pi; surface->uv_domain.min.y = 0; surface->uv_domain.max.y = 2*pi; surface->major_radius = major_radius; surface->minor_radius = minor_radius; } #undef PRCFACETRANSFORM #undef ADDFACE #undef ADDWIRE #undef SETTRANSF uint32_t PRCFileStructure::addRgbColor(double r, double g, double b) { const PRCRgbColor color(r, g, b); colors.push_back(color); return 3*(colors.size()-1); } uint32_t PRCFileStructure::addRgbColorUnique(double r, double g, double b) { const PRCRgbColor color(r, g, b); uint32_t color_index = m1; PRCRgbColorMap::const_iterator iRgbColor = colorMap.find(color); if(iRgbColor!=colorMap.end()) { color_index = iRgbColor->second; } else { color_index = 3*colors.size(); colors.push_back(color); colorMap.insert(make_pair(color,color_index)); } return color_index; } #define ADD_ADDUNIQ( prctype, prcmap, prclist) \ uint32_t PRCFileStructure::add##prctype(PRC##prctype *& p##prctype) \ { \ prclist.push_back(p##prctype); \ p##prctype = NULL; \ return prclist.size()-1; \ } \ \ uint32_t PRCFileStructure::add##prctype##Unique(PRC##prctype*& p##prctype) \ { \ uint32_t prc_index = m1; \ PRC##prctype##Map::const_iterator i##prctype = prcmap.find(p##prctype); \ if(i##prctype!=prcmap.end()) \ { \ delete p##prctype; \ prc_index = i##prctype->second; \ } \ else \ { \ prc_index = prclist.size(); \ prclist.push_back(p##prctype); \ prcmap.insert(make_pair(p##prctype,prc_index)); \ } \ p##prctype = NULL; \ return prc_index; \ } ADD_ADDUNIQ(UncompressedFile, uncompressedfileMap, uncompressed_files ) ADD_ADDUNIQ(Picture, pictureMap, pictures ) ADD_ADDUNIQ(TextureDefinition, texturedefinitionMap, texture_definitions ) ADD_ADDUNIQ(MaterialGeneric, materialgenericMap, materials ) ADD_ADDUNIQ(TextureApplication, textureapplicationMap, materials ) ADD_ADDUNIQ(Style, styleMap, styles ) #undef ADD_ADDUNIQ uint32_t PRCFileStructure::addPartDefinition(PRCPartDefinition*& pPartDefinition) { part_definitions.push_back(pPartDefinition); pPartDefinition = NULL; return part_definitions.size()-1; } uint32_t PRCFileStructure::addProductOccurrence(PRCProductOccurrence*& pProductOccurrence) { product_occurrences.push_back(pProductOccurrence); pProductOccurrence = NULL; return product_occurrences.size()-1; } uint32_t PRCFileStructure::addTopoContext(PRCTopoContext*& pTopoContext) { contexts.push_back(pTopoContext); pTopoContext = NULL; return contexts.size()-1; } uint32_t PRCFileStructure::getTopoContext(PRCTopoContext*& pTopoContext) { pTopoContext = new PRCTopoContext; contexts.push_back(pTopoContext); return contexts.size()-1; } uint32_t PRCFileStructure::add3DTess(PRC3DTess*& p3DTess) { tessellations.push_back(p3DTess); p3DTess = NULL; return tessellations.size()-1; } uint32_t PRCFileStructure::add3DWireTess(PRC3DWireTess*& p3DWireTess) { tessellations.push_back(p3DWireTess); p3DWireTess = NULL; return tessellations.size()-1; } /* uint32_t PRCFileStructure::addMarkupTess(PRCMarkupTess*& pMarkupTess) { tessellations.push_back(pMarkupTess); pMarkupTess = NULL; return tessellations.size()-1; } uint32_t PRCFileStructure::addMarkup(PRCMarkup*& pMarkup) { markups.push_back(pMarkup); pMarkup = NULL; return markups.size()-1; } uint32_t PRCFileStructure::addAnnotationItem(PRCAnnotationItem*& pAnnotationItem) { annotation_entities.push_back(pAnnotationItem); pAnnotationItem = NULL; return annotation_entities.size()-1; } */ uint32_t PRCFileStructure::addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem) { reference_coordinate_systems.push_back(pCoordinateSystem); pCoordinateSystem = NULL; return reference_coordinate_systems.size()-1; } uint32_t PRCFileStructure::addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem) { for(uint32_t i = 0; i < reference_coordinate_systems.size(); ++i) { if(*(reference_coordinate_systems[i])==*pCoordinateSystem) { pCoordinateSystem = NULL; return i; } } reference_coordinate_systems.push_back(pCoordinateSystem); pCoordinateSystem = NULL; return reference_coordinate_systems.size()-1; } mathgl-2.4.4/src/prc/writePRC.h0000644000175000017500000014726113513030041016403 0ustar alastairalastair/************ * * This file is part of a tool for producing 3D content in the PRC format. * Copyright (C) 2008 Orest Shardt * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * *************/ #ifndef __WRITE_PRC_H #define __WRITE_PRC_H #include #include #include #include #include #include #include #include "PRCbitStream.h" #include "PRC.h" #include #include static const uint32_t m1=(uint32_t)-1; static const double pi=acos(-1.0); class PRCVector3d { public : double x; double y; double z; PRCVector3d() : x(0), y(0), z(0) {} PRCVector3d(double fx, double fy, double fz) : x(fx), y(fy), z(fz) {} PRCVector3d(const double c[], double fx=0, double fy=0, double fz=0) : x(c?c[0]:fx), y(c?c[1]:fy), z(c?c[2]:fz) {} PRCVector3d(const PRCVector3d& sVector3d) : x(sVector3d.x), y(sVector3d.y), z(sVector3d.z) {} void Set(double fx, double fy, double fz) { x = fx; y = fy; z = fz; } double Dot(const PRCVector3d & sPt) const { return(x*sPt.x)+(y*sPt.y)+(z*sPt.z); } double LengthSquared() { return(x*x+y*y+z*z); } friend PRCVector3d operator + (const PRCVector3d& a, const PRCVector3d& b) { return PRCVector3d(a.x+b.x,a.y+b.y,a.z+b.z); } friend PRCVector3d operator - (const PRCVector3d& a) { return PRCVector3d(-a.x,-a.y,-a.z); } friend PRCVector3d operator - (const PRCVector3d& a, const PRCVector3d& b) { return PRCVector3d(a.x-b.x,a.y-b.y,a.z-b.z); } friend PRCVector3d operator * (const PRCVector3d& a, const double d) { return PRCVector3d(a.x*d,a.y*d,a.z*d); } friend PRCVector3d operator * (const double d, const PRCVector3d& a) { return PRCVector3d(a.x*d,a.y*d,a.z*d); } friend PRCVector3d operator / (const PRCVector3d& a, const double d) { return PRCVector3d(a.x/d,a.y/d,a.z/d); } friend PRCVector3d operator * (const PRCVector3d& a, const PRCVector3d& b) { return PRCVector3d((a.y*b.z)-(a.z*b.y), (a.z*b.x)-(a.x*b.z), (a.x*b.y)-(a.y*b.x)); } void write(PRCbitStream &out) { out << x << y << z; } void serializeVector3d(PRCbitStream &pbs) const { pbs << x << y << z; } void serializeVector2d(PRCbitStream &pbs) const { pbs << x << y; } double Length(); bool Normalize(); bool operator==(const PRCVector3d &v) const { return x==v.x && y==v.y && z==v.z; } bool operator!=(const PRCVector3d &v) const { return !(x==v.x && y==v.y && z==v.z); } bool operator<(const PRCVector3d &v) const { if(x!=v.x) return (x attribute_keys; }; typedef std::list PRCAttributeList; class PRCAttributes { public: void serializeAttributes(PRCbitStream&) const; PRCAttribute& newAttribute() { attributes.push_front(PRCAttribute()); return attributes.front(); } void addAttribute(const PRCAttribute &attribute) { attributes.push_front(attribute); } PRCAttributeList attributes; }; bool type_eligible_for_reference(uint32_t type); uint32_t makeCADID(); uint32_t makePRCID(); class ContentPRCBase : public PRCAttributes { public: ContentPRCBase(uint32_t t, std::string n="") : type(t),name(n),CAD_identifier(0), CAD_persistent_identifier(0), PRC_unique_identifier(0) { if(type_eligible_for_reference(type)) { CAD_identifier = makeCADID(); PRC_unique_identifier = makePRCID(); } } void serializeContentPRCBase(PRCbitStream&) const; uint32_t getPRCID() const { return PRC_unique_identifier; } uint32_t getType() const { return type; } uint32_t type; std::string name; uint32_t CAD_identifier, CAD_persistent_identifier, PRC_unique_identifier; }; class PRCReferenceUniqueIdentifier { public: PRCReferenceUniqueIdentifier() : type(0), unique_identifier(m1) {} void serializeReferenceUniqueIdentifier(PRCbitStream&); uint32_t type; // bool reference_in_same_file_structure; // PRCUniqueId target_file_structure; uint32_t unique_identifier; }; extern std::string currentName; void writeName(PRCbitStream&,const std::string&); void resetName(); extern uint32_t current_layer_index; extern uint32_t current_index_of_line_style; extern uint16_t current_behaviour_bit_field; void writeGraphics(PRCbitStream&,uint32_t=m1,uint32_t=m1,uint16_t=1,bool=false); void resetGraphics(); void resetGraphicsAndName(); struct PRCVector2d { PRCVector2d() : x(0.0), y(0.0) {} PRCVector2d(double X, double Y) : x(X), y(Y) {} void serializeVector2d(PRCbitStream&); double x; double y; PRCVector2d(const double c[], double fx=0, double fy=0) : x(c?c[0]:fx), y(c?c[1]:fy) {} PRCVector2d(const PRCVector2d& sVector2d) : x(sVector2d.x), y(sVector2d.y) {} void Set(double fx, double fy) { x = fx; y = fy; } double Dot(const PRCVector2d & sPt) const { return(x*sPt.x)+(y*sPt.y); } double LengthSquared() { return(x*x+y*y); } friend PRCVector2d operator + (const PRCVector2d& a, const PRCVector2d& b) { return PRCVector2d(a.x+b.x,a.y+b.y); } friend PRCVector2d operator - (const PRCVector2d& a) { return PRCVector2d(-a.x,-a.y); } friend PRCVector2d operator - (const PRCVector2d& a, const PRCVector2d& b) { return PRCVector2d(a.x-b.x,a.y-b.y); } friend PRCVector2d operator * (const PRCVector2d& a, const double d) { return PRCVector2d(a.x*d,a.y*d); } friend PRCVector2d operator * (const double d, const PRCVector2d& a) { return PRCVector2d(a.x*d,a.y*d); } friend PRCVector2d operator / (const PRCVector2d& a, const double d) { return PRCVector2d(a.x/d,a.y/d); } double Length(); bool Normalize(); bool operator==(const PRCVector2d &v) const { return x==v.x && y==v.y; } bool operator!=(const PRCVector2d &v) const { return !(x==v.x && y==v.y); } bool operator<(const PRCVector2d &v) const { if(x!=v.x) return (x \ { bool operator()(const PRCtype* Left, const PRCtype* Right) const { return (*Left < *Right); } }; \ typedef std::map PRCtype##Map; #define PRCLIST(PRCtype) \ typedef std::deque PRCtype##List; struct PRCRgbColor { PRCRgbColor(double r=0.0, double g=0.0, double b=0.0) : red(r), green(g), blue(b) {} double red,green,blue; void serializeRgbColor(PRCbitStream&); bool operator==(const PRCRgbColor &c) const { return (EQFLD(red) && EQFLD(green) && EQFLD(blue) ); } bool operator!=(const PRCRgbColor &c) const { return !(EQFLD(red) && EQFLD(green) && EQFLD(blue) ); } bool operator<(const PRCRgbColor &c) const { COMPFLD(red) COMPFLD(green) COMPFLD(blue) return false; } }; typedef std::map PRCRgbColorMap; typedef std::deque PRCRgbColorList; class PRCUncompressedFile { public: PRCUncompressedFile() {} PRCUncompressedFile(uint32_t fs, uint8_t *d) { file_contents.assign( d, d + fs ); } std::vector file_contents; void serializeUncompressedFile(std::ostream&) const; uint32_t getSize() const; bool operator==(const PRCUncompressedFile& c) const { return file_contents==c.file_contents; } bool operator<(const PRCUncompressedFile& c) const { return file_contents lengths; double phase; bool is_real_length; }; typedef std::deque PRCLinePatternList; class PRCStyle : public ContentPRCBase { public: PRCStyle(std::string n="") : ContentPRCBase(PRC_TYPE_GRAPH_Style,n), line_width(0.0), is_vpicture(false), line_pattern_vpicture_index(m1), is_material(false), color_material_index(m1), is_transparency_defined(false), transparency(255), additional(0) {} void serializeCategory1LineStyle(PRCbitStream&); double line_width; bool is_vpicture; uint32_t line_pattern_vpicture_index; bool is_material; uint32_t color_material_index; bool is_transparency_defined; uint8_t transparency; uint8_t additional; bool operator==(const PRCStyle& c) const { return (EQFLD(line_width) && EQFLD(is_vpicture) && EQFLD(line_pattern_vpicture_index) && EQFLD(is_material) && EQFLD(color_material_index) && EQFLD(is_transparency_defined) && EQFLD(transparency) && EQFLD(additional) && EQFLD(name) ); } bool operator<(const PRCStyle& c) const { COMPFLD(line_width) COMPFLD(is_vpicture) COMPFLD(line_pattern_vpicture_index) COMPFLD(is_material) COMPFLD(color_material_index) COMPFLD(is_transparency_defined) COMPFLD(transparency) COMPFLD(additional) COMPFLD(name) return false; } }; PRCLIST(PRCStyle) PRCMAP(PRCStyle) #undef EQFLD #undef COMPFLD #undef PRCMAP class PRCTessFace { public: PRCTessFace() : start_wire(0), used_entities_flag(0), start_triangulated(0), number_of_texture_coordinate_indexes(0), is_rgba(false), behaviour(PRC_GRAPHICS_Show) {} void serializeTessFace(PRCbitStream&); std::vector line_attributes; uint32_t start_wire; // specifing bounding wire seems not to work as of Acrobat/Reader 9.2 std::vector sizes_wire; // specifing bounding wire seems not to work as of Acrobat/Reader 9.2 uint32_t used_entities_flag; uint32_t start_triangulated; std::vector sizes_triangulated; uint32_t number_of_texture_coordinate_indexes; bool is_rgba; std::vector rgba_vertices; uint32_t behaviour; }; typedef std::deque PRCTessFaceList; class PRCContentBaseTessData { public: PRCContentBaseTessData() : is_calculated(false) {} void serializeContentBaseTessData(PRCbitStream&); bool is_calculated; std::vector coordinates; }; class PRCTess : public PRCContentBaseTessData { public: virtual ~PRCTess() {} virtual void serializeBaseTessData(PRCbitStream &pbs) = 0; }; typedef std::deque PRCTessList; class PRC3DTess : public PRCTess { public: PRC3DTess() : has_faces(false), has_loops(false), crease_angle(25.8419) // arccos(0.9), default found in Acrobat output {} ~PRC3DTess() { for(PRCTessFaceList::iterator it=face_tessellation.begin(); it!=face_tessellation.end(); ++it) delete *it; } void serialize3DTess(PRCbitStream&); void serializeBaseTessData(PRCbitStream &pbs) { serialize3DTess(pbs); } void addTessFace(PRCTessFace*& pTessFace); bool has_faces; bool has_loops; double crease_angle; std::vector normal_coordinate; std::vector wire_index; // specifing bounding wire seems not to work as of Acrobat/Reader 9.2 std::vector triangulated_index; PRCTessFaceList face_tessellation; std::vector texture_coordinate; }; class PRC3DWireTess : public PRCTess { public: PRC3DWireTess() : is_rgba(false), is_segment_color(false) {} void serialize3DWireTess(PRCbitStream&); void serializeBaseTessData(PRCbitStream &pbs) { serialize3DWireTess(pbs); } bool is_rgba; bool is_segment_color; std::vector wire_indexes; std::vector rgba_vertices; }; class PRCMarkupTess : public PRCTess { public: PRCMarkupTess() : behaviour(0) {} void serializeMarkupTess(PRCbitStream&); void serializeBaseTessData(PRCbitStream &pbs) { serializeMarkupTess(pbs); } std::vector codes; std::vector texts; std::string label; uint8_t behaviour; }; class PRCGraphics { public: PRCGraphics() : layer_index(m1), index_of_line_style(m1), behaviour_bit_field(PRC_GRAPHICS_Show) {} void serializeGraphics(PRCbitStream&); void serializeGraphicsForced(PRCbitStream&); bool has_graphics() { return (index_of_line_style!=m1 || layer_index!=m1 || behaviour_bit_field!=PRC_GRAPHICS_Show) ; } uint32_t layer_index; uint32_t index_of_line_style; uint16_t behaviour_bit_field; }; typedef std::deque PRCGraphicsList; void writeGraphics(PRCbitStream&,const PRCGraphics&,bool=false); class PRCMarkup: public PRCGraphics, public ContentPRCBase { public: PRCMarkup(std::string n="") : ContentPRCBase(PRC_TYPE_MKP_Markup,n), type(KEPRCMarkupType_Unknown), sub_type(KEPRCMarkupSubType_Unknown), index_tessellation(m1) {} void serializeMarkup(PRCbitStream&); EPRCMarkupType type; EPRCMarkupSubType sub_type; // vector linked_items; // vector leaders; uint32_t index_tessellation; }; typedef std::deque PRCMarkupList; class PRCAnnotationItem: public PRCGraphics, public ContentPRCBase { public: PRCAnnotationItem(std::string n="") : ContentPRCBase(PRC_TYPE_MKP_AnnotationItem,n) {} void serializeAnnotationItem(PRCbitStream&); void serializeAnnotationEntity(PRCbitStream &pbs) { serializeAnnotationItem(pbs); } PRCReferenceUniqueIdentifier markup; }; typedef std::deque PRCAnnotationItemList; class PRCRepresentationItemContent: public PRCGraphics, public ContentPRCBase { public: PRCRepresentationItemContent(uint32_t t, std::string n="") : ContentPRCBase(t,n), index_local_coordinate_system(m1), index_tessellation(m1) {} void serializeRepresentationItemContent(PRCbitStream&); uint32_t index_local_coordinate_system; uint32_t index_tessellation; }; class PRCRepresentationItem : public PRCRepresentationItemContent { public: PRCRepresentationItem(uint32_t t, std::string n="") : PRCRepresentationItemContent(t,n) {} virtual ~PRCRepresentationItem() {} virtual void serializeRepresentationItem(PRCbitStream &pbs) = 0; }; typedef std::deque PRCRepresentationItemList; class PRCBrepModel : public PRCRepresentationItem { public: PRCBrepModel(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_BrepModel,n), has_brep_data(true), context_id(m1), body_id(m1), is_closed(false) {} void serializeBrepModel(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializeBrepModel(pbs); } bool has_brep_data; uint32_t context_id; uint32_t body_id; bool is_closed; }; class PRCPolyBrepModel : public PRCRepresentationItem { public: PRCPolyBrepModel(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_PolyBrepModel,n), is_closed(false) {} void serializePolyBrepModel(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyBrepModel(pbs); } bool is_closed; }; class PRCPointSet : public PRCRepresentationItem { public: PRCPointSet(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_PointSet,n) {} void serializePointSet(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializePointSet(pbs); } std::vector point; }; class PRCWire : public PRCRepresentationItem { public: PRCWire(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_Curve,n), has_wire_body(true), context_id(m1), body_id(m1) {} void serializeWire(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializeWire(pbs); } bool has_wire_body; uint32_t context_id; uint32_t body_id; }; class PRCPolyWire : public PRCRepresentationItem { public: PRCPolyWire(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_PolyWire,n) {} void serializePolyWire(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyWire(pbs); } }; class PRCSet : public PRCRepresentationItem { public: PRCSet(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_Set,n) {} ~PRCSet() { for(PRCRepresentationItemList::iterator it=elements.begin(); it!=elements.end(); ++it) delete *it; } void serializeSet(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializeSet(pbs); } uint32_t addBrepModel(PRCBrepModel*& pBrepModel); uint32_t addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel); uint32_t addPointSet(PRCPointSet*& pPointSet); uint32_t addSet(PRCSet*& pSet); uint32_t addWire(PRCWire*& pWire); uint32_t addPolyWire(PRCPolyWire*& pPolyWire); uint32_t addRepresentationItem(PRCRepresentationItem*& pRepresentationItem); PRCRepresentationItemList elements; }; class PRCTransformation3d { public: virtual ~PRCTransformation3d() {} virtual void serializeTransformation3d(PRCbitStream&) const =0; }; typedef std::deque PRCTransformation3dList; class PRCGeneralTransformation3d : public PRCTransformation3d { public: PRCGeneralTransformation3d() { setidentity(); } PRCGeneralTransformation3d(const double t[]) { set(t); } void serializeGeneralTransformation3d(PRCbitStream&) const; void serializeTransformation3d(PRCbitStream& pbs) const { serializeGeneralTransformation3d(pbs); } double m_coef[16]; bool operator==(const PRCGeneralTransformation3d &t) const { for (size_t i=0;i<16;i++) if(m_coef[i]!=t.m_coef[i]) return false; return true; } bool operator<(const PRCGeneralTransformation3d &t) const { for (size_t i=0;i<16;i++) if(m_coef[i]!=t.m_coef[i]) { return (m_coef[i] PRCGeneralTransformation3dList; class PRCCartesianTransformation3d : public PRCTransformation3d { public: PRCCartesianTransformation3d() : behaviour(PRC_TRANSFORMATION_Identity), origin(0.0,0.0,0.0), X(1.0,0.0,0.0), Y(0.0,1.0,0.0), Z(0.0,0.0,1.0), scale(1.0,1.0,1.0), uniform_scale(1.0), X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0) {} PRCCartesianTransformation3d(const double o[3], const double x[3], const double y[3], double sc) : behaviour(PRC_TRANSFORMATION_Identity), origin(o,0.0,0.0,0.0), X(x,1.0,0.0,0.0), Y(y,0.0,1.0,0.0), Z(0.0,0.0,1.0), scale(1.0,1.0,1.0), uniform_scale(sc), X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0) { if(origin!=PRCVector3d(0.0,0.0,0.0)) behaviour = behaviour | PRC_TRANSFORMATION_Translate; if(X!=PRCVector3d(1.0,0.0,0.0) || Y!=PRCVector3d(0.0,1.0,0.0)) behaviour = behaviour | PRC_TRANSFORMATION_Rotate; if(uniform_scale!=1) behaviour = behaviour | PRC_TRANSFORMATION_Scale; } void serializeCartesianTransformation3d(PRCbitStream& pbs) const; void serializeTransformation3d(PRCbitStream& pbs) const { serializeCartesianTransformation3d(pbs); } uint8_t behaviour; PRCVector3d origin; PRCVector3d X; PRCVector3d Y; PRCVector3d Z; PRCVector3d scale; double uniform_scale; double X_homogeneous_coord; double Y_homogeneous_coord; double Z_homogeneous_coord; double origin_homogeneous_coord; bool operator==(const PRCCartesianTransformation3d &t) const { return behaviour==t.behaviour && origin==t.origin && X==t.X && Y==t.Y && Z==t.Z && scale==t.scale && uniform_scale==t.uniform_scale && X_homogeneous_coord==t.X_homogeneous_coord && Y_homogeneous_coord==t.Y_homogeneous_coord && Z_homogeneous_coord==t.Z_homogeneous_coord && origin_homogeneous_coord==t.origin_homogeneous_coord; } }; class PRCTransformation { public: PRCTransformation() : has_transformation(false), geometry_is_2D(false), behaviour(PRC_TRANSFORMATION_Identity), origin(0.0,0.0,0.0), x_axis(1.0,0.0,0.0), y_axis(0.0,1.0,0.0), scale(1) {} void serializeTransformation(PRCbitStream&); bool has_transformation; bool geometry_is_2D; uint8_t behaviour; PRCVector3d origin; PRCVector3d x_axis; PRCVector3d y_axis; double scale; }; class PRCCoordinateSystem : public PRCRepresentationItem { public: PRCCoordinateSystem(std::string n="") : PRCRepresentationItem(PRC_TYPE_RI_CoordinateSystem,n), axis_set(NULL) {} ~PRCCoordinateSystem() { delete axis_set; } void serializeCoordinateSystem(PRCbitStream&); void serializeRepresentationItem(PRCbitStream &pbs) { serializeCoordinateSystem(pbs); } void setAxisSet(PRCGeneralTransformation3d*& transform) { axis_set = transform; transform = NULL; } void setAxisSet(PRCCartesianTransformation3d*& transform) { axis_set = transform; transform = NULL; } PRCTransformation3d *axis_set; bool operator==(const PRCCoordinateSystem &t) const { if(index_local_coordinate_system!=t.index_local_coordinate_system) return false; PRCGeneralTransformation3d* axis_set_general = dynamic_cast(axis_set); PRCGeneralTransformation3d* t_axis_set_general = dynamic_cast(t.axis_set); PRCCartesianTransformation3d* axis_set_cartesian = dynamic_cast(axis_set); PRCCartesianTransformation3d* t_axis_set_cartesian = dynamic_cast(t.axis_set); if(axis_set_general!=NULL) return (t_axis_set_general!=NULL?(*axis_set_general==*t_axis_set_general):false); if(axis_set_cartesian!=NULL) return (t_axis_set_cartesian!=NULL?(*axis_set_cartesian==*t_axis_set_cartesian):false); return false; } }; typedef std::deque PRCCoordinateSystemList; struct PRCFontKey { uint32_t font_size; uint8_t attributes; }; class PRCFontKeysSameFont { public: void serializeFontKeysSameFont(PRCbitStream&); std::string font_name; uint32_t char_set; std::vector font_keys; }; // Topology class PRCBaseGeometry : public PRCAttributes { public: PRCBaseGeometry() : base_information(false), identifier(0) {} PRCBaseGeometry(std::string n, uint32_t id = 0) : base_information(true),name(n),identifier(id) {} void serializeBaseGeometry(PRCbitStream&); bool base_information; std::string name; uint32_t identifier; }; class PRCBoundingBox { public: PRCBoundingBox() {min=PRCVector3d(0.0,0.0,0.0); max=PRCVector3d(0.0,0.0,0.0);} PRCBoundingBox(const PRCVector3d &m, const PRCVector3d& M) {min=PRCVector3d(m); max=PRCVector3d(M);} void serializeBoundingBox(PRCbitStream &pbs); PRCVector3d min; PRCVector3d max; }; class PRCDomain { public: void serializeDomain(PRCbitStream &pbs); PRCVector2d min; PRCVector2d max; }; class PRCInterval { public: PRCInterval() { min=max=0;} PRCInterval(double m, double M) {min=m;max=M;} void serializeInterval(PRCbitStream &pbs); double min; double max; }; class PRCParameterization { public: PRCParameterization() : parameterization_coeff_a(1), parameterization_coeff_b(0) {} PRCParameterization(double min, double max) : interval(min, max), parameterization_coeff_a(1), parameterization_coeff_b(0) {} void serializeParameterization(PRCbitStream &pbs); PRCInterval interval; double parameterization_coeff_a; double parameterization_coeff_b; }; class PRCUVParameterization { public: PRCUVParameterization() : swap_uv(false), parameterization_on_u_coeff_a(1), parameterization_on_v_coeff_a(1), parameterization_on_u_coeff_b(0), parameterization_on_v_coeff_b(0) {} void serializeUVParameterization(PRCbitStream &pbs); bool swap_uv; PRCDomain uv_domain; double parameterization_on_u_coeff_a; double parameterization_on_v_coeff_a; double parameterization_on_u_coeff_b; double parameterization_on_v_coeff_b; }; class PRCControlPoint { public: PRCControlPoint() : x(0), y(0), z(0), w(1) {} PRCControlPoint(double X, double Y, double Z=0, double W=1) : x(X), y(Y), z(Z), w(W) {} PRCControlPoint(const PRCVector3d &v) : x(v.x), y(v.y), z(v.z), w(1) {} void Set(double fx, double fy, double fz, double fw=1) { x = fx; y = fy; z = fz; w = fw; } double x; double y; double z; double w; }; class PRCContentSurface: public PRCBaseGeometry { public: PRCContentSurface() : PRCBaseGeometry(), extend_info(KEPRCExtendTypeNone) {} PRCContentSurface(std::string n) : PRCBaseGeometry(n,makeCADID()),extend_info(KEPRCExtendTypeNone) {} void serializeContentSurface(PRCbitStream&); EPRCExtendType extend_info; }; class PRCSurface : public PRCContentSurface { public: PRCSurface() : PRCContentSurface() {} PRCSurface(std::string n) : PRCContentSurface(n) {} virtual ~PRCSurface() {} virtual void serializeSurface(PRCbitStream &pbs) = 0; }; class PRCNURBSSurface : public PRCSurface { public: PRCNURBSSurface() : PRCSurface(), knot_type(KEPRCKnotTypeUnspecified), surface_form(KEPRCBSplineSurfaceFormUnspecified) {} PRCNURBSSurface(std::string n) : PRCSurface(n), knot_type(KEPRCKnotTypeUnspecified), surface_form(KEPRCBSplineSurfaceFormUnspecified) {} void serializeNURBSSurface(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeNURBSSurface(pbs); } bool is_rational; uint32_t degree_in_u; uint32_t degree_in_v; std::vector control_point; std::vector knot_u; std::vector knot_v; const EPRCKnotType knot_type; const EPRCBSplineSurfaceForm surface_form; }; class PRCContentCurve: public PRCBaseGeometry { public: PRCContentCurve() : PRCBaseGeometry(), extend_info(KEPRCExtendTypeNone), is_3d(true) {} PRCContentCurve(std::string n) : PRCBaseGeometry(n,makeCADID()),extend_info(KEPRCExtendTypeNone), is_3d(true) {} void serializeContentCurve(PRCbitStream&); EPRCExtendType extend_info; bool is_3d; }; class PRCCurve : public PRCContentCurve { public: PRCCurve() : PRCContentCurve() {} PRCCurve(std::string n) : PRCContentCurve(n) {} virtual ~PRCCurve() {} virtual void serializeCurve(PRCbitStream &pbs) = 0; }; typedef std::deque PRCCurveList; class PRCNURBSCurve : public PRCCurve { public: PRCNURBSCurve() : PRCCurve(), knot_type(KEPRCKnotTypeUnspecified), curve_form(KEPRCBSplineCurveFormUnspecified) {} PRCNURBSCurve(std::string n) : PRCCurve(n), knot_type(KEPRCKnotTypeUnspecified), curve_form(KEPRCBSplineCurveFormUnspecified) {} void serializeNURBSCurve(PRCbitStream &pbs); void serializeCurve(PRCbitStream &pbs) { serializeNURBSCurve(pbs); } bool is_rational; uint32_t degree; std::vector control_point; std::vector knot; const EPRCKnotType knot_type; const EPRCBSplineCurveForm curve_form; }; class PRCPolyLine : public PRCCurve, public PRCTransformation, public PRCParameterization { public: PRCPolyLine() : PRCCurve() {} PRCPolyLine(std::string n) : PRCCurve(n) {} void serializePolyLine(PRCbitStream &pbs); void serializeCurve(PRCbitStream &pbs) { serializePolyLine(pbs); } std::vector point; }; class PRCCircle : public PRCCurve, public PRCTransformation, public PRCParameterization { public: PRCCircle() : PRCCurve(), PRCParameterization(0,2*pi) {} PRCCircle(std::string n) : PRCCurve(n), PRCParameterization(0,2*pi) {} void serializeCircle(PRCbitStream &pbs); void serializeCurve(PRCbitStream &pbs) { serializeCircle(pbs); } double radius; }; class PRCComposite : public PRCCurve, public PRCTransformation, public PRCParameterization { public: PRCComposite() : PRCCurve() {} PRCComposite(std::string n) : PRCCurve(n) {} void serializeComposite(PRCbitStream &pbs); void serializeCurve(PRCbitStream &pbs) { serializeComposite(pbs); } PRCCurveList base_curve; std::vector base_sense; bool is_closed; }; class PRCBlend01 : public PRCSurface, public PRCTransformation, public PRCUVParameterization { public: PRCBlend01() : PRCSurface(), center_curve(NULL), origin_curve(NULL), tangent_curve(NULL) {} PRCBlend01(std::string n) : PRCSurface(n), center_curve(NULL), origin_curve(NULL), tangent_curve(NULL) {} ~PRCBlend01() { delete center_curve; delete origin_curve; delete tangent_curve; } void serializeBlend01(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeBlend01(pbs); } // void setCenterCurve (PRCCurve*& curve) { center_curve = curve; curve = NULL; } // void setOriginCurve (PRCCurve*& curve) { origin_curve = curve; curve = NULL; } // void setTangentCurve(PRCCurve*& curve) { tangent_curve = curve; curve = NULL; } PRCCurve* center_curve; PRCCurve* origin_curve; PRCCurve* tangent_curve; }; class PRCRuled : public PRCSurface, public PRCTransformation, public PRCUVParameterization { public: PRCRuled() : PRCSurface(), first_curve(NULL), second_curve(NULL) {} PRCRuled(std::string n) : PRCSurface(n) {} ~PRCRuled() { delete first_curve; delete second_curve; } void serializeRuled(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeRuled(pbs); } // void setFirstCurve(PRCCurve*& curve) { first_curve = curve; curve = NULL; } // void setSecondCurve(PRCCurve*& curve) { second_curve = curve; curve = NULL; } PRCCurve* first_curve; PRCCurve* second_curve; }; class PRCSphere : public PRCSurface, public PRCTransformation, public PRCUVParameterization { public: PRCSphere() : PRCSurface() {} PRCSphere(std::string n) : PRCSurface(n) {} void serializeSphere(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeSphere(pbs); } double radius; }; class PRCCone : public PRCSurface, public PRCTransformation, public PRCUVParameterization { public: PRCCone() : PRCSurface() {} PRCCone(std::string n) : PRCSurface(n) {} void serializeCone(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeCone(pbs); } double bottom_radius; double semi_angle; }; class PRCCylinder : public PRCSurface, public PRCTransformation, public PRCUVParameterization { public: PRCCylinder() : PRCSurface() {} PRCCylinder(std::string n) : PRCSurface(n) {} void serializeCylinder(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeCylinder(pbs); } double radius; }; class PRCTorus : public PRCSurface, public PRCTransformation, public PRCUVParameterization { public: PRCTorus() : PRCSurface() {} PRCTorus(std::string n) : PRCSurface(n) {} void serializeTorus(PRCbitStream &pbs); void serializeSurface(PRCbitStream &pbs) { serializeTorus(pbs); } double major_radius; double minor_radius; }; class PRCBaseTopology : public PRCAttributes { public: PRCBaseTopology() : base_information(false),identifier(0) {} PRCBaseTopology(std::string n, uint32_t id = 0) : base_information(true),name(n),identifier(id) {} void serializeBaseTopology(PRCbitStream&); bool base_information; std::string name; uint32_t identifier; }; class PRCTopoItem { public: virtual ~PRCTopoItem() {} virtual void serializeTopoItem(PRCbitStream&)=0; }; class PRCContentBody: public PRCBaseTopology { public: PRCContentBody() : PRCBaseTopology(), behavior(0) {} PRCContentBody(std::string n) : PRCBaseTopology(n,makeCADID()), behavior(0) {} void serializeContentBody(PRCbitStream&); uint8_t behavior; }; class PRCBody : public PRCContentBody, public PRCTopoItem { public: PRCBody() : PRCContentBody(), topo_item_type(PRC_TYPE_ROOT) {} PRCBody(uint32_t tit) : PRCContentBody(), topo_item_type(tit) {} PRCBody(uint32_t tit, std::string n) : PRCContentBody(n), topo_item_type(tit) {} virtual ~PRCBody() {} virtual void serializeBody(PRCbitStream &pbs) = 0; void serializeTopoItem(PRCbitStream &pbs) { serializeBody(pbs); } uint32_t serialType() { return topo_item_type; } virtual double serialTolerance() { return 0; } const uint32_t topo_item_type; }; typedef std::deque PRCBodyList; class PRCContentWireEdge : public PRCBaseTopology { public: PRCContentWireEdge() : PRCBaseTopology(), curve_3d(NULL), has_curve_trim_interval(false) {} PRCContentWireEdge(std::string n) : PRCBaseTopology(n,makeCADID()), curve_3d(NULL), has_curve_trim_interval(false) {} ~PRCContentWireEdge() { delete curve_3d; } void serializeContentWireEdge(PRCbitStream &pbs); // void setCurve(PRCCurve*& curve) { curve_3d = curve; curve = NULL; } PRCCurve* curve_3d; bool has_curve_trim_interval; PRCInterval curve_trim_interval; }; class PRCWireEdge : public PRCContentWireEdge, public PRCTopoItem { public: void serializeWireEdge(PRCbitStream &pbs); void serializeTopoItem(PRCbitStream &pbs) { serializeWireEdge(pbs); } }; class PRCSingleWireBody : public PRCBody { public: PRCSingleWireBody() : PRCBody(PRC_TYPE_TOPO_SingleWireBody), wire_edge(NULL) {} PRCSingleWireBody(std::string n) : PRCBody(PRC_TYPE_TOPO_SingleWireBody, n), wire_edge(NULL) {} ~PRCSingleWireBody() { delete wire_edge; } void serializeSingleWireBody(PRCbitStream &pbs); void serializeBody(PRCbitStream &pbs) { serializeSingleWireBody(pbs); } void setWireEdge(PRCWireEdge*& wireEdge) { wire_edge = wireEdge; wireEdge = NULL; } PRCWireEdge* wire_edge; }; class PRCFace : public PRCBaseTopology, public PRCTopoItem, public PRCGraphics { public: PRCFace() : PRCBaseTopology(), base_surface(NULL), have_surface_trim_domain(false), have_tolerance(false), tolerance(0), number_of_loop(0), outer_loop_index(-1) {} PRCFace(std::string n) : PRCBaseTopology(n,makeCADID()), base_surface(NULL), have_surface_trim_domain(false), have_tolerance(false), tolerance(0), number_of_loop(0), outer_loop_index(-1) {} ~PRCFace() { delete base_surface; } void serializeFace(PRCbitStream &pbs); void serializeTopoItem(PRCbitStream &pbs) { serializeFace(pbs); } void setBaseSurface(PRCSurface*& surface) { base_surface = surface; surface = NULL; } PRCSurface *base_surface; const bool have_surface_trim_domain; PRCDomain surface_trim_domain; const bool have_tolerance; const double tolerance; const uint32_t number_of_loop; const int32_t outer_loop_index; // PRCLoopList loop; }; typedef std::deque PRCFaceList; class PRCShell : public PRCBaseTopology, public PRCTopoItem { public: PRCShell() : PRCBaseTopology(), shell_is_closed(false) {} PRCShell(std::string n) : PRCBaseTopology(n,makeCADID()), shell_is_closed(false) {} ~PRCShell() { for(PRCFaceList::iterator it=face.begin(); it!=face.end(); ++it) delete *it; } void serializeShell(PRCbitStream &pbs); void serializeTopoItem(PRCbitStream &pbs) { serializeShell(pbs); } void addFace(PRCFace*& pFace, uint8_t orientation=2); bool shell_is_closed; PRCFaceList face; std::vector orientation_surface_with_shell; }; typedef std::deque PRCShellList; class PRCConnex : public PRCBaseTopology, public PRCTopoItem { public: PRCConnex() : PRCBaseTopology() {} PRCConnex(std::string n) : PRCBaseTopology(n,makeCADID()) {} ~PRCConnex() { for(PRCShellList::iterator it=shell.begin(); it!=shell.end(); ++it) delete *it; } void serializeConnex(PRCbitStream &pbs); void serializeTopoItem(PRCbitStream &pbs) { serializeConnex(pbs); } void addShell(PRCShell*& pShell); PRCShellList shell; }; typedef std::deque PRCConnexList; class PRCBrepData : public PRCBody, public PRCBoundingBox { public: PRCBrepData() : PRCBody(PRC_TYPE_TOPO_BrepData) {} PRCBrepData(std::string n) : PRCBody(PRC_TYPE_TOPO_BrepData, n) {} ~PRCBrepData() { for(PRCConnexList::iterator it=connex.begin(); it!=connex.end(); ++it) delete *it; } void serializeBrepData(PRCbitStream &pbs); void serializeBody(PRCbitStream &pbs) { serializeBrepData(pbs); } void addConnex(PRCConnex*& pConnex); PRCConnexList connex; }; // For now - treat just the case of Bezier surfaces cubic 4x4 or linear 2x2 class PRCCompressedFace : public PRCBaseTopology, public PRCGraphics { public: PRCCompressedFace() : PRCBaseTopology(), orientation_surface_with_shell(true), degree(0) {} PRCCompressedFace(std::string n) : PRCBaseTopology(n,makeCADID()), orientation_surface_with_shell(true), degree(0) {} void serializeCompressedFace(PRCbitStream &pbs, double brep_data_compressed_tolerance); void serializeContentCompressedFace(PRCbitStream &pbs); void serializeCompressedAnaNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance); void serializeCompressedNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance); bool orientation_surface_with_shell; uint32_t degree; std::vector control_point; }; typedef std::deque PRCCompressedFaceList; // For now - treat just the case of one connex/one shell class PRCCompressedBrepData : public PRCBody { public: PRCCompressedBrepData() : PRCBody(PRC_TYPE_TOPO_BrepDataCompress), serial_tolerance(0), brep_data_compressed_tolerance(0) {} PRCCompressedBrepData(std::string n) : PRCBody(PRC_TYPE_TOPO_BrepDataCompress, n), serial_tolerance(0), brep_data_compressed_tolerance(0) {} ~PRCCompressedBrepData() { for(PRCCompressedFaceList::iterator it=face.begin(); it!=face.end(); ++it) delete *it; } void serializeCompressedBrepData(PRCbitStream &pbs); void serializeBody(PRCbitStream &pbs) { serializeCompressedBrepData(pbs); } void serializeCompressedShell(PRCbitStream &pbs); double serialTolerance() { return serial_tolerance; } double serial_tolerance; double brep_data_compressed_tolerance; PRCCompressedFaceList face; }; class PRCTopoContext : public ContentPRCBase { public: PRCTopoContext(std::string n="") : ContentPRCBase(PRC_TYPE_TOPO_Context,n), behaviour(0), granularity(1), tolerance(0), have_smallest_face_thickness(false), smallest_thickness(0), have_scale(false), scale(1) {} ~PRCTopoContext() { for(PRCBodyList::iterator it=body.begin(); it!=body.end(); ++it) delete *it; } void serializeTopoContext(PRCbitStream&); void serializeContextAndBodies(PRCbitStream&); void serializeGeometrySummary(PRCbitStream&); void serializeContextGraphics(PRCbitStream&); uint32_t addSingleWireBody(PRCSingleWireBody*& body); uint32_t addBrepData(PRCBrepData*& body); uint32_t addCompressedBrepData(PRCCompressedBrepData*& body); uint8_t behaviour; double granularity; double tolerance; bool have_smallest_face_thickness; double smallest_thickness; bool have_scale; double scale; PRCBodyList body; }; typedef std::deque PRCTopoContextList; class PRCUniqueId { public: PRCUniqueId() : id0(0), id1(0), id2(0), id3(0) {} void serializeCompressedUniqueId(PRCbitStream&) const; void serializeFileStructureUncompressedUniqueId(std::ostream& out) const; uint32_t id0; uint32_t id1; uint32_t id2; uint32_t id3; }; class PRCUnit { public: PRCUnit() : unit_from_CAD_file(false), unit(1) {} PRCUnit(double u, bool ufcf=true) : unit_from_CAD_file(ufcf), unit(u) {} void serializeUnit(PRCbitStream&); bool unit_from_CAD_file; double unit; }; class PRCProductOccurrence: public PRCGraphics, public ContentPRCBase { public: PRCProductOccurrence(std::string n="") : ContentPRCBase(PRC_TYPE_ASM_ProductOccurence,n), index_part(m1), index_prototype(m1), prototype_in_same_file_structure(true), index_external_data(m1), external_data_in_same_file_structure(true), product_behaviour(0), product_information_flags(0), product_load_status(KEPRCProductLoadStatus_Loaded), location(NULL) {} ~PRCProductOccurrence() { delete location; } void setLocation(PRCGeneralTransformation3d*& transform) { location = transform; transform = NULL; } void serializeProductOccurrence(PRCbitStream&); uint32_t index_part; uint32_t index_prototype; bool prototype_in_same_file_structure; PRCUniqueId prototype_file_structure; uint32_t index_external_data; bool external_data_in_same_file_structure; PRCUniqueId external_data_file_structure; std::vector index_son_occurrence; uint8_t product_behaviour; PRCUnit unit_information; uint8_t product_information_flags; EPRCProductLoadStatus product_load_status; PRCGeneralTransformation3d *location; }; typedef std::deque PRCProductOccurrenceList; class PRCPartDefinition: public PRCGraphics, public ContentPRCBase, public PRCBoundingBox { public: PRCPartDefinition(std::string n="") : ContentPRCBase(PRC_TYPE_ASM_PartDefinition,n) {} ~PRCPartDefinition() { for(PRCRepresentationItemList::iterator it=representation_item.begin(); it!=representation_item.end(); ++it) delete *it; } void serializePartDefinition(PRCbitStream&); uint32_t addBrepModel(PRCBrepModel*& pBrepModel); uint32_t addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel); uint32_t addPointSet(PRCPointSet*& pPointSet); uint32_t addSet(PRCSet*& pSet); uint32_t addWire(PRCWire*& pWire); uint32_t addPolyWire(PRCPolyWire*& pPolyWire); uint32_t addRepresentationItem(PRCRepresentationItem*& pRepresentationItem); PRCRepresentationItemList representation_item; }; typedef std::deque PRCPartDefinitionList; #endif //__WRITE_PRC_H mathgl-2.4.4/src/prc/PRCbitStream.cc0000644000175000017500000002020213513030041017322 0ustar alastairalastair/************ * * This file is part of a tool for producing 3D content in the PRC format. * Copyright (C) 2008 Orest Shardt * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * *************/ #include #include #include #include #include #include #include "PRCbitStream.h" #include "PRCdouble.h" using std::string; using std::cerr; using std::endl; void PRCbitStream::compress() { const int CHUNK= 1024; // is this reasonable? compressedDataSize = 0; z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK) { cerr << "Compression initialization failed" << endl; return; } unsigned int sizeAvailable = deflateBound(&strm,getSize()); uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable); strm.avail_in = getSize(); strm.next_in = (unsigned char*)data; strm.next_out = (unsigned char*)compressedData; strm.avail_out = sizeAvailable; int code; unsigned int chunks = 0; while((code = deflate(&strm,Z_FINISH)) == Z_OK) { ++chunks; // strm.avail_out should be 0 if we got Z_OK compressedDataSize = sizeAvailable - strm.avail_out; compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks); strm.next_out = (Bytef*)(compressedData + compressedDataSize); strm.avail_out += CHUNK; sizeAvailable += CHUNK; } compressedDataSize = sizeAvailable-strm.avail_out; if(code != Z_STREAM_END) { cerr << "Compression error" << endl; deflateEnd(&strm); free(compressedData); return; } compressed = true; free(data); data = compressedData; deflateEnd(&strm); } void PRCbitStream::write(std::ostream &out) const { if(compressed) { out.write((char*)data,compressedDataSize); } else { cerr << "Attempt to write stream before compression." << endl; exit(1); } } unsigned int PRCbitStream::getSize() const { if(compressed) return compressedDataSize; else return byteIndex+1; } uint8_t* PRCbitStream::getData() { return data; } PRCbitStream& PRCbitStream::operator <<(bool b) { writeBit(b); return *this; } PRCbitStream& PRCbitStream::operator <<(uint32_t u) { while(u != 0) { writeBit(1); writeByte(u & 0xFF); u >>= 8; } writeBit(0); return *this; } PRCbitStream& PRCbitStream::operator <<(uint8_t u) { writeByte(u); return *this; } PRCbitStream& PRCbitStream::operator <<(int32_t i) { uint8_t lastByte = 0; //while(!((current value is 0 and last byte was positive) OR (current value is -1 and last value was negative))) while(!(((i == 0)&&((lastByte & 0x80)==0))||((i == -1)&&((lastByte & 0x80) != 0)))) { writeBit(1); lastByte = i & 0xFF; writeByte(lastByte); i >>= 8; } writeBit(0); return *this; } PRCbitStream& PRCbitStream::operator <<(double value) { // write a double if(compressed) { cerr << "Cannot write to a stream that has been compressed." << endl; return *this; } union ieee754_double *pid=(union ieee754_double *)&value; int i, fSaveAtEnd; PRCbyte *pb, *pbStart, *pbStop, *pbEnd, *pbResult, bSaveAtEnd = 0; struct sCodageOfFrequentDoubleOrExponent cofdoe, *pcofdoe; cofdoe.u2uod.Value=value; pcofdoe = (struct sCodageOfFrequentDoubleOrExponent *)bsearch( &cofdoe, acofdoe, sizeof(acofdoe)/sizeof(pcofdoe[0]), sizeof(pcofdoe[0]), stCOFDOECompare); while(pcofdoe>acofdoe && EXPONENT(pcofdoe->u2uod.Value)==EXPONENT((pcofdoe-1)->u2uod.Value)) pcofdoe--; assert(pcofdoe); while(pcofdoe->Type==VT_double) { if(fabs(value)==pcofdoe->u2uod.Value) break; pcofdoe++; } for(i=1<<(pcofdoe->NumberOfBits-1);i>=1;i>>=1) writeBit((pcofdoe->Bits&i)!=0); if ( !memcmp(&value,stadwZero,sizeof(value)) || !memcmp(&value,stadwNegativeZero,sizeof(value)) ) return *this; writeBit(pid->ieee.negative); if(pcofdoe->Type==VT_double) return *this; if(pid->ieee.mantissa0==0 && pid->ieee.mantissa1==0) { writeBit(0); return *this; } writeBit(1); #ifdef WORDS_BIGENDIAN pb=((PRCbyte *)&value)+1; #else pb=((PRCbyte *)&value)+6; #endif //add_bits((*pb)&0x0f,4 STAT_V STAT_DOUBLE); writeBits((*pb)&0x0F,4); NEXTBYTE(pb); pbStart=pb; #ifdef WORDS_BIGENDIAN pbEnd= pbStop= ((PRCbyte *)(&value+1))-1; #else pbEnd= pbStop= ((PRCbyte *)&value); #endif if((fSaveAtEnd=(*pbStop!=*BEFOREBYTE(pbStop)))!=0) bSaveAtEnd=*pbEnd; PREVIOUSBYTE(pbStop); while(*pbStop==*BEFOREBYTE(pbStop)) PREVIOUSBYTE(pbStop); for(;MOREBYTE(pb,pbStop);NEXTBYTE(pb)) { if(pb!=pbStart && (pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL) { writeBit(0); writeBits(DIFFPOINTERS(pb,pbResult),3); } else { writeBit(1); writeByte(*pb); } } if(!MOREBYTE(BEFOREBYTE(pbEnd),pbStop)) { if(fSaveAtEnd) { writeBit(0); writeBits(6,3); writeByte(bSaveAtEnd); } else { writeBit(0); writeBits(0,3); } } else { if((pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL) { writeBit(0); writeBits(DIFFPOINTERS(pb,pbResult),3); } else { writeBit(1); writeByte(*pb); } } return *this; } PRCbitStream& PRCbitStream::operator <<(const char* s) { if (s == NULL) { writeBit(false); // string is NULL return *this; } string str(s); *this << str; return *this; } PRCbitStream& PRCbitStream::operator <<(const string& s) { if(s == "") { writeBit(false); // string is NULL return *this; } writeBit(true); size_t l = s.length(); *this << static_cast(l); for(size_t i = 0; i < l; ++i) writeByte(s[i]); return *this; } void PRCbitStream::writeBit(bool b) { if(compressed) { cerr << "Cannot write to a stream that has been compressed." << endl; return; } if(b) { data[byteIndex] |= (0x80 >> bitIndex); } nextBit(); } void PRCbitStream::writeBits(uint32_t u, uint8_t bits) { if(bits > 32) return; else { for(uint32_t mask = (1 << (bits-1)); mask != 0; mask >>= 1) { writeBit((u&mask) != 0); } } } void PRCbitStream::writeByte(uint8_t u) { if(compressed) { cerr << "Cannot write to a stream that has been compressed." << endl; return; } if(bitIndex == 0) { data[byteIndex] = u; nextByte(); } else { data[byteIndex] |= (u >> bitIndex); unsigned int obi = bitIndex; nextByte(); data[byteIndex] |= (u << (8-obi)); bitIndex = obi; // bit index is not changed by writing 8 bits } } void PRCbitStream::nextBit() { ++bitIndex; if(bitIndex == 8) { nextByte(); } } void PRCbitStream::nextByte() { ++byteIndex; if(byteIndex >= allocatedLength) getAChunk(); data[byteIndex] = 0; // clear the garbage data bitIndex = 0; } void PRCbitStream::getAChunk() { if(allocatedLength==0) data = (uint8_t*)realloc((void*)data,CHUNK_SIZE); else data = (uint8_t*)realloc((void*)data,2*allocatedLength); if(data != NULL) { if(allocatedLength==0) { allocatedLength = CHUNK_SIZE; *data = 0; // clear first byte } else allocatedLength *= 2; } else { // warn about memory problem! cerr << "Memory allocation error." << endl; exit(1); } } mathgl-2.4.4/src/prc/PRCbitStream.h0000644000175000017500000000470213513030041017173 0ustar alastairalastair/************ * * This file is part of a tool for producing 3D content in the PRC format. * Copyright (C) 2008 Orest Shardt * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * *************/ #ifndef __PRC_BIT_STREAM_H #define __PRC_BIT_STREAM_H #ifdef _MSC_VER #include #if _MSC_VER >= 1600 #include #else typedef signed char int8_t; typedef signed short int16_t; typedef signed long int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; #endif // _MSC_VER >= 1600 #elif defined __BORLANDC__ #include #else #include #endif // _MSC_VER #include #include #include #define CHUNK_SIZE (1024) // Is this a reasonable initial size? class PRCbitStream { public: PRCbitStream(uint8_t*& buff, unsigned int l) : byteIndex(0), bitIndex(0), allocatedLength(l), data(buff), compressed(false) { if(data == 0) { getAChunk(); } } unsigned int getSize() const; uint8_t* getData(); PRCbitStream& operator <<(const std::string&); PRCbitStream& operator <<(bool); PRCbitStream& operator <<(uint32_t); PRCbitStream& operator <<(uint8_t); PRCbitStream& operator <<(int32_t); PRCbitStream& operator <<(double); PRCbitStream& operator <<(const char*); void compress(); void write(std::ostream &out) const; private: void writeBit(bool); void writeBits(uint32_t,uint8_t); void writeByte(uint8_t); void nextByte(); void nextBit(); void getAChunk(); // bitIndex is "big endian", zero based, location of next bit to write unsigned int byteIndex,bitIndex; unsigned int allocatedLength; uint8_t*& data; bool compressed; uint32_t compressedDataSize; }; #endif // __PRC_BIT_STREAM_H mathgl-2.4.4/src/prc/writePRC.cc0000644000175000017500000020272613513030041016537 0ustar alastairalastair/************ * * This file is part of a tool for producing 3D content in the PRC format. * Copyright (C) 2008 Orest Shardt * with enhancements contributed by Michail Vidiassov. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * *************/ #include "writePRC.h" #include #include // debug print includes #include #include #include #include #if !defined(__GNUC__) || defined(__clang__) #include #endif #include using namespace std; #ifndef __GNUC_PREREQ #define __GNUC_PREREQ(maj, min) (0) #endif // Count leading zeros. uint32_t CLZ(uint32_t a) { #if __GNUC_PREREQ(3,4) return __builtin_clz(a); #else // find the log base 2 of a 32-bit integer static const int MultiplyDeBruijnBitPosition[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; a |= a >> 1; // first round down to one less than a power of 2 a |= a >> 2; a |= a >> 4; a |= a >> 8; a |= a >> 16; return 31-MultiplyDeBruijnBitPosition[(uint32_t)(a * 0x07C4ACDDU) >> 27]; #endif } // Portable integer implementation of ceil(log2(x)). uint32_t Log2(uint32_t x) { assert(x != 0); uint32_t L=31-CLZ(x); return ((uint32_t) 1 << L == x) ? L : L+1; } #define WriteUnsignedInteger( value ) pbs << (uint32_t)(value); #define WriteInteger( value ) pbs << (int32_t)(value); #define WriteCharacter( value ) pbs << (uint8_t)(value); #define WriteDouble( value ) pbs << (double)(value); #define WriteBit( value ) pbs << (bool)(value); #define WriteBoolean( value ) pbs << (bool)(value); #define WriteString( value ) pbs << (value); #define SerializeContentPRCBase serializeContentPRCBase(pbs); #define SerializeGraphics serializeGraphics(pbs); #define SerializePRCBaseWithGraphics { serializeContentPRCBase(pbs); serializeGraphics(pbs); } #define SerializeRepresentationItemContent serializeRepresentationItemContent(pbs); #define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(pbs); #define SerializeMarkup( value ) (value).serializeMarkup(pbs); #define SerializeReferenceUniqueIdentifier( value ) (value).serializeReferenceUniqueIdentifier(pbs); #define SerializeContentBaseTessData serializeContentBaseTessData(pbs); #define SerializeTessFace( value ) (value)->serializeTessFace(pbs); #define SerializeUserData UserData(0,0).write(pbs); #define SerializeLineAttr( value ) pbs << (uint32_t)((value)+1); #define SerializeVector3d( value ) (value).serializeVector3d(pbs); #define SerializeVector2d( value ) (value).serializeVector2d(pbs); #define SerializeName( value ) writeName(pbs, (value)); #define SerializeInterval( value ) (value).serializeInterval(pbs); // #define SerializeBoundingBox( value ) (value).serializeBoundingBox(pbs); #define SerializeDomain( value ) (value).serializeDomain(pbs); #define SerializeParameterization serializeParameterization(pbs); #define SerializeUVParameterization serializeUVParameterization(pbs); #define SerializeTransformation serializeTransformation(pbs); #define SerializeBaseTopology serializeBaseTopology(pbs); #define SerializeBaseGeometry serializeBaseGeometry(pbs); #define SerializePtrCurve( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeCurve(pbs);} #define SerializePtrSurface( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeSurface(pbs);} #define SerializePtrTopology( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeTopoItem(pbs);} #define SerializeContentCurve serializeContentCurve(pbs); #define SerializeContentWireEdge serializeContentWireEdge(pbs); #define SerializeContentBody serializeContentBody(pbs); #define SerializeTopoContext serializeTopoContext(pbs); #define SerializeContextAndBodies( value ) (value).serializeContextAndBodies(pbs); #define SerializeBody( value ) (value)->serializeBody(pbs); #define ResetCurrentGraphics resetGraphics(); #define SerializeContentSurface serializeContentSurface(pbs); #define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(pbs); #define SerializeUnit( value ) (value).serializeUnit(pbs); #define SerializeBoundingBox serializeBoundingBox(pbs); #define SerializeAttributeEntry serializeAttributeEntry(pbs); #define SerializeContentSingleAttribute( value ) (value).serializeSingleAttribute(pbs); #define SerializeAttribute( value ) (value).serializeAttribute(pbs); #define SerializeAttributeData serializeAttributes(pbs); #define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value)); #define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out); void writeUncompressedUnsignedInteger(ostream &out, uint32_t data) { #ifdef WORDS_BIGENDIAN out.write(((char*)&data)+3,1); out.write(((char*)&data)+2,1); out.write(((char*)&data)+1,1); out.write(((char*)&data)+0,1); #else out.write(((char*)&data)+0,1); out.write(((char*)&data)+1,1); out.write(((char*)&data)+2,1); out.write(((char*)&data)+3,1); #endif } double PRCVector3d::Length() { return sqrt(x*x+y*y+z*z); } bool PRCVector3d::Normalize() { double fLength=Length(); if(fLength < FLT_EPSILON) return false; double factor=1.0/fLength; x *= factor; y *= factor; z *= factor; return true; } double PRCVector2d::Length() { return sqrt(x*x+y*y); } bool PRCVector2d::Normalize() { double fLength=Length(); if(fLength < FLT_EPSILON) return false; double factor=1.0/fLength; x *= factor; y *= factor; return true; } void PRCVector2d::serializeVector2d(PRCbitStream &pbs) { WriteDouble (x) WriteDouble (y) } uint32_t makeCADID() { static uint32_t ID = 1; return ID++; } uint32_t makePRCID() { static uint32_t ID = 1; return ID++; } bool type_eligible_for_reference(uint32_t type) { if( type == PRC_TYPE_MISC_EntityReference || type == PRC_TYPE_MISC_MarkupLinkedItem || type == PRC_TYPE_RI_BrepModel || type == PRC_TYPE_RI_Curve || type == PRC_TYPE_RI_Direction || type == PRC_TYPE_RI_Plane || type == PRC_TYPE_RI_PointSet || type == PRC_TYPE_RI_PolyBrepModel || type == PRC_TYPE_RI_PolyWire || type == PRC_TYPE_RI_Set || type == PRC_TYPE_RI_CoordinateSystem || type == PRC_TYPE_ASM_ProductOccurence || type == PRC_TYPE_ASM_PartDefinition || type == PRC_TYPE_ASM_Filter || type == PRC_TYPE_MKP_View || type == PRC_TYPE_MKP_Markup || type == PRC_TYPE_MKP_Leader || type == PRC_TYPE_MKP_AnnotationItem || type == PRC_TYPE_MKP_AnnotationSet || type == PRC_TYPE_MKP_AnnotationReference || type == PRC_TYPE_GRAPH_Style || type == PRC_TYPE_GRAPH_Material || type == PRC_TYPE_GRAPH_TextureApplication || type == PRC_TYPE_GRAPH_TextureDefinition || type == PRC_TYPE_GRAPH_LinePattern || type == PRC_TYPE_GRAPH_DottingPattern || type == PRC_TYPE_GRAPH_HatchingPattern || type == PRC_TYPE_GRAPH_SolidPattern || type == PRC_TYPE_GRAPH_VPicturePattern || type == PRC_TYPE_GRAPH_AmbientLight || type == PRC_TYPE_GRAPH_PointLight || type == PRC_TYPE_GRAPH_DirectionalLight || type == PRC_TYPE_GRAPH_SpotLight || type == PRC_TYPE_GRAPH_SceneDisplayParameters || type == PRC_TYPE_GRAPH_Camera ) return true; else return false; } void UserData::write(PRCbitStream &pbs) { pbs << size; if(size > 0) { uint32_t quot=size/8; uint32_t rem=size-8*quot; for(uint32_t i = 0; i < quot; ++i) pbs << data[i]; for(uint32_t j = 0; j < rem; ++j) // 0-based, big endian bit counting pbs << (bool)((data[quot] & (0x80 >> j))!=0); } } void PRCAttributeEntry::serializeAttributeEntry(PRCbitStream &pbs) const { WriteBoolean (title_is_integer) if (title_is_integer) WriteUnsignedInteger (title_integer) else WriteString (title_text) } void PRCSingleAttribute::serializeSingleAttribute(PRCbitStream &pbs) const { SerializeAttributeEntry WriteUnsignedInteger (type) switch (type) { case KEPRCModellerAttributeTypeInt: WriteInteger (value.integer) break; case KEPRCModellerAttributeTypeReal: WriteDouble (value.real) break; case KEPRCModellerAttributeTypeTime: WriteUnsignedInteger (value.time) break; case KEPRCModellerAttributeTypeString: WriteString (value_text) break; default: break; } } void PRCAttribute::serializeAttribute(PRCbitStream &pbs) const { WriteUnsignedInteger (PRC_TYPE_MISC_Attribute) SerializeAttributeEntry const uint32_t size_of_attribute_keys = attribute_keys.size(); WriteUnsignedInteger (size_of_attribute_keys) for(uint32_t i=0;i out_it (out); copy ( file_contents.begin(), file_contents.end(), out_it ); } uint32_t PRCUncompressedFile::getSize() const { return sizeof(uint32_t)+file_contents.size(); } void PRCRgbColor::serializeRgbColor(PRCbitStream &pbs) { WriteDouble (red) WriteDouble (green) WriteDouble (blue) } void PRCPicture::serializePicture(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_GRAPH_Picture) SerializeContentPRCBase WriteInteger (format) //see Types for picture files WriteUnsignedInteger (uncompressed_file_index+1) WriteUnsignedInteger (pixel_width) WriteUnsignedInteger (pixel_height) } void PRCTextureDefinition::serializeTextureDefinition(PRCbitStream &pbs) { uint32_t i=0; // universal index for PRC standart compatibility const uint8_t texture_dimension = 2; const uint32_t texture_mapping_attributes = texture_mapping_attribute; const uint32_t size_texture_mapping_attributes_intensities = 1; const double *texture_mapping_attributes_intensities = &texture_mapping_attribute_intensity; const uint32_t size_texture_mapping_attributes_components = 1; const uint8_t *texture_mapping_attributes_components = &texture_mapping_attribute_components; const EPRCTextureMappingType eMappingType = KEPRCTextureMappingType_Stored; const double red = 1.0; const double green = 1.0; const double blue = 1.0; const double alpha = 1.0; const EPRCTextureBlendParameter blend_src_rgb = KEPRCTextureBlendParameter_Unknown; const EPRCTextureBlendParameter blend_dst_rgb = KEPRCTextureBlendParameter_Unknown; const EPRCTextureBlendParameter blend_src_alpha = KEPRCTextureBlendParameter_Unknown; const EPRCTextureBlendParameter blend_dst_alpha = KEPRCTextureBlendParameter_Unknown; const EPRCTextureAlphaTest alpha_test = KEPRCTextureAlphaTest_Unknown; const double alpha_test_reference = 1.0; const EPRCTextureWrappingMode texture_wrapping_mode_R = KEPRCTextureWrappingMode_ClampToBorder; const bool texture_transformation = false; WriteUnsignedInteger (PRC_TYPE_GRAPH_TextureDefinition) SerializeContentPRCBase WriteUnsignedInteger (picture_index+1) WriteCharacter (texture_dimension) // SerializeTextureMappingType WriteInteger (eMappingType) // Texture mapping type // if (eMappingType == TEXTURE_MAPPING_OPERATOR) // { // WriteInteger (eMappingOperator) // Texture mapping operator // WriteInteger (transformation) // if (transformation) // SerializeCartesianTransformation3d (transformation) // } WriteUnsignedInteger (texture_mapping_attributes) // Texture mapping attributes WriteUnsignedInteger (size_texture_mapping_attributes_intensities) for (i=0;i 1) WriteInteger (texture_wrapping_mode_T) // Texture wrapping mode if (texture_dimension > 2 ) WriteInteger (texture_wrapping_mode_R) // Texture wrapping mode WriteBit (texture_transformation) // if (texture_transformation) // SerializeTextureTransformation (texture_transformation) } void PRCMaterialGeneric::serializeMaterialGeneric(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_GRAPH_Material) SerializeContentPRCBase WriteUnsignedInteger (ambient + 1) WriteUnsignedInteger (diffuse + 1) WriteUnsignedInteger (emissive + 1) WriteUnsignedInteger (specular + 1) WriteDouble (shininess) WriteDouble (ambient_alpha) WriteDouble (diffuse_alpha) WriteDouble (emissive_alpha) WriteDouble (specular_alpha) } void PRCTextureApplication::serializeTextureApplication(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_GRAPH_TextureApplication) SerializeContentPRCBase WriteUnsignedInteger (material_generic_index+1) WriteUnsignedInteger (texture_definition_index+1) WriteUnsignedInteger (next_texture_index+1) WriteUnsignedInteger (UV_coordinates_index+1) } void PRCLinePattern::serializeLinePattern(PRCbitStream &pbs) { uint32_t i = 0; WriteUnsignedInteger (PRC_TYPE_GRAPH_LinePattern) SerializeContentPRCBase const uint32_t size_lengths = lengths.size(); WriteUnsignedInteger (size_lengths) for (i=0;i>8)&0xFF); current_layer_index = l; current_index_of_line_style = i; current_behaviour_bit_field = b; } else pbs << true; } void writeGraphics(PRCbitStream &pbs,const PRCGraphics &graphics,bool force) { if(force || current_layer_index != graphics.layer_index || current_index_of_line_style != graphics.index_of_line_style || current_behaviour_bit_field != graphics.behaviour_bit_field) { pbs << false << (uint32_t)(graphics.layer_index+1) << (uint32_t)(graphics.index_of_line_style+1) << (uint8_t)(graphics.behaviour_bit_field&0xFF) << (uint8_t)((graphics.behaviour_bit_field>>8)&0xFF); current_layer_index = graphics.layer_index; current_index_of_line_style = graphics.index_of_line_style; current_behaviour_bit_field = graphics.behaviour_bit_field; } else pbs << true; } void PRCGraphics::serializeGraphics(PRCbitStream &pbs) { if(current_layer_index != this->layer_index || current_index_of_line_style != this->index_of_line_style || current_behaviour_bit_field != this->behaviour_bit_field) { pbs << false << (uint32_t)(this->layer_index+1) << (uint32_t)(this->index_of_line_style+1) << (uint8_t)(this->behaviour_bit_field&0xFF) << (uint8_t)((this->behaviour_bit_field>>8)&0xFF); current_layer_index = this->layer_index; current_index_of_line_style = this->index_of_line_style; current_behaviour_bit_field = this->behaviour_bit_field; } else pbs << true; } void PRCGraphics::serializeGraphicsForced(PRCbitStream &pbs) { pbs << false << (uint32_t)(this->layer_index+1) << (uint32_t)(this->index_of_line_style+1) << (uint8_t)(this->behaviour_bit_field&0xFF) << (uint8_t)((this->behaviour_bit_field>>8)&0xFF); current_layer_index = this->layer_index; current_index_of_line_style = this->index_of_line_style; current_behaviour_bit_field = this->behaviour_bit_field; } void resetGraphics() { current_layer_index = m1; current_index_of_line_style = m1; current_behaviour_bit_field = 1; } void resetGraphicsAndName() { resetGraphics(); resetName(); } void PRCMarkup::serializeMarkup(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_MKP_Markup) SerializeContentPRCBase SerializeGraphics WriteUnsignedInteger (type) WriteUnsignedInteger (sub_type) const uint32_t number_of_linked_items = 0; WriteUnsignedInteger (number_of_linked_items) // for (i=0;iserializeTransformation3d(pbs); SerializeUserData } void PRCFontKeysSameFont::serializeFontKeysSameFont(PRCbitStream &pbs) { uint32_t i=0; // universal index for PRC standart compatibility WriteString (font_name) WriteUnsignedInteger (char_set) const uint32_t number_of_font_keys = font_keys.size(); WriteUnsignedInteger (number_of_font_keys) for (i=0;i &rgba_vertices,const bool is_rgba, PRCbitStream &pbs) { uint32_t i = 0; uint32_t j = 0; // number_by_vector can be assigned a value of 3 (RGB) or 4 (RGBA). // number_of_vectors is equal to number_of_colors / number_by_vector. const uint32_t number_by_vector=is_rgba?4:3; const std::vector &vector_color = rgba_vertices; const uint32_t number_of_colors=vector_color.size(); const uint32_t number_of_vectors=number_of_colors / number_by_vector; // first one for (i=0;i= 1u<<(bit_number - 1 - i) ) { WriteBoolean (true) value -= 1u<<(bit_number - 1 - i); } else { WriteBoolean (false) } } } #define WriteUnsignedIntegerWithVariableBitNumber( value, bit_number ) writeUnsignedIntegerWithVariableBitNumber( pbs, (value), (bit_number) ); void writeIntegerWithVariableBitNumber(PRCbitStream &pbs, int32_t iValue, uint32_t uBitNumber) { WriteBoolean(iValue<0); WriteUnsignedIntegerWithVariableBitNumber(abs(iValue), uBitNumber - 1); } #define WriteIntegerWithVariableBitNumber( value, bit_number ) writeIntegerWithVariableBitNumber( pbs, (value), (bit_number) ); void writeDoubleWithVariableBitNumber(PRCbitStream &pbs, double dValue,double dTolerance, unsigned uBitNumber) { // calling functions must ensure no overflow int32_t iTempValue = (int32_t) ( dValue / dTolerance ); WriteIntegerWithVariableBitNumber(iTempValue, uBitNumber); } #define WriteDoubleWithVariableBitNumber( value, bit_number ) writeDoubleWithVariableBitNumber( pbs, (value), (bit_number) ); uint32_t GetNumberOfBitsUsedToStoreUnsignedInteger(uint32_t uValue) { uint32_t uNbBit=2; uint32_t uTemp = 2; while(uValue >= uTemp) { uTemp*=2; uNbBit++; } return uNbBit-1; } void writeNumberOfBitsThenUnsignedInteger(PRCbitStream &pbs, uint32_t unsigned_integer) { uint32_t number_of_bits = GetNumberOfBitsUsedToStoreUnsignedInteger( unsigned_integer ); WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits, 5 ) WriteUnsignedIntegerWithVariableBitNumber ( unsigned_integer, number_of_bits ) } #define WriteNumberOfBitsThenUnsignedInteger( value ) writeNumberOfBitsThenUnsignedInteger( pbs, value ); uint32_t GetNumberOfBitsUsedToStoreInteger(int32_t iValue) { return GetNumberOfBitsUsedToStoreUnsignedInteger(abs(iValue))+1; } int32_t intdiv(double dValue, double dTolerance) { double ratio=fabs(dValue)/dTolerance; assert(ratio <= INT_MAX); int32_t iTempValue=(int32_t) ratio; if(ratio - iTempValue >= 0.5) iTempValue++; if(dValue < 0) return -iTempValue; else return iTempValue; } // round dValue to nearest multiple of dTolerance double roundto(double dValue, double dTolerance) { return intdiv(dValue, dTolerance) * dTolerance; } PRCVector3d roundto(PRCVector3d vec, double dTolerance) { PRCVector3d res; res.x = roundto(vec.x,dTolerance); res.y = roundto(vec.y,dTolerance); res.z = roundto(vec.z,dTolerance); return res; } uint32_t GetNumberOfBitsUsedToStoreDouble(double dValue, double dTolerance ) { return GetNumberOfBitsUsedToStoreInteger(intdiv(dValue,dTolerance)); } struct itriple { int32_t x; int32_t y; int32_t z; }; uint32_t GetNumberOfBitsUsedToStoreTripleInteger(const itriple &iTriple) { const uint32_t x_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.x); const uint32_t y_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.y); const uint32_t z_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.z); uint32_t bits = x_bits; if(y_bits > bits) bits = y_bits; if(z_bits > bits) bits = z_bits; return bits; } itriple iroundto(PRCVector3d vec, double dTolerance) { itriple res; res.x = intdiv(vec.x, dTolerance); res.y = intdiv(vec.y, dTolerance); res.z = intdiv(vec.z, dTolerance); return res; } void PRCCompressedFace::serializeCompressedFace(PRCbitStream &pbs, double brep_data_compressed_tolerance) { serializeCompressedAnaNurbs( pbs, brep_data_compressed_tolerance ); } #define SerializeCompressedFace( value ) (value)->serializeCompressedFace( pbs, brep_data_compressed_tolerance ); void PRCCompressedFace::serializeContentCompressedFace(PRCbitStream &pbs) { WriteBoolean ( orientation_surface_with_shell ) const bool surface_is_trimmed = false; WriteBoolean ( surface_is_trimmed ) } void PRCCompressedFace::serializeCompressedAnaNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance) { // WriteCompressedEntityType ( PRC_HCG_AnaNurbs ) const bool is_a_curve = false; WriteBoolean ( is_a_curve ) WriteUnsignedIntegerWithVariableBitNumber (13 , 4) serializeContentCompressedFace( pbs ); serializeCompressedNurbs( pbs, brep_data_compressed_tolerance ); } void PRCCompressedFace::serializeCompressedNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance) { const double nurbs_tolerance = 0.2*brep_data_compressed_tolerance; const uint32_t degree_in_u = degree; const uint32_t degree_in_v = degree; WriteUnsignedIntegerWithVariableBitNumber ( degree_in_u, 5) WriteUnsignedIntegerWithVariableBitNumber ( degree_in_v, 5) const uint32_t number_of_knots_in_u = 4; // 0011 or 00001111 knot vector - just 2 spans WriteUnsignedIntegerWithVariableBitNumber (number_of_knots_in_u - 2, 16) uint32_t number_bit = degree_in_u ? Log2( degree_in_u + 2 ) : 2; WriteBoolean (false) // Multiplicity_is_already_stored - no WriteUnsignedIntegerWithVariableBitNumber( degree_in_u+1,number_bit) WriteBoolean (true) // Multiplicity_is_already_stored - yes const uint32_t number_of_knots_in_v = 4; // 0011 or 00001111 knot vector - just 2 spans WriteUnsignedIntegerWithVariableBitNumber (number_of_knots_in_v - 2, 16) number_bit = degree_in_v ? Log2( degree_in_v + 2 ) : 2; WriteBoolean (false) // Multiplicity_is_already_stored - no WriteUnsignedIntegerWithVariableBitNumber( degree_in_v+1,number_bit) WriteBoolean (true) // Multiplicity_is_already_stored - yes const bool is_closed_u = false; WriteBoolean ( is_closed_u ) const bool is_closed_v = false; WriteBoolean ( is_closed_v ) const uint32_t number_of_control_point_in_u = degree_in_u + 1; const uint32_t number_of_control_point_in_v = degree_in_v + 1; #if defined( __GNUC__ ) && !defined( __clang__ ) PRCVector3d P[number_of_control_point_in_u][number_of_control_point_in_v]; #else vector > P(number_of_control_point_in_u, vector(number_of_control_point_in_v)); #endif for(uint32_t i=0;i > compressed_control_point(number_of_control_point_in_u, vector(number_of_control_point_in_v)); vector > control_point_type(number_of_control_point_in_u, vector(number_of_control_point_in_v)); #endif uint32_t number_of_bits_for_isomin = 1; uint32_t number_of_bits_for_rest = 1; for(uint32_t j = 1; j < number_of_control_point_in_v; j++) { compressed_control_point[0][j] = iroundto(P[0][j]-P[0][j-1], nurbs_tolerance ); P[0][j] = P[0][j-1] + roundto(P[0][j]-P[0][j-1], nurbs_tolerance); uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[0][j]); if (bit_size > number_of_bits_for_isomin) number_of_bits_for_isomin = bit_size; } for(uint32_t i = 1; i < number_of_control_point_in_u; i++) { compressed_control_point[i][0] = iroundto(P[i][0]-P[i-1][0], nurbs_tolerance ); P[i][0] = P[i-1][0] + roundto(P[i][0]-P[i-1][0], nurbs_tolerance); uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[i][0]); if (bit_size > number_of_bits_for_isomin) number_of_bits_for_isomin = bit_size; } for(uint32_t i=1;i number_of_bits_for_rest) number_of_bits_for_rest = bit_size; } if( number_of_bits_for_rest == 2 ) number_of_bits_for_rest--; // really I think it must be unconditional, but so it seems to be done in Adobe Acrobat (9.3) WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits_for_isomin, 20 ) WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits_for_rest, 20 ) WriteDouble ( P[0][0].x ) WriteDouble ( P[0][0].y ) WriteDouble ( P[0][0].z ) for(uint32_t j = 1; j < number_of_control_point_in_v; j++) { WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].x, number_of_bits_for_isomin+1) WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].y, number_of_bits_for_isomin+1) WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].z, number_of_bits_for_isomin+1) } for(uint32_t i = 1; i < number_of_control_point_in_u; i++) { WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].x, number_of_bits_for_isomin+1) WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].y, number_of_bits_for_isomin+1) WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].z, number_of_bits_for_isomin+1) } for(uint32_t i = 1; i < number_of_control_point_in_u; i++) { for(uint32_t j = 1; j < number_of_control_point_in_v; j++) { WriteUnsignedIntegerWithVariableBitNumber ( control_point_type[i][j], 2 ) if(control_point_type[i][j] == 1) { WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].z, number_of_bits_for_rest+1 ) } else if(control_point_type[i][j] == 2) { WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].x, number_of_bits_for_rest+1 ) WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].y, number_of_bits_for_rest+1 ) } else if(control_point_type[i][j] == 3) { WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].x, number_of_bits_for_rest+1 ) WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].y, number_of_bits_for_rest+1 ) WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].z, number_of_bits_for_rest+1 ) } } } const uint32_t type_param_u = 0; WriteBoolean( type_param_u == 0 ) const uint32_t type_param_v = 0; WriteBoolean( type_param_v == 0 ) const bool is_rational = false; WriteBoolean( is_rational ) } void PRCCompressedBrepData::serializeCompressedShell(PRCbitStream &pbs) { uint32_t i; const uint32_t number_of_face = face.size(); WriteBoolean ( number_of_face == 1 ) if( number_of_face != 1 ) WriteNumberOfBitsThenUnsignedInteger (number_of_face) for( i=0; i < number_of_face; i++) SerializeCompressedFace ( face[i] ) const bool is_an_iso_face = false; for( i=0; i < number_of_face; i++) WriteBoolean ( is_an_iso_face ) } void PRCCompressedBrepData::serializeCompressedBrepData(PRCbitStream &pbs) { WriteUnsignedInteger ( PRC_TYPE_TOPO_BrepDataCompress ) SerializeContentBody WriteDouble ( brep_data_compressed_tolerance ) const uint32_t number_of_bits_to_store_reference = 1; WriteNumberOfBitsThenUnsignedInteger ( number_of_bits_to_store_reference ) const uint32_t number_vertex_iso = 0; WriteUnsignedIntegerWithVariableBitNumber ( number_vertex_iso, number_of_bits_to_store_reference ) const uint32_t number_edge_iso = 0; WriteUnsignedIntegerWithVariableBitNumber ( number_edge_iso, number_of_bits_to_store_reference ) const uint32_t number_of_shell = 1; const uint32_t number_of_connex = 1; WriteBoolean ( number_of_shell == 1 && number_of_connex == 1 ) serializeCompressedShell( pbs ); uint32_t i; const uint32_t number_of_faces = face.size(); for(i=0; i< number_of_faces; i++) face[i]->serializeBaseTopology( pbs ); } void PRCBlend01::serializeBlend01(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_SURF_Blend01) SerializeContentSurface SerializeTransformation SerializeUVParameterization SerializePtrCurve ( center_curve ) SerializePtrCurve ( origin_curve ) SerializePtrCurve ( tangent_curve ) } void PRCRuled::serializeRuled(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_SURF_Ruled) SerializeContentSurface SerializeTransformation SerializeUVParameterization SerializePtrCurve ( first_curve ) SerializePtrCurve ( second_curve ) } void PRCSphere::serializeSphere(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_SURF_Sphere) SerializeContentSurface SerializeTransformation SerializeUVParameterization WriteDouble ( radius ) } void PRCCone::serializeCone(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_SURF_Cone) SerializeContentSurface SerializeTransformation SerializeUVParameterization WriteDouble ( bottom_radius ) WriteDouble ( semi_angle ) } void PRCCylinder::serializeCylinder(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_SURF_Cylinder) SerializeContentSurface SerializeTransformation SerializeUVParameterization WriteDouble ( radius ) } void PRCTorus::serializeTorus(PRCbitStream &pbs) { WriteUnsignedInteger (PRC_TYPE_SURF_Torus) SerializeContentSurface SerializeTransformation SerializeUVParameterization WriteDouble ( major_radius ) WriteDouble ( minor_radius ) } void PRCFace::serializeFace(PRCbitStream &pbs) { uint32_t i = 0; WriteUnsignedInteger (PRC_TYPE_TOPO_Face) SerializeBaseTopology SerializePtrSurface ( base_surface ) WriteBit ( have_surface_trim_domain ) if ( have_surface_trim_domain ) SerializeDomain ( surface_trim_domain ) WriteBit ( have_tolerance ) if ( have_tolerance ) WriteDouble ( tolerance ) WriteUnsignedInteger ( number_of_loop ) WriteInteger ( outer_loop_index ) for (i=0;iserialType() ) if ( IsCompressedType(body[i]->serialType()) ) { WriteDouble ( body[i]->serialTolerance() ) } } } void PRCTopoContext::serializeContextGraphics(PRCbitStream &pbs) { uint32_t i=0, j=0, k=0, l=0; ResetCurrentGraphics uint32_t number_of_body = body.size(); PRCGraphicsList element; bool has_graphics = false; for (i=0;itopo_item_type == PRC_TYPE_TOPO_BrepData && dynamic_cast(body[i])) { PRCBrepData *body_i = dynamic_cast(body[i]); for (j=0;jconnex.size();j++) { for(k=0;kconnex[j]->shell.size();k++) { for( l=0;lconnex[j]->shell[k]->face.size();l++) { element.push_back( body_i->connex[j]->shell[k]->face[l] ); has_graphics = has_graphics || body_i->connex[j]->shell[k]->face[l]->has_graphics(); } } } } else if ( body[i]->topo_item_type == PRC_TYPE_TOPO_BrepDataCompress && dynamic_cast(body[i])) { PRCCompressedBrepData *body_i = dynamic_cast(body[i]); for( l=0;lface.size();l++) { element.push_back( body_i->face[l] ); has_graphics = has_graphics || body_i->face[l]->has_graphics(); } } } uint32_t number_of_treat_type = 0; if (has_graphics && !element.empty()) number_of_treat_type = 1; WriteUnsignedInteger (number_of_treat_type) for (i=0;ihas_graphics() ) if (element[j]->has_graphics()) { element[j]->serializeGraphics(pbs); } } } } uint32_t PRCTopoContext::addSingleWireBody(PRCSingleWireBody*& pSingleWireBody) { body.push_back(pSingleWireBody); pSingleWireBody = NULL; return body.size()-1; } uint32_t PRCTopoContext::addBrepData(PRCBrepData*& pBrepData) { body.push_back(pBrepData); pBrepData = NULL; return body.size()-1; } uint32_t PRCTopoContext::addCompressedBrepData(PRCCompressedBrepData*& pCompressedBrepData) { body.push_back(pCompressedBrepData); pCompressedBrepData = NULL; return body.size()-1; } void PRCSingleWireBody::serializeSingleWireBody(PRCbitStream &pbs) { WriteUnsignedInteger ( PRC_TYPE_TOPO_SingleWireBody) SerializeContentBody SerializePtrTopology ( wire_edge ) } void PRCUniqueId::serializeCompressedUniqueId(PRCbitStream &pbs) const { WriteUnsignedInteger (id0) WriteUnsignedInteger (id1) WriteUnsignedInteger (id2) WriteUnsignedInteger (id3) } void PRCUniqueId::serializeFileStructureUncompressedUniqueId(std::ostream& out) const { WriteUncompressedUnsignedInteger (id0) WriteUncompressedUnsignedInteger (id1) WriteUncompressedUnsignedInteger (id2) WriteUncompressedUnsignedInteger (id3) } void PRCUnit::serializeUnit(PRCbitStream &pbs) { WriteBoolean (unit_from_CAD_file) WriteDouble (unit) } void PRCProductOccurrence::serializeProductOccurrence(PRCbitStream &pbs) { WriteUnsignedInteger ( PRC_TYPE_ASM_ProductOccurence ) SerializePRCBaseWithGraphics // SerializeReferencesOfProductOccurrence WriteUnsignedInteger (index_part+1) WriteUnsignedInteger (index_prototype+1) if (index_prototype != m1) { WriteBoolean (prototype_in_same_file_structure) if (!prototype_in_same_file_structure) SerializeCompressedUniqueId (prototype_file_structure) } WriteUnsignedInteger(index_external_data+1) if (index_external_data != m1) { WriteBoolean (external_data_in_same_file_structure) if (!external_data_in_same_file_structure) SerializeCompressedUniqueId (external_data_file_structure) } const uint32_t number_of_son_product_occurrences = index_son_occurrence.size(); WriteUnsignedInteger (number_of_son_product_occurrences) for (uint32_t i=0;iserializeTransformation3d (pbs); WriteUnsignedInteger (0) // number_of_references // SerializeMarkups (markups) WriteUnsignedInteger (0) // number_of_linked_items WriteUnsignedInteger (0) // number_of_leaders WriteUnsignedInteger (0) // number_of_markups WriteUnsignedInteger (0) // number_of_annotation_entities WriteUnsignedInteger (0) // number_of_views WriteBit (false) // has_entity_filter WriteUnsignedInteger (0) // number_of_display_filters WriteUnsignedInteger (0) // number_of_scene_display_parameters SerializeUserData } uint32_t PRCPartDefinition::addBrepModel(PRCBrepModel*& pBrepModel) { representation_item.push_back(pBrepModel); pBrepModel = NULL; return representation_item.size()-1; } uint32_t PRCPartDefinition::addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel) { representation_item.push_back(pPolyBrepModel); pPolyBrepModel = NULL; return representation_item.size()-1; } uint32_t PRCPartDefinition::addPointSet(PRCPointSet*& pPointSet) { representation_item.push_back(pPointSet); pPointSet = NULL; return representation_item.size()-1; } uint32_t PRCPartDefinition::addSet(PRCSet*& pSet) { representation_item.push_back(pSet); pSet = NULL; return representation_item.size()-1; } uint32_t PRCPartDefinition::addWire(PRCWire*& pWire) { representation_item.push_back(pWire); pWire = NULL; return representation_item.size()-1; } uint32_t PRCPartDefinition::addPolyWire(PRCPolyWire*& pPolyWire) { representation_item.push_back(pPolyWire); pPolyWire = NULL; return representation_item.size()-1; } uint32_t PRCPartDefinition::addRepresentationItem(PRCRepresentationItem*& pRepresentationItem) { representation_item.push_back(pRepresentationItem); pRepresentationItem = NULL; return representation_item.size()-1; } void PRCPartDefinition::serializePartDefinition(PRCbitStream &pbs) { WriteUnsignedInteger ( PRC_TYPE_ASM_PartDefinition ) SerializePRCBaseWithGraphics SerializeBoundingBox uint32_t number_of_representation_items = representation_item.size(); WriteUnsignedInteger (number_of_representation_items) for (uint32_t i=0;i= 1600 #include #else typedef signed char int8_t; typedef signed short int16_t; typedef signed long int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; #endif // _MSC_VER >= 1600 #elif defined __BORLANDC__ #include #else #include #endif // _MSC_VER #include //const uint32_t PRCVersion=7094; // For Adobe Reader 8 or later const uint32_t PRCVersion=8137; // For Adobe Reader 9 or later // from Adobe's documentation #define PRC_TYPE_Unknown ( (uint32_t)-1 ) #define PRC_TYPE_ROOT 0 // This type does not correspond to any entity #define PRC_TYPE_ROOT_PRCBase ( PRC_TYPE_ROOT + 1 ) // Abstract root type for any PRC entity. #define PRC_TYPE_ROOT_PRCBaseWithGraphics ( PRC_TYPE_ROOT + 2 ) // Abstract root type for any PRC entity which can bear graphics. #define PRC_TYPE_CRV ( PRC_TYPE_ROOT + 10 ) // Types for PRC geometrical curves #define PRC_TYPE_SURF ( PRC_TYPE_ROOT + 75 ) // Types for PRC geometrical surfaces #define PRC_TYPE_TOPO ( PRC_TYPE_ROOT + 140 ) // Types for PRC topology #define PRC_TYPE_TESS ( PRC_TYPE_ROOT + 170 ) // Types for PRC tessellation #define PRC_TYPE_MISC ( PRC_TYPE_ROOT + 200 ) // Types for PRC global data #define PRC_TYPE_RI ( PRC_TYPE_ROOT + 230 ) // Types for PRC representation items #define PRC_TYPE_ASM ( PRC_TYPE_ROOT + 300 ) // Types for PRC assembly #define PRC_TYPE_MKP ( PRC_TYPE_ROOT + 500 ) // Types for PRC markup #define PRC_TYPE_GRAPH ( PRC_TYPE_ROOT + 700 ) // Types for PRC graphics #define PRC_TYPE_MATH ( PRC_TYPE_ROOT + 900 ) // Types for PRC mathematical operators #define PRC_TYPE_CRV_Base ( PRC_TYPE_CRV + 1 ) // Abstract type for all geometric curves. #define PRC_TYPE_CRV_Blend02Boundary ( PRC_TYPE_CRV + 2 ) // Boundary Curve. #define PRC_TYPE_CRV_NURBS ( PRC_TYPE_CRV + 3 ) // Non Uniform BSpline curve. #define PRC_TYPE_CRV_Circle ( PRC_TYPE_CRV + 4 ) // Circle. #define PRC_TYPE_CRV_Composite ( PRC_TYPE_CRV + 5 ) // Array of oriented curves. #define PRC_TYPE_CRV_OnSurf ( PRC_TYPE_CRV + 6 ) // Curve defined by a UV curve on a surface. #define PRC_TYPE_CRV_Ellipse ( PRC_TYPE_CRV + 7 ) // Ellipse. #define PRC_TYPE_CRV_Equation ( PRC_TYPE_CRV + 8 ) // curve described by specific law elements #define PRC_TYPE_CRV_Helix ( PRC_TYPE_CRV + 9 ) // Helix curve. #define PRC_TYPE_CRV_Hyperbola ( PRC_TYPE_CRV + 10 ) // Hyperbola. #define PRC_TYPE_CRV_Intersection ( PRC_TYPE_CRV + 11 ) // Intersection between 2 surfaces. #define PRC_TYPE_CRV_Line ( PRC_TYPE_CRV + 12 ) // Line. #define PRC_TYPE_CRV_Offset ( PRC_TYPE_CRV + 13 ) // Offset curve. #define PRC_TYPE_CRV_Parabola ( PRC_TYPE_CRV + 14 ) // Parabola. #define PRC_TYPE_CRV_PolyLine ( PRC_TYPE_CRV + 15 ) // Polyedric curve. #define PRC_TYPE_CRV_Transform ( PRC_TYPE_CRV + 16 ) // Transformed curve. #define PRC_TYPE_SURF_Base ( PRC_TYPE_SURF + 1 ) // Abstract type for all geometric surfaces. #define PRC_TYPE_SURF_Blend01 ( PRC_TYPE_SURF + 2 ) // Blend surface. #define PRC_TYPE_SURF_Blend02 ( PRC_TYPE_SURF + 3 ) // Blend Surface. #define PRC_TYPE_SURF_Blend03 ( PRC_TYPE_SURF + 4 ) // Blend Surface. #define PRC_TYPE_SURF_NURBS ( PRC_TYPE_SURF + 5 ) // Non Uniform BSpline surface. #define PRC_TYPE_SURF_Cone ( PRC_TYPE_SURF + 6 ) // Cone. #define PRC_TYPE_SURF_Cylinder ( PRC_TYPE_SURF + 7 ) // Cylinder. #define PRC_TYPE_SURF_Cylindrical ( PRC_TYPE_SURF + 8 ) // Surface who is defined in cylindrical space. #define PRC_TYPE_SURF_Offset ( PRC_TYPE_SURF + 9 ) // Offset surface. #define PRC_TYPE_SURF_Pipe ( PRC_TYPE_SURF + 10 ) // Pipe. #define PRC_TYPE_SURF_Plane ( PRC_TYPE_SURF + 11 ) // Plane. #define PRC_TYPE_SURF_Ruled ( PRC_TYPE_SURF + 12 ) // Ruled surface. #define PRC_TYPE_SURF_Sphere ( PRC_TYPE_SURF + 13 ) // Sphere. #define PRC_TYPE_SURF_Revolution ( PRC_TYPE_SURF + 14 ) // Surface of revolution. #define PRC_TYPE_SURF_Extrusion ( PRC_TYPE_SURF + 15 ) // Surface of extrusion. #define PRC_TYPE_SURF_FromCurves ( PRC_TYPE_SURF + 16 ) // Surface from two curves. #define PRC_TYPE_SURF_Torus ( PRC_TYPE_SURF + 17 ) // Torus. #define PRC_TYPE_SURF_Transform ( PRC_TYPE_SURF + 18 ) // Transformed surface. #define PRC_TYPE_SURF_Blend04 ( PRC_TYPE_SURF + 19 ) // defined for future use. #define PRC_TYPE_TOPO_Context ( PRC_TYPE_TOPO + 1 ) // Self-containing set of topological entities. #define PRC_TYPE_TOPO_Item ( PRC_TYPE_TOPO + 2 ) // Abstract root type for any topological entity (body or single item). #define PRC_TYPE_TOPO_MultipleVertex ( PRC_TYPE_TOPO + 3 ) // Vertex whose position is the average of all edges' extremity positions to whom it belongs. #define PRC_TYPE_TOPO_UniqueVertex ( PRC_TYPE_TOPO + 4 ) // Vertex with one set of coordinates (absolute position). #define PRC_TYPE_TOPO_WireEdge ( PRC_TYPE_TOPO + 5 ) // Edge belonging to a wire body / single wire body. #define PRC_TYPE_TOPO_Edge ( PRC_TYPE_TOPO + 6 ) // Edge belonging to a brep data. #define PRC_TYPE_TOPO_CoEdge ( PRC_TYPE_TOPO + 7 ) // Usage of an edge in a loop. #define PRC_TYPE_TOPO_Loop ( PRC_TYPE_TOPO + 8 ) // Array of co edges which delimits a face. #define PRC_TYPE_TOPO_Face ( PRC_TYPE_TOPO + 9 ) // Topological face delimiting a shell. #define PRC_TYPE_TOPO_Shell ( PRC_TYPE_TOPO + 10 ) // Topological shell (open or closed). #define PRC_TYPE_TOPO_Connex ( PRC_TYPE_TOPO + 11 ) // Topological region delimited by one or several shells. #define PRC_TYPE_TOPO_Body ( PRC_TYPE_TOPO + 12 ) // Abstract root type for any topological body. #define PRC_TYPE_TOPO_SingleWireBody ( PRC_TYPE_TOPO + 13 ) // Single wire body. #define PRC_TYPE_TOPO_BrepData ( PRC_TYPE_TOPO + 14 ) // Main entry to solid and surface topology (regular form). #define PRC_TYPE_TOPO_SingleWireBodyCompress ( PRC_TYPE_TOPO + 15 ) // Single wire body. (ultra compressed form). #define PRC_TYPE_TOPO_BrepDataCompress ( PRC_TYPE_TOPO + 16 ) // Main entry to solid and surface topology (ultra compressed form). #define PRC_TYPE_TOPO_WireBody ( PRC_TYPE_TOPO + 17 ) // This type is the main entry to wire topology. #define PRC_TYPE_TESS_Base ( PRC_TYPE_TESS + 1 ) // Abstract root type for any tessellated entity. #define PRC_TYPE_TESS_3D ( PRC_TYPE_TESS + 2 ) // Tessellated faceted data; regular form. #define PRC_TYPE_TESS_3D_Compressed ( PRC_TYPE_TESS + 3 ) // Tessellated faceted data; highly compressed form. #define PRC_TYPE_TESS_Face ( PRC_TYPE_TESS + 4 ) // Tessellated face. #define PRC_TYPE_TESS_3D_Wire ( PRC_TYPE_TESS + 5 ) // Tessellated wireframe. #define PRC_TYPE_TESS_Markup ( PRC_TYPE_TESS + 6 ) // Tessellated markup. #define PRC_TYPE_MISC_Attribute ( PRC_TYPE_MISC + 1 ) // Entity attribute. #define PRC_TYPE_MISC_CartesianTransformation ( PRC_TYPE_MISC + 2 ) // Cartesian transformation. #define PRC_TYPE_MISC_EntityReference ( PRC_TYPE_MISC + 3 ) // Entity reference. #define PRC_TYPE_MISC_MarkupLinkedItem ( PRC_TYPE_MISC + 4 ) // Link between a markup and an entity. #define PRC_TYPE_MISC_ReferenceOnPRCBase ( PRC_TYPE_MISC + 5 ) // Reference pointing on a regular entity (not topological). #define PRC_TYPE_MISC_ReferenceOnTopology ( PRC_TYPE_MISC + 6 ) // Reference pointing on a topological entity. #define PRC_TYPE_MISC_GeneralTransformation ( PRC_TYPE_MISC + 7 ) // General transformation. #define PRC_TYPE_RI_RepresentationItem ( PRC_TYPE_RI + 1 ) // Basic abstract type for representation items. #define PRC_TYPE_RI_BrepModel ( PRC_TYPE_RI + 2 ) // Basic type for surfaces and solids. #define PRC_TYPE_RI_Curve ( PRC_TYPE_RI + 3 ) // Basic type for curves. #define PRC_TYPE_RI_Direction ( PRC_TYPE_RI + 4 ) // Optional point + vector. #define PRC_TYPE_RI_Plane ( PRC_TYPE_RI + 5 ) // Construction plane, as opposed to planar surface. #define PRC_TYPE_RI_PointSet ( PRC_TYPE_RI + 6 ) // Set of points. #define PRC_TYPE_RI_PolyBrepModel ( PRC_TYPE_RI + 7 ) // Basic type to polyhedral surfaces and solids. #define PRC_TYPE_RI_PolyWire ( PRC_TYPE_RI + 8 ) // Polyedric wireframe entity. #define PRC_TYPE_RI_Set ( PRC_TYPE_RI + 9 ) // Logical grouping of arbitrary number of representation items. #define PRC_TYPE_RI_CoordinateSystem ( PRC_TYPE_RI + 10 ) // Coordinate system. #define PRC_TYPE_ASM_ModelFile ( PRC_TYPE_ASM + 1 ) // Basic entry type for PRC. #define PRC_TYPE_ASM_FileStructure ( PRC_TYPE_ASM + 2 ) // Basic structure for PRC files. #define PRC_TYPE_ASM_FileStructureGlobals ( PRC_TYPE_ASM + 3 ) // Basic structure for PRC files : globals. #define PRC_TYPE_ASM_FileStructureTree ( PRC_TYPE_ASM + 4 ) // Basic structure for PRC files : tree. #define PRC_TYPE_ASM_FileStructureTessellation ( PRC_TYPE_ASM + 5 ) // Basic structure for PRC files : tessellation. #define PRC_TYPE_ASM_FileStructureGeometry ( PRC_TYPE_ASM + 6 ) // Basic structure for PRC files : geometry. #define PRC_TYPE_ASM_FileStructureExtraGeometry ( PRC_TYPE_ASM + 7 ) // Basic structure for PRC files : extra geometry data. #define PRC_TYPE_ASM_ProductOccurence ( PRC_TYPE_ASM + 10 ) // Basic contruct for assemblies. #define PRC_TYPE_ASM_PartDefinition ( PRC_TYPE_ASM + 11 ) // Basic construct for parts. #define PRC_TYPE_ASM_Filter ( PRC_TYPE_ASM + 20 ) #define PRC_TYPE_MKP_View ( PRC_TYPE_MKP + 1 ) // Grouping of markup by views. #define PRC_TYPE_MKP_Markup ( PRC_TYPE_MKP + 2 ) // Basic type for simple markups. #define PRC_TYPE_MKP_Leader ( PRC_TYPE_MKP + 3 ) // basic type for markup leader #define PRC_TYPE_MKP_AnnotationItem ( PRC_TYPE_MKP + 4 ) // Usage of a markup. #define PRC_TYPE_MKP_AnnotationSet ( PRC_TYPE_MKP + 5 ) // Group of annotations. #define PRC_TYPE_MKP_AnnotationReference ( PRC_TYPE_MKP + 6 ) // Logical grouping of annotations for reference. #define PRC_TYPE_GRAPH_Style ( PRC_TYPE_GRAPH + 1 ) // Display style. #define PRC_TYPE_GRAPH_Material ( PRC_TYPE_GRAPH + 2 ) // Display material properties. #define PRC_TYPE_GRAPH_Picture ( PRC_TYPE_GRAPH + 3 ) // Picture. #define PRC_TYPE_GRAPH_TextureApplication ( PRC_TYPE_GRAPH + 11 ) // Texture application. #define PRC_TYPE_GRAPH_TextureDefinition ( PRC_TYPE_GRAPH + 12 ) // Texture definition. #define PRC_TYPE_GRAPH_TextureTransformation ( PRC_TYPE_GRAPH + 13 ) // Texture transformation. #define PRC_TYPE_GRAPH_LinePattern ( PRC_TYPE_GRAPH + 21 ) // One dimensional display style. #define PRC_TYPE_GRAPH_FillPattern ( PRC_TYPE_GRAPH + 22 ) // Abstract class for two-dimensional display style. #define PRC_TYPE_GRAPH_DottingPattern ( PRC_TYPE_GRAPH + 23 ) // Two-dimensional filling with dots. #define PRC_TYPE_GRAPH_HatchingPattern ( PRC_TYPE_GRAPH + 24 ) // Two-dimensional filling with hatches. #define PRC_TYPE_GRAPH_SolidPattern ( PRC_TYPE_GRAPH + 25 ) // Two-dimensional filling with particular style (color, material, texture). #define PRC_TYPE_GRAPH_VPicturePattern ( PRC_TYPE_GRAPH + 26 ) // Two-dimensional filling with vectorised picture. #define PRC_TYPE_GRAPH_AmbientLight ( PRC_TYPE_GRAPH + 31 ) // Scene ambient illumination. #define PRC_TYPE_GRAPH_PointLight ( PRC_TYPE_GRAPH + 32 ) // Scene point illumination. #define PRC_TYPE_GRAPH_DirectionalLight ( PRC_TYPE_GRAPH + 33 ) // Scene directional illumination. #define PRC_TYPE_GRAPH_SpotLight ( PRC_TYPE_GRAPH + 34 ) // Scene spot illumination. #define PRC_TYPE_GRAPH_SceneDisplayParameters ( PRC_TYPE_GRAPH + 41 ) // Parameters for scene visualisation. #define PRC_TYPE_GRAPH_Camera ( PRC_TYPE_GRAPH + 42 ) // #define PRC_TYPE_MATH_FCT_1D ( PRC_TYPE_MATH + 1 ) // Basic type for one degree equation object. #define PRC_TYPE_MATH_FCT_1D_Polynom ( PRC_TYPE_MATH_FCT_1D + 1 ) // Polynomial equation. #define PRC_TYPE_MATH_FCT_1D_Trigonometric ( PRC_TYPE_MATH_FCT_1D + 2 ) // Cosinus based equation. #define PRC_TYPE_MATH_FCT_1D_Fraction ( PRC_TYPE_MATH_FCT_1D + 3 ) // Fraction between 2 one degree equation object. #define PRC_TYPE_MATH_FCT_1D_ArctanCos ( PRC_TYPE_MATH_FCT_1D + 4 ) // Specific equation. #define PRC_TYPE_MATH_FCT_1D_Combination ( PRC_TYPE_MATH_FCT_1D + 5 ) // Combination of one degree equation object. #define PRC_TYPE_MATH_FCT_3D ( PRC_TYPE_MATH + 10 ) // Basic type for 3rd degree equation object. #define PRC_TYPE_MATH_FCT_3D_Linear ( PRC_TYPE_MATH_FCT_3D + 1 ) // Linear transformation ( with a matrix ). #define PRC_TYPE_MATH_FCT_3D_NonLinear ( PRC_TYPE_MATH_FCT_3D + 2 ) // Specific transformation. #define PRC_PRODUCT_FLAG_DEFAULT 0x0001 #define PRC_PRODUCT_FLAG_INTERNAL 0x0002 #define PRC_PRODUCT_FLAG_CONTAINER 0x0004 #define PRC_PRODUCT_FLAG_CONFIG 0x0008 #define PRC_PRODUCT_FLAG_VIEW 0x0010 #define PRC_TRANSFORMATION_Identity 0x00 #define PRC_TRANSFORMATION_Translate 0x01 #define PRC_TRANSFORMATION_Rotate 0x02 #define PRC_TRANSFORMATION_Mirror 0x04 #define PRC_TRANSFORMATION_Scale 0x08 #define PRC_TRANSFORMATION_NonUniformScale 0x10 #define PRC_TRANSFORMATION_NonOrtho 0x20 #define PRC_TRANSFORMATION_Homogeneous 0x40 #define PRC_FACETESSDATA_Polyface 0x0001 #define PRC_FACETESSDATA_Triangle 0x0002 #define PRC_FACETESSDATA_TriangleFan 0x0004 #define PRC_FACETESSDATA_TriangleStripe 0x0008 #define PRC_FACETESSDATA_PolyfaceOneNormal 0x0010 #define PRC_FACETESSDATA_TriangleOneNormal 0x0020 #define PRC_FACETESSDATA_TriangleFanOneNormal 0x0040 #define PRC_FACETESSDATA_TriangleStripeOneNormal 0x0080 #define PRC_FACETESSDATA_PolyfaceTextured 0x0100 #define PRC_FACETESSDATA_TriangleTextured 0x0200 #define PRC_FACETESSDATA_TriangleFanTextured 0x0400 #define PRC_FACETESSDATA_TriangleStripeTextured 0x0800 #define PRC_FACETESSDATA_PolyfaceOneNormalTextured 0x1000 #define PRC_FACETESSDATA_TriangleOneNormalTextured 0x2000 #define PRC_FACETESSDATA_TriangleFanOneNormalTextured 0x4000 #define PRC_FACETESSDATA_TriangleStripeOneNormalTextured 0x8000 #define PRC_FACETESSDATA_NORMAL_Single 0x40000000 #define PRC_FACETESSDATA_NORMAL_Mask 0x3FFFFFFF #define PRC_FACETESSDATA_WIRE_IsNotDrawn 0x4000 // Indicates that the edge should not be drawn (its neighbor will be drawn). #define PRC_FACETESSDATA_WIRE_IsClosing 0x8000 // Indicates that this is the last edge of a loop. #define PRC_3DWIRETESSDATA_IsClosing 0x10000000 // Indicates that the first point is implicitely repeated after the last one to close the wire edge. #define PRC_3DWIRETESSDATA_IsContinuous 0x20000000 // Indicates that the last point of the preceding wire should be linked with the first point of the current one. #define PRC_TEXTURE_MAPPING_DIFFUSE 0x0001 // Diffuse texture mapping attribute. Default value. #define PRC_TEXTURE_MAPPING_BUMP 0x0002 // Bump texture mapping attribute. #define PRC_TEXTURE_MAPPING_OPACITY 0x0004 // Opacity texture mapping attribute. #define PRC_TEXTURE_MAPPING_SPHERICAL_REFLECTION 0x0008 // Spherical reflection texture mapping attribute (used for environment mapping). #define PRC_TEXTURE_MAPPING_CUBICAL_REFLECTION 0x0010 // Cubical reflection texture mapping attribute (used for environment mapping). #define PRC_TEXTURE_MAPPING_REFRACTION 0x0020 // Refraction texture mapping attribute. #define PRC_TEXTURE_MAPPING_SPECULAR 0x0040 // Specular texture mapping attribute. #define PRC_TEXTURE_MAPPING_AMBIENT 0x0080 // Ambient texture mapping attribute. #define PRC_TEXTURE_MAPPING_EMISSION 0x0100 // Emission texture mapping attribute. #define PRC_TEXTURE_APPLYING_MODE_NONE 0x00 // let the application choose #define PRC_TEXTURE_APPLYING_MODE_LIGHTING 0x01 // use lighting mode #define PRC_TEXTURE_APPLYING_MODE_ALPHATEST 0x02 // use alpha test #define PRC_TEXTURE_APPLYING_MODE_VERTEXCOLOR 0x04 // combine a texture with one-color-per-vertex mode #define PRC_TEXTURE_MAPPING_COMPONENTS_RED 0x0001 // Red texture mapping component. #define PRC_TEXTURE_MAPPING_COMPONENTS_GREEN 0x0002 // Green texture mapping component. #define PRC_TEXTURE_MAPPING_COMPONENTS_BLUE 0x0004 // Blue texture mapping component. #define PRC_TEXTURE_MAPPING_COMPONENTS_RGB 0x0007 // RGB texture mapping component. #define PRC_TEXTURE_MAPPING_COMPONENTS_ALPHA 0x0008 // Alpha texture mapping component. #define PRC_TEXTURE_MAPPING_COMPONENTS_RGBA 0x000F // RGBA texture mapping component. enum EPRCModellerAttributeType { KEPRCModellerAttributeTypeNull = 0, KEPRCModellerAttributeTypeInt = 1, KEPRCModellerAttributeTypeReal = 2, KEPRCModellerAttributeTypeTime = 3, KEPRCModellerAttributeTypeString = 4 }; enum EPRCPictureDataFormat { KEPRCPicture_PNG, KEPRCPicture_JPG, KEPRCPicture_BITMAP_RGB_BYTE, KEPRCPicture_BITMAP_RGBA_BYTE, KEPRCPicture_BITMAP_GREY_BYTE, KEPRCPicture_BITMAP_GREYA_BYTE }; enum EPRCProductLoadStatus { KEPRCProductLoadStatus_Unknown = 0, KEPRCProductLoadStatus_Error, KEPRCProductLoadStatus_NotLoaded, KEPRCProductLoadStatus_NotLoadable, KEPRCProductLoadStatus_Loaded }; enum EPRCExtendType { KEPRCExtendTypeNone = 0, // Discontinuous position. KEPRCExtendTypeExt1 = 2, // Same as EPRCExtendTypeCInfinity. KEPRCExtendTypeExt2 = 4, // Same as EPRCExtendTypeG1R for surface, and EPRCExtendTypeG1 for curve. KEPRCExtendTypeG1 = 6, // Continuous in direction but not magnitude of first derivative. KEPRCExtendTypeG1R = 8, // Surface extended with a ruled surface that connects with G1-continuity. KEPRCExtendTypeG1_G2 = 10, // Extended by reflection, yielding a G2 continuous extension. KEPRCExtendTypeCInfinity = 12 // Unlimited continuity. }; enum EPRCKnotType { // Knot vector type KEPRCKnotTypeUniformKnots, // Uniform knot vector. KEPRCKnotTypeUnspecified, // Unspecified knot type. KEPRCKnotTypeQuasiUniformKnots, // Quasi-uniform knot vector. KEPRCKnotTypePiecewiseBezierKnots // Extrema with multiplicities of degree +1. }; // Note : this value is currently unused and should be set to KEPRCKnotTypeUnspecified. enum EPRCBSplineSurfaceForm { KEPRCBSplineSurfaceFormPlane, // Planar surface. KEPRCBSplineSurfaceFormCylindrical, // Cylindrical surface. KEPRCBSplineSurfaceFormConical, // Conical surface. KEPRCBSplineSurfaceFormSpherical, // Spherical surface. KEPRCBSplineSurfaceFormRevolution, // Surface of revolution. KEPRCBSplineSurfaceFormRuled, // Ruled surface. KEPRCBSplineSurfaceFormGeneralizedCone, // Cone. KEPRCBSplineSurfaceFormQuadric, // Quadric surface. KEPRCBSplineSurfaceFormLinearExtrusion, // Surface of extrusion. KEPRCBSplineSurfaceFormUnspecified, // Unspecified surface. KEPRCBSplineSurfaceFormPolynomial // Polynomial surface. }; enum EPRCBSplineCurveForm { // NURBS curve form KEPRCBSplineCurveFormUnspecified, // Unspecified curve form. KEPRCBSplineCurveFormPolyline, // Polygon. KEPRCBSplineCurveFormCircularArc, // Circle arc. KEPRCBSplineCurveFormEllipticArc, // Elliptical arc. KEPRCBSplineCurveFormParabolicArc, // Parabolic arc. KEPRCBSplineCurveFormHyperbolicArc // Hyperbolic arc. }; // Note : this value is currently unused and should be set to KEPRCBSplineCurveFormUnspecified. enum EPRCTextureMappingType { // Defines how to retrieve mapping coordinates. KEPRCTextureMappingType_Unknown, // Let the application choose. KEPRCTextureMappingType_Stored, // Use the mapping coordinates that are stored on a 3D tessellation object KEPRCTextureMappingType_Parametric, // Retrieve the UV coordinates on the surface as mapping coordinates KEPRCTextureMappingType_Operator // Use the defined Texture mapping operator to calculate mapping coordinates }; enum EPRCTextureFunction { // Defines how to paint a texture on the surface being rendered. KEPRCTextureFunction_Unknown, // Let the application choose. KEPRCTextureFunction_Modulate, // Combine lighting with texturing. This is the default value. KEPRCTextureFunction_Replace, // Replace the object color with texture color data. KEPRCTextureFunction_Blend, // Reserved for future use. KEPRCTextureFunction_Decal // Reserved for future use. }; enum EPRCTextureMappingOperator { // The operator to use when computing mapping coordinates. KEPRCTextureMappingOperator_Unknown, // Default value KEPRCTextureMappingOperator_Planar, // Reserved for future use KEPRCTextureMappingOperator_Cylindrical, // Reserved for future use KEPRCTextureMappingOperator_Spherical, // Reserved for future use KEPRCTextureMappingOperator_Cubical // Reserved for future use }; enum EPRCTextureBlendParameter { // Reserved for future use. Defines how to apply blending. KEPRCTextureBlendParameter_Unknown, // Default value. KEPRCTextureBlendParameter_Zero, // Reserved for future use. KEPRCTextureBlendParameter_One, // Reserved for future use. KEPRCTextureBlendParameter_SrcColor, // Reserved for future use. KEPRCTextureBlendParameter_OneMinusSrcColor, // Reserved for future use. KEPRCTextureBlendParameter_DstColor, // Reserved for future use. KEPRCTextureBlendParameter_OneMinusDstColor, // Reserved for future use. KEPRCTextureBlendParameter_SrcAlpha, // Reserved for future use. KEPRCTextureBlendParameter_OneMinusSrcAlpha, // Reserved for future use. KEPRCTextureBlendParameter_DstAlpha, // Reserved for future use. KEPRCTextureBlendParameter_OneMinusDstAlpha, // Reserved for future use. KEPRCTextureBlendParameter_SrcAlphaSaturate // Reserved for future use. }; enum EPRCTextureWrappingMode { // Defines repeating and clamping texture modes. KEPRCTextureWrappingMode_Unknown, // Let the application choose. KEPRCTextureWrappingMode_Repeat, // Display the repeated texture on the surface. KEPRCTextureWrappingMode_ClampToBorder, // Clamp the texture to the border. Display the surface color along the texture limits. KEPRCTextureWrappingMode_Clamp, // Reserved for future use. KEPRCTextureWrappingMode_ClampToEdge, // Reserved for future use. KEPRCTextureWrappingMode_MirroredRepeat // Reserved for future use. }; enum EPRCTextureAlphaTest { // Reserved for future use. Defines how to use a texture alpha test. KEPRCTextureAlphaTest_Unknown, // Default value. KEPRCTextureAlphaTest_Never, // Reserved for future use. KEPRCTextureAlphaTest_Less, // Reserved for future use. KEPRCTextureAlphaTest_Equal, // Reserved for future use. KEPRCTextureAlphaTest_Lequal, // Reserved for future use. KEPRCTextureAlphaTest_Greater, // Reserved for future use. KEPRCTextureAlphaTest_Notequal, // Reserved for future use. KEPRCTextureAlphaTest_Gequal, // Reserved for future use. KEPRCTextureAlphaTest_Always // Reserved for future use. }; // Bit field for graphics behavior #define PRC_GRAPHICS_Show 0x0001 // The entity is shown. #define PRC_GRAPHICS_SonHeritShow 0x0002 // Shown entity son inheritance. #define PRC_GRAPHICS_FatherHeritShow 0x0004 // Shown entity father inheritance. #define PRC_GRAPHICS_SonHeritColor 0x0008 // Color/material son inheritance. #define PRC_GRAPHICS_FatherHeritColor 0x0010 // Color/material father inheritance. #define PRC_GRAPHICS_SonHeritLayer 0x0020 // Layer son inheritance. #define PRC_GRAPHICS_FatherHeritLayer 0x0040 // Layer father inheritance. #define PRC_GRAPHICS_SonHeritTransparency 0x0080 // Transparency son inheritance. #define PRC_GRAPHICS_FatherHeritTransparency 0x0100 // Transparency father inheritance. #define PRC_GRAPHICS_SonHeritLinePattern 0x0200 // Line pattern son inheritance. #define PRC_GRAPHICS_FatherHeritLinePattern 0x0400 // Line pattern father inheritance. #define PRC_GRAPHICS_SonHeritLineWidth 0x0800 // Line width son inheritance. #define PRC_GRAPHICS_FatherHeritLineWidth 0x1000 // Line width father inheritance. #define PRC_GRAPHICS_Removed 0x2000 // The entity has been removed and no longer appears in the tree. enum EPRCMarkupType { KEPRCMarkupType_Unknown = 0, KEPRCMarkupType_Text, KEPRCMarkupType_Dimension, KEPRCMarkupType_Arrow, KEPRCMarkupType_Balloon, KEPRCMarkupType_CircleCenter, KEPRCMarkupType_Coordinate, KEPRCMarkupType_Datum, KEPRCMarkupType_Fastener, KEPRCMarkupType_Gdt, KEPRCMarkupType_Locator, KEPRCMarkupType_MeasurementPoint, KEPRCMarkupType_Roughness, KEPRCMarkupType_Welding, KEPRCMarkupType_Table, KEPRCMarkupType_Other }; enum EPRCMarkupSubType { KEPRCMarkupSubType_Unknown = 0, KEPRCMarkupSubType_EnumMax, KEPRCMarkupSubType_Datum_Ident = 1 , KEPRCMarkupSubType_Datum_EnumMax, KEPRCMarkupSubType_Dimension_Distance = 1, KEPRCMarkupSubType_Dimension_Radius_Tangent, KEPRCMarkupSubType_Dimension_Radius_Cylinder, KEPRCMarkupSubType_Dimension_Radius_Edge, KEPRCMarkupSubType_Dimension_Diameter, KEPRCMarkupSubType_Dimension_Diameter_Tangent, KEPRCMarkupSubType_Dimension_Diameter_Cylinder, KEPRCMarkupSubType_Dimension_Diameter_Edge, KEPRCMarkupSubType_Dimension_Diameter_Cone, KEPRCMarkupSubType_Dimension_Length, KEPRCMarkupSubType_Dimension_Length_Curvilinear, KEPRCMarkupSubType_Dimension_Length_Circular, KEPRCMarkupSubType_Dimension_Angle, KEPRCMarkupSubType_Dimension_EnumMax, KEPRCMarkupSubType_Gdt_Fcf = 1, KEPRCMarkupSubType_Gdt_EnumMax, KEPRCMarkupSubType_Welding_Line = 1, KEPRCMarkupSubType_Welding_EnumMax, KEPRCMarkupSubType_Other_Symbol_User = 1, KEPRCMarkupSubType_Other_EnumMax }; #define PRC_MARKUP_IsHidden 0x01 // The tessellation is hidden. #define PRC_MARKUP_HasFrame 0x02 // The tessellation has a frame. #define PRC_MARKUP_IsNotModifiable 0x04 // The tessellation is given and should not be modified. #define PRC_MARKUP_IsZoomable 0x08 // The tessellation has zoom capability. #define PRC_MARKUP_IsOnTop 0x10 // The tessellation is on top of the geometry. #define PRC_MARKUP_IsFlipable 0x20 // The text tessellation can be flipped to always be readable on screen. This value is currently unused. #define PRC_RENDERING_PARAMETER_SPECIAL_CULLING 0x0001 // special culling strategy to apply #define PRC_RENDERING_PARAMETER_FRONT_CULLING 0x0002 // apply front culling (ignored if no special culling strategy) #define PRC_RENDERING_PARAMETER_BACK_CULLING 0x0004 // apply back culling (ignored if no special culling strategy) #define PRC_RENDERING_PARAMETER_NO_LIGHT 0x0008 // if set, no light will apply on corresponding object #define PRC_MARKUP_IsMatrix 0x08000000 // Bit to denote that the current entity is a matrix. #define PRC_MARKUP_IsExtraData 0x04000000 // Bit to denote that the current entity is extra data (it is neither a matrix nor a polyline). #define PRC_MARKUP_IntegerMask 0xFFFFF // Integer mask to retrieve sizes. #define PRC_MARKUP_ExtraDataType 0x3E00000 // Mask to retrieve the integer type of the entity. #define PRC_MARKUP_ExtraDataType_Pattern (( 0<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Picture (( 1<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Triangles (( 2<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Quads (( 3<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_FaceViewMode (( 6<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_FrameDrawMode (( 7<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_FixedSizeMode (( 8<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Symbol (( 9<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Cylinder ((10<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Color ((11<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_LineStipple ((12<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Font ((13<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Text ((14<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Points ((15<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_Polygon ((16<<21)|PRC_MARKUP_IsExtraData) #define PRC_MARKUP_ExtraDataType_LineWidth ((17<<21)|PRC_MARKUP_IsExtraData) enum EPRCCharSet { KEPRCCharsetUnknown = -1, KEPRCCharsetRoman = 0, KEPRCCharsetJapanese, KEPRCCharsetTraditionalChinese, KEPRCCharsetKorean, KEPRCCharsetArabic, KEPRCCharsetHebrew, KEPRCCharsetGreek, KEPRCCharsetCyrillic, KEPRCCharsetRightLeft, KEPRCCharsetDevanagari, KEPRCCharsetGurmukhi, KEPRCCharsetGujarati, KEPRCCharsetOriya, KEPRCCharsetBengali, KEPRCCharsetTamil, KEPRCCharsetTelugu, KEPRCCharsetKannada, KEPRCCharsetMalayalam, KEPRCCharsetSinhalese, KEPRCCharsetBurmese, KEPRCCharsetKhmer, KEPRCCharsetThai, KEPRCCharsetLaotian, KEPRCCharsetGeorgian, KEPRCCharsetArmenian, KEPRCCharsetSimplifiedChinese, KEPRCCharsetTibetan, KEPRCCharsetMongolian, KEPRCCharsetGeez, KEPRCCharsetEastEuropeanRoman, KEPRCCharsetVietnamese, KEPRCCharsetExtendedArabic }; #define PRC_Font_Bold 0x02 /*!< Bold. */ #define PRC_Font_Italic 0x04 /*!< Italic. */ #define PRC_Font_Underlined 0x08 /*!< Underlined. */ #define PRC_Font_StrikedOut 0x10 /*!< Striked-out. */ #define PRC_Font_Overlined 0x20 /*!< Overlined. */ #define PRC_Font_Streched 0x40 /*!< Streched. In case the font used is not the original font, it indicates that the text needs to be stretched to fit its bounding box. */ #define PRC_Font_Wired 0x80 /*!< Wired. Indicates that the original font is a wirefame font. */ #define PRC_Font_FixedWidth 0x100 /*!< Fixed width. Indicates that the original font is not proportional (each glyph has the same width). */ #define PRC_CONTEXT_OuterLoopFirst 0x0001 // Outer loops are always first loops (specific to PRC_TYPE_TOPO_BrepData). #define PRC_CONTEXT_NoClamp 0x0002 // UV curves are clamped on the surface (specific to PRC_TYPE_TOPO_BrepData). #define PRC_CONTEXT_NoSplit 0x0004 // Faces are split (specific to PRC_TYPE_TOPO_BrepData). #define PRC_BODY_BBOX_Evaluation 0x0001 // Bounding box based on geometry. #define PRC_BODY_BBOX_Precise 0x0002 // Bounding box based on tessellation. #define PRC_BODY_BBOX_CADData 0x0003 // Bounding box given by a CAD data file. #endif // __PRC_H mathgl-2.4.4/src/prc/PRCdouble.h0000644000175000017500000000726513513030041016522 0ustar alastairalastair#ifndef __PRC_DOUBLE_H #define __PRC_DOUBLE_H #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef BYTE_ORDER # undef WORDS_BIG_ENDIAN # undef WORDS_LITTLE_ENDIAN # if BYTE_ORDER == BIG_ENDIAN # define WORDS_BIG_ENDIAN 1 # endif # if BYTE_ORDER == LITTLE_ENDIAN # define WORDS_LITTLE_ENDIAN 1 # endif #endif // from Adobe's documentation union ieee754_double { double d; /* This is the IEEE 754 double-precision format. */ struct { #ifdef WORDS_BIGENDIAN unsigned int negative:1; unsigned int exponent:11; /* Together these comprise the mantissa. */ unsigned int mantissa0:20; unsigned int mantissa1:32; #else /* Together these comprise the mantissa. */ unsigned int mantissa1:32; unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; #endif } ieee; }; union ieee754_float { float f; /* This is the IEEE 754 float-precision format. */ struct { #ifdef WORDS_BIGENDIAN unsigned int negative:1; unsigned int exponent:8; unsigned int mantissa:23; #else unsigned int mantissa:23; unsigned int exponent:8; unsigned int negative:1; #endif } ieee; }; enum ValueType {VT_double,VT_exponent}; struct sCodageOfFrequentDoubleOrExponent { short Type; short NumberOfBits; unsigned Bits; union { unsigned ul[2]; double Value; } u2uod; }; #ifdef WORDS_BIGENDIAN # define DOUBLEWITHTWODWORD(upper,lower) upper,lower # define UPPERPOWER (0) # define LOWERPOWER (!UPPERPOWER) # define NEXTBYTE(pbd) ((pbd)++) # define PREVIOUSBYTE(pbd) ((pbd)--) # define MOREBYTE(pbd,pbend) ((pbd)<=(pbend)) # define OFFSETBYTE(pbd,offset) ((pbd)+=offset) # define BEFOREBYTE(pbd) ((pbd)-1) # define DIFFPOINTERS(p1,p2) ((p1)-(p2)) # define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memrchr((pbstart),(b),(nb)) # define BYTEAT(pb,i) *((pb)-(i)) #else # define DOUBLEWITHTWODWORD(upper,lower) lower,upper # define UPPERPOWER (1) # define LOWERPOWER (!UPPERPOWER) # define NEXTBYTE(pbd) ((pbd)--) # define PREVIOUSBYTE(pbd) ((pbd)++) # define MOREBYTE(pbd,pbend) ((pbd)>=(pbend)) # define OFFSETBYTE(pbd,offset) ((pbd)-=offset) # define BEFOREBYTE(pbd) ((pbd)+1) # define DIFFPOINTERS(p1,p2) ((unsigned)((p2)-(p1))) # define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memchr((pbstart),(b),(nb)) # define BYTEAT(pb,i) *((pb)+(i)) #endif #define MAXLENGTHFORCOMPRESSEDTYPE ((22+1+1+4+6*(1+8))+7)/8 #define NEGATIVE(d) (((union ieee754_double *)&(d))->ieee.negative) #define EXPONENT(d) (((union ieee754_double *)&(d))->ieee.exponent) #define MANTISSA0(d) (((union ieee754_double *)&(d))->ieee.mantissa0) #define MANTISSA1(d) (((union ieee754_double *)&(d))->ieee.mantissa1) typedef unsigned char PRCbyte; typedef unsigned short PRCword; typedef unsigned PRCdword; extern PRCdword stadwZero[2],stadwNegativeZero[2]; #define NUMBEROFELEMENTINACOFDOE (2077) #ifdef WORDS_BIGENDIAN # define DOUBLEWITHTWODWORDINTREE(upper,lower) {upper,lower} #else # define DOUBLEWITHTWODWORDINTREE(upper,lower) {lower,upper} #endif extern sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE]; struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned,short); #define STAT_V #define STAT_DOUBLE int stCOFDOECompare(const void*,const void*); #ifdef WORDS_BIGENDIAN #ifndef HAVE_MEMRCHR void *memrchr(const void *,int,size_t); #endif #endif #endif // __PRC_DOUBLE_H mathgl-2.4.4/src/prc/oPRCFile.h0000644000175000017500000010257513513030041016306 0ustar alastairalastair/************ * * This file is part of a tool for producing 3D content in the PRC format. * Copyright (C) 2008 Orest Shardt * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * *************/ #ifndef __O_PRC_FILE_H #define __O_PRC_FILE_H #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "PRC.h" #include "PRCbitStream.h" #include "writePRC.h" class oPRCFile; class PRCFileStructure; #define EQFLD(fld) fld==c.fld #define COMPFLD(fld) \ if(fld != c.fld) \ return (fld < c.fld); struct RGBAColour { RGBAColour(double r=0.0, double g=0.0, double b=0.0, double a=1.0) : R(r), G(g), B(b), A(a) {} double R,G,B,A; void Set(double r, double g, double b, double a=1.0) { R = r; G = g; B = b; A = a; } bool operator==(const RGBAColour &c) const { return (EQFLD(R) && EQFLD(G) && EQFLD(B) && EQFLD(A)); } bool operator!=(const RGBAColour &c) const { return !(EQFLD(R) && EQFLD(G) && EQFLD(B) && EQFLD(A)); } bool operator<(const RGBAColour &c) const { COMPFLD(R) COMPFLD(G) COMPFLD(B) COMPFLD(A) return false; } friend RGBAColour operator * (const RGBAColour& a, const double d) { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); } friend RGBAColour operator * (const double d, const RGBAColour& a) { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); } }; typedef std::map PRCcolourMap; struct RGBAColourWidth { RGBAColourWidth(double r=0.0, double g=0.0, double b=0.0, double a=1.0, double w=1.0) : R(r), G(g), B(b), A(a), W(w) {} double R,G,B,A,W; bool operator==(const RGBAColourWidth &c) const { return (EQFLD(R) && EQFLD(G) && EQFLD(B) && EQFLD(A) && EQFLD(W)); } bool operator!=(const RGBAColourWidth &c) const { return !(EQFLD(R) && EQFLD(G) && EQFLD(B) && EQFLD(A) && EQFLD(W)); } bool operator<(const RGBAColourWidth &c) const { COMPFLD(R) COMPFLD(G) COMPFLD(B) COMPFLD(A) COMPFLD(W) return false; } }; typedef std::map PRCcolourwidthMap; struct PRCmaterial { PRCmaterial() : alpha(1.0),shininess(1.0),width(1.0) {} PRCmaterial(const RGBAColour &a, const RGBAColour &d, const RGBAColour &e, const RGBAColour &s, double p, double h, double w=1.0) : ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h), width(w) {} RGBAColour ambient,diffuse,emissive,specular; double alpha,shininess,width; bool operator==(const PRCmaterial &c) const { return (EQFLD(ambient) && EQFLD(diffuse) && EQFLD(emissive) && EQFLD(specular) && EQFLD(alpha) && EQFLD(shininess) && EQFLD(width)); } bool operator<(const PRCmaterial &c) const { COMPFLD(ambient) COMPFLD(diffuse) COMPFLD(emissive) COMPFLD(specular) COMPFLD(alpha) COMPFLD(shininess) COMPFLD(width) return false; } }; typedef std::map PRCmaterialMap; #undef EQFLD #undef COMPFLD struct PRCtexture { PRCtexture() : data(NULL), format(KEPRCPicture_BITMAP_RGBA_BYTE), width(0), height(0), size(0), mapping(0), components(PRC_TEXTURE_MAPPING_COMPONENTS_RGBA), function(KEPRCTextureFunction_Modulate), wrapping_mode_S(KEPRCTextureWrappingMode_Repeat), wrapping_mode_T(KEPRCTextureWrappingMode_Repeat) {} const uint8_t* data; EPRCPictureDataFormat format; /* KEPRCPicture_PNG KEPRCPicture_JPG KEPRCPicture_BITMAP_RGB_BYTE KEPRCPicture_BITMAP_RGBA_BYTE KEPRCPicture_BITMAP_GREY_BYTE KEPRCPicture_BITMAP_GREYA_BYTE */ uint32_t width; // may be omitted for PNG and JPEG uint32_t height; // too uint32_t size; uint32_t mapping; /* PRC_TEXTURE_MAPPING_DIFFUSE PRC_TEXTURE_MAPPING_BUMP PRC_TEXTURE_MAPPING_OPACITY PRC_TEXTURE_MAPPING_SPHERICAL_REFLECTION */ uint8_t components; /* PRC_TEXTURE_MAPPING_COMPONENTS_RED PRC_TEXTURE_MAPPING_COMPONENTS_GREEN PRC_TEXTURE_MAPPING_COMPONENTS_BLUE PRC_TEXTURE_MAPPING_COMPONENTS_RGB PRC_TEXTURE_MAPPING_COMPONENTS_ALPHA PRC_TEXTURE_MAPPING_COMPONENTS_RGBA */ EPRCTextureFunction function; /* enum EPRCTextureFunction { // Defines how to paint a texture on the surface being rendered. KEPRCTextureFunction_Unknown, // Let the application choose. KEPRCTextureFunction_Modulate, // Combine lighting with texturing. This is the default value. KEPRCTextureFunction_Replace, // Replace the object color with texture color data. KEPRCTextureFunction_Blend, // Reserved for future use. KEPRCTextureFunction_Decal // Reserved for future use. }; */ EPRCTextureWrappingMode wrapping_mode_S; EPRCTextureWrappingMode wrapping_mode_T; /* enum EPRCTextureWrappingMode { // Defines repeating and clamping texture modes. KEPRCTextureWrappingMode_Unknown, // Let the application choose. KEPRCTextureWrappingMode_Repeat, // Display the repeated texture on the surface. KEPRCTextureWrappingMode_ClampToBorder, // Clamp the texture to the border. Display the surface color along the texture limits. KEPRCTextureWrappingMode_Clamp, // Reserved for future use. KEPRCTextureWrappingMode_ClampToEdge, // Reserved for future use. KEPRCTextureWrappingMode_MirroredRepeat // Reserved for future use. }; */ }; /* struct PRCmaterial { PRCmaterial() : alpha(1.0),shininess(1.0), picture_data(NULL), picture_format(KEPRCPicture_BITMAP_RGB_BYTE), picture_width(0), picture_height(0), picture_size(0), picture_replace(false), picture_repeat(false) {} PRCmaterial(const RGBAColour &a, const RGBAColour &d, const RGBAColour &e, const RGBAColour &s, double p, double h, const uint8_t* pic=NULL, EPRCPictureDataFormat picf=KEPRCPicture_BITMAP_RGB_BYTE, uint32_t picw=0, uint32_t pich=0, uint32_t pics=0, bool picreplace=false, bool picrepeat=false) : ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h), picture_data(pic), picture_format(picf), picture_width(picw), picture_height(pich), picture_size(pics), picture_replace(picreplace), picture_repeat(picrepeat) { if(picture_size==0) { if (picture_format==KEPRCPicture_BITMAP_RGB_BYTE) picture_size = picture_width*picture_height*3; if (picture_format==KEPRCPicture_BITMAP_RGBA_BYTE) picture_size = picture_width*picture_height*4; if (picture_format==KEPRCPicture_BITMAP_GREY_BYTE) picture_size = picture_width*picture_height*1; if (picture_format==KEPRCPicture_BITMAP_GREYA_BYTE) picture_size = picture_width*picture_height*2; } } RGBAColour ambient,diffuse,emissive,specular; double alpha,shininess; const uint8_t* picture_data; EPRCPictureDataFormat picture_format; uint32_t picture_width; uint32_t picture_height; uint32_t picture_size; bool picture_replace; // replace material color with texture color? if false - just modify bool picture_repeat; // repeat texture? if false - clamp to edge bool operator==(const PRCmaterial &m) const { return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive && specular==m.specular && alpha==m.alpha && shininess==m.shininess && picture_replace==m.picture_replace && picture_repeat==m.picture_repeat && picture_format==m.picture_format && picture_width==m.picture_width && picture_height==m.picture_height && picture_size==m.picture_size && (picture_data==m.picture_data || memcmp(picture_data,m.picture_data,picture_size)==0) ); } bool operator<(const PRCmaterial &m) const { if(ambient!=m.ambient) return (ambient PRCmaterialMap; */ struct PRCtessrectangle // rectangle { PRCVector3d vertices[4]; uint32_t style; }; typedef std::vector PRCtessrectangleList; struct PRCtessquad // rectangle { PRCVector3d vertices[4]; RGBAColour colours[4]; }; typedef std::vector PRCtessquadList; /* struct PRCtesstriangle // textured triangle { PRCtesstriangle() : style(m1) {} PRCVector3d vertices[3]; // PRCVector3d normals[3]; // RGBAColour colors[3]; PRCVector2d texcoords[3]; uint32_t style; }; typedef std::vector PRCtesstriangleList; */ struct PRCtessline // polyline { std::vector point; PRCRgbColor color; }; typedef std::list PRCtesslineList; typedef std::map PRCtesslineMap; struct PRCface { PRCface() : transform(NULL), face(NULL) {} uint32_t style; bool transparent; PRCGeneralTransformation3d* transform; PRCFace* face; }; typedef std::vector PRCfaceList; struct PRCcompface { PRCcompface() : face(NULL) {} uint32_t style; bool transparent; PRCCompressedFace* face; }; typedef std::vector PRCcompfaceList; struct PRCwire { PRCwire() : style(m1), transform(NULL), curve(NULL) {} uint32_t style; PRCGeneralTransformation3d* transform; PRCCurve* curve; }; typedef std::vector PRCwireList; typedef std::map > PRCpointsetMap; class PRCoptions { public: double compression; double granularity; bool closed; // render the surface as one-sided; may yield faster rendering bool tess; // use tessellated mesh to store straight patches bool do_break; // bool no_break; // do not render transparent patches as one-faced nodes double crease_angle; // crease angle for meshes PRCoptions(double compression=0.0, double granularity=0.0, bool closed=false, bool tess=false, bool do_break=true, bool no_break=false, double crease_angle=25.8419) : compression(compression), granularity(granularity), closed(closed), tess(tess), do_break(do_break), no_break(no_break), crease_angle(crease_angle) {} }; class PRCgroup { public: PRCgroup() : product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL) {} PRCgroup(const std::string& name) : product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL), name(name) {} PRCProductOccurrence *product_occurrence, *parent_product_occurrence; PRCPartDefinition *part_definition, *parent_part_definition; PRCfaceList faces; PRCcompfaceList compfaces; PRCtessrectangleList rectangles; // PRCtesstriangleList triangles; PRCtessquadList quads; PRCtesslineMap lines; PRCwireList wires; PRCpointsetMap points; std::vector pointsets; std::vector polymodels; std::vector polywires; PRCGeneralTransformation3d* transform; std::string name; PRCoptions options; }; void makeFileUUID(PRCUniqueId&); void makeAppUUID(PRCUniqueId&); class PRCStartHeader { public: uint32_t minimal_version_for_read; // PRCVersion uint32_t authoring_version; // PRCVersion PRCUniqueId file_structure_uuid; PRCUniqueId application_uuid; // should be 0 PRCStartHeader() : minimal_version_for_read(PRCVersion), authoring_version(PRCVersion) {} void serializeStartHeader(std::ostream&) const; void serializeUncompressedFiles(std::ostream&) const; PRCUncompressedFileList uncompressed_files; uint32_t getStartHeaderSize() const; uint32_t getUncompressedFilesSize() const; }; class PRCFileStructure : public PRCStartHeader { public: uint32_t number_of_referenced_file_structures; double tessellation_chord_height_ratio; double tessellation_angle_degree; std::string default_font_family_name; PRCRgbColorList colors; PRCRgbColorMap colorMap; PRCPictureList pictures; PRCPictureMap pictureMap; PRCUncompressedFileMap uncompressedfileMap; PRCTextureDefinitionList texture_definitions; PRCTextureDefinitionMap texturedefinitionMap; PRCMaterialList materials; PRCMaterialGenericMap materialgenericMap; PRCTextureApplicationMap textureapplicationMap; PRCStyleList styles; PRCStyleMap styleMap; PRCCoordinateSystemList reference_coordinate_systems; std::vector font_keys_of_font; PRCPartDefinitionList part_definitions; PRCProductOccurrenceList product_occurrences; // PRCMarkupList markups; // PRCAnnotationItemList annotation_entities; double unit; PRCTopoContextList contexts; PRCTessList tessellations; uint32_t sizes[6]; uint8_t *globals_data; PRCbitStream globals_out; // order matters: PRCbitStream must be initialized last uint8_t *tree_data; PRCbitStream tree_out; uint8_t *tessellations_data; PRCbitStream tessellations_out; uint8_t *geometry_data; PRCbitStream geometry_out; uint8_t *extraGeometry_data; PRCbitStream extraGeometry_out; ~PRCFileStructure () { for(PRCUncompressedFileList::iterator it=uncompressed_files.begin(); it!=uncompressed_files.end(); ++it) delete *it; for(PRCPictureList::iterator it=pictures.begin(); it!=pictures.end(); ++it) delete *it; for(PRCTextureDefinitionList::iterator it=texture_definitions.begin(); it!=texture_definitions.end(); ++it) delete *it; for(PRCMaterialList::iterator it=materials.begin(); it!=materials.end(); ++it) delete *it; for(PRCStyleList::iterator it=styles.begin(); it!=styles.end(); ++it) delete *it; for(PRCTopoContextList::iterator it=contexts.begin(); it!=contexts.end(); ++it) delete *it; for(PRCTessList::iterator it=tessellations.begin(); it!=tessellations.end(); ++it) delete *it; for(PRCPartDefinitionList::iterator it=part_definitions.begin(); it!=part_definitions.end(); ++it) delete *it; for(PRCProductOccurrenceList::iterator it=product_occurrences.begin(); it!=product_occurrences.end(); ++it) delete *it; for(PRCCoordinateSystemList::iterator it=reference_coordinate_systems.begin(); it!=reference_coordinate_systems.end(); it++) delete *it; free(globals_data); free(tree_data); free(tessellations_data); free(geometry_data); free(extraGeometry_data); } PRCFileStructure() : number_of_referenced_file_structures(0), tessellation_chord_height_ratio(2000.0),tessellation_angle_degree(40.0), default_font_family_name(""), unit(1), globals_data(NULL),globals_out(globals_data,0), tree_data(NULL),tree_out(tree_data,0), tessellations_data(NULL),tessellations_out(tessellations_data,0), geometry_data(NULL),geometry_out(geometry_data,0), extraGeometry_data(NULL),extraGeometry_out(extraGeometry_data,0) {} void write(std::ostream&); void prepare(); uint32_t getSize(); void serializeFileStructureGlobals(PRCbitStream&); void serializeFileStructureTree(PRCbitStream&); void serializeFileStructureTessellation(PRCbitStream&); void serializeFileStructureGeometry(PRCbitStream&); void serializeFileStructureExtraGeometry(PRCbitStream&); uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0, std::string name=""); #define ADD_ADDUNIQ( prctype ) \ uint32_t add##prctype( PRC##prctype*& p##prctype ); \ uint32_t add##prctype##Unique( PRC##prctype*& p##prctype); ADD_ADDUNIQ( UncompressedFile ) ADD_ADDUNIQ( Picture ) ADD_ADDUNIQ( TextureDefinition ) ADD_ADDUNIQ( TextureApplication ) ADD_ADDUNIQ( MaterialGeneric ) ADD_ADDUNIQ( Style ) #undef ADD_ADDUNIQ uint32_t addRgbColor(double r, double g, double b); uint32_t addRgbColorUnique(double r, double g, double b); uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition); uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence); uint32_t addTopoContext(PRCTopoContext*& pTopoContext); uint32_t getTopoContext(PRCTopoContext*& pTopoContext); uint32_t add3DTess(PRC3DTess*& p3DTess); uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess); /* uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess); uint32_t addMarkup(PRCMarkup*& pMarkup); uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem); */ uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem); uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem); }; class PRCFileStructureInformation { public: PRCUniqueId UUID; uint32_t reserved; // 0 uint32_t number_of_offsets; uint32_t *offsets; void write(std::ostream&); uint32_t getSize(); }; class PRCHeader : public PRCStartHeader { public : uint32_t number_of_file_structures; PRCFileStructureInformation *fileStructureInformation; uint32_t model_file_offset; uint32_t file_size; // not documented void write(std::ostream&); uint32_t getSize(); }; typedef std::map PRCtransformMap; class oPRCFile { public: oPRCFile(std::ostream &os, double u=1, uint32_t n=1) : number_of_file_structures(n), fileStructures(new PRCFileStructure*[n]), unit(u), modelFile_data(NULL),modelFile_out(modelFile_data,0), fout(NULL),output(os) { for(uint32_t i = 0; i < number_of_file_structures; ++i) { fileStructures[i] = new PRCFileStructure(); fileStructures[i]->minimal_version_for_read = PRCVersion; fileStructures[i]->authoring_version = PRCVersion; makeFileUUID(fileStructures[i]->file_structure_uuid); makeAppUUID(fileStructures[i]->application_uuid); fileStructures[i]->unit = u; } groups.push(PRCgroup()); PRCgroup &group = groups.top(); group.name="root"; group.transform = NULL; group.product_occurrence = new PRCProductOccurrence(group.name); group.parent_product_occurrence = NULL; group.part_definition = new PRCPartDefinition; group.parent_part_definition = NULL; } oPRCFile(const std::string &name, double u=1, uint32_t n=1) : number_of_file_structures(n), fileStructures(new PRCFileStructure*[n]), unit(u), modelFile_data(NULL),modelFile_out(modelFile_data,0), fout(new std::ofstream(name.c_str(), std::ios::out|std::ios::binary|std::ios::trunc)), output(*fout) { for(uint32_t i = 0; i < number_of_file_structures; ++i) { fileStructures[i] = new PRCFileStructure(); fileStructures[i]->minimal_version_for_read = PRCVersion; fileStructures[i]->authoring_version = PRCVersion; makeFileUUID(fileStructures[i]->file_structure_uuid); makeAppUUID(fileStructures[i]->application_uuid); fileStructures[i]->unit = u; } groups.push(PRCgroup()); PRCgroup &group = groups.top(); group.name="root"; group.transform = NULL; group.product_occurrence = new PRCProductOccurrence(group.name); group.parent_product_occurrence = NULL; group.part_definition = new PRCPartDefinition; group.parent_part_definition = NULL; } ~oPRCFile() { for(uint32_t i = 0; i < number_of_file_structures; ++i) delete fileStructures[i]; delete[] fileStructures; if(fout != NULL) delete fout; free(modelFile_data); } void begingroup(const char *name, const PRCoptions *options=NULL, const double* t=NULL); void endgroup(); std::string lastgroupname; std::vector lastgroupnames; std::string calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence); bool finish(); uint32_t getSize(); const uint32_t number_of_file_structures; PRCFileStructure **fileStructures; PRCHeader header; PRCUnit unit; uint8_t *modelFile_data; PRCbitStream modelFile_out; // order matters: PRCbitStream must be initialized last PRCmaterialMap materialMap; PRCcolourMap colourMap; PRCcolourwidthMap colourwidthMap; PRCgroup rootGroup; PRCtransformMap transformMap; std::stack groups; PRCgroup& findGroup(); void doGroup(PRCgroup& group); uint32_t addColour(const RGBAColour &colour); uint32_t addColourWidth(const RGBAColour &colour, double width); uint32_t addLineMaterial(const RGBAColour& c, double width) { return addColourWidth(c,width); } uint32_t addMaterial(const PRCmaterial &material); uint32_t addTexturedMaterial(const PRCmaterial &material, uint32_t n=0, const PRCtexture* const* tt=NULL); uint32_t addTransform(PRCGeneralTransformation3d*& transform); uint32_t addTransform(const double* t); uint32_t addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale); void addPoint(const double P[3], const RGBAColour &c, double w=1.0); void addPoint(double x, double y, double z, const RGBAColour &c, double w); void addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w=1.0); void addPoints(uint32_t n, const double P[][3], uint32_t style_index); void addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[], const RGBAColour& c, double w, bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]); uint32_t createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[], bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]); uint32_t createSegments(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][2], bool segment_color, uint32_t nC, const RGBAColour C[], const uint32_t CI[][2]); void addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m, uint32_t nN, const double N[][3], const uint32_t NI[][3], uint32_t nT, const double T[][2], const uint32_t TI[][3], uint32_t nC, const RGBAColour C[], const uint32_t CI[][3], uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca); uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], uint32_t style_index, uint32_t nN, const double N[][3], const uint32_t NI[][3], uint32_t nT, const double T[][2], const uint32_t TI[][3], uint32_t nC, const RGBAColour C[], const uint32_t CI[][3], uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca); uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m, uint32_t nN, const double N[][3], const uint32_t NI[][3], uint32_t nT, const double T[][2], const uint32_t TI[][3], uint32_t nC, const RGBAColour C[], const uint32_t CI[][3], uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca) { const uint32_t style = addMaterial(m); if(M!=NULL && nM>0) { uint32_t* const styles = new uint32_t[nM]; for(uint32_t i=0; i0) { uint32_t* const styles = new uint32_t[nM]; for(uint32_t i=0; iaddPicture(format, size, picture, width, height, name); } #define ADD_ADDUNIQ( prctype ) \ uint32_t add##prctype(PRC##prctype*& p##prctype, uint32_t fileStructure=0) \ { return fileStructures[fileStructure]->add##prctype( p##prctype ); } \ uint32_t add##prctype##Unique(PRC##prctype*& p##prctype, uint32_t fileStructure=0) \ { return fileStructures[fileStructure]->add##prctype##Unique(p##prctype); } ADD_ADDUNIQ( TextureDefinition ) ADD_ADDUNIQ( TextureApplication ) ADD_ADDUNIQ( MaterialGeneric ) ADD_ADDUNIQ( Style ) #undef ADD_ADDUNIQ uint32_t addRgbColor(double r, double g, double b, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addRgbColor(r, g, b); } uint32_t addRgbColorUnique(double r, double g, double b, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addRgbColorUnique(r, g, b); } uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addPartDefinition(pPartDefinition); } uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addProductOccurrence(pProductOccurrence); } uint32_t addTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addTopoContext(pTopoContext); } uint32_t getTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0) { return fileStructures[fileStructure]->getTopoContext(pTopoContext); } uint32_t add3DTess(PRC3DTess*& p3DTess, uint32_t fileStructure=0) { return fileStructures[fileStructure]->add3DTess(p3DTess); } uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess, uint32_t fileStructure=0) { return fileStructures[fileStructure]->add3DWireTess(p3DWireTess); } /* uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addMarkupTess(pMarkupTess); } uint32_t addMarkup(PRCMarkup*& pMarkup, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addMarkup(pMarkup); } uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addAnnotationItem(pAnnotationItem); } */ uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addCoordinateSystem(pCoordinateSystem); } uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0) { return fileStructures[fileStructure]->addCoordinateSystemUnique(pCoordinateSystem); } private: void serializeModelFileData(PRCbitStream&); std::ofstream *fout; std::ostream &output; }; #endif // __O_PRC_FILE_H mathgl-2.4.4/src/prc/PRCdouble.cc0000644000175000017500000053213613513030041016660 0ustar alastairalastair#include "PRCdouble.h" // from Adobe's documentation PRCdword stadwZero[2]={DOUBLEWITHTWODWORD(0x00000000,0x00000000)}; PRCdword stadwNegativeZero[2]={DOUBLEWITHTWODWORD(0x80000000,0x00000000)}; struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned Bits, short NumberOfBits) { struct sCodageOfFrequentDoubleOrExponent *pcofdoe; for(pcofdoe=acofdoe; pcofdoe < acofdoe+NUMBEROFELEMENTINACOFDOE; ++pcofdoe) { if(pcofdoe->NumberOfBits == NumberOfBits && pcofdoe->Bits == Bits) return pcofdoe; } return NULL; } int stCOFDOECompare(const void* pcofdoe1,const void* pcofdoe2) { return(EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe1)->u2uod.Value)- EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe2)->u2uod.Value)); } #ifdef WORDS_BIGENDIAN #ifndef HAVE_MEMRCHR void *memrchr(const void *buf,int c,size_t count) { unsigned char *pcBuffer=(unsigned char *)buf, *pcBufferEnd=pcBuffer-count; for(;pcBuffer>pcBufferEnd;pcBuffer--) if(*pcBuffer==c) return(pcBuffer); return(NULL); } #endif #endif sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE] = { {VT_double,2,0x1,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}}, {VT_exponent,22,0xd1d32,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}}, {VT_exponent,22,0xd1d33,{DOUBLEWITHTWODWORDINTREE(0x00100000,0x00000000)}}, {VT_exponent,22,0xf78d8,{DOUBLEWITHTWODWORDINTREE(0x00200000,0x00000000)}}, {VT_exponent,22,0xf78d9,{DOUBLEWITHTWODWORDINTREE(0x00300000,0x00000000)}}, {VT_exponent,22,0xf78da,{DOUBLEWITHTWODWORDINTREE(0x00400000,0x00000000)}}, {VT_exponent,22,0xf78db,{DOUBLEWITHTWODWORDINTREE(0x00500000,0x00000000)}}, {VT_exponent,22,0xf78dc,{DOUBLEWITHTWODWORDINTREE(0x00600000,0x00000000)}}, {VT_exponent,22,0xf78dd,{DOUBLEWITHTWODWORDINTREE(0x00700000,0x00000000)}}, {VT_exponent,22,0xf78de,{DOUBLEWITHTWODWORDINTREE(0x00800000,0x00000000)}}, {VT_exponent,22,0xf78df,{DOUBLEWITHTWODWORDINTREE(0x00900000,0x00000000)}}, {VT_exponent,22,0xf78e0,{DOUBLEWITHTWODWORDINTREE(0x00a00000,0x00000000)}}, {VT_exponent,22,0xf78e1,{DOUBLEWITHTWODWORDINTREE(0x00b00000,0x00000000)}}, {VT_exponent,22,0xf78e2,{DOUBLEWITHTWODWORDINTREE(0x00c00000,0x00000000)}}, {VT_exponent,22,0xf78e3,{DOUBLEWITHTWODWORDINTREE(0x00d00000,0x00000000)}}, {VT_exponent,22,0xf78e4,{DOUBLEWITHTWODWORDINTREE(0x00e00000,0x00000000)}}, {VT_exponent,22,0xf78e5,{DOUBLEWITHTWODWORDINTREE(0x00f00000,0x00000000)}}, {VT_exponent,22,0xf78e6,{DOUBLEWITHTWODWORDINTREE(0x01000000,0x00000000)}}, {VT_exponent,22,0xf78e7,{DOUBLEWITHTWODWORDINTREE(0x01100000,0x00000000)}}, {VT_exponent,22,0xf78e8,{DOUBLEWITHTWODWORDINTREE(0x01200000,0x00000000)}}, {VT_exponent,22,0xf78e9,{DOUBLEWITHTWODWORDINTREE(0x01300000,0x00000000)}}, {VT_exponent,22,0xf78ea,{DOUBLEWITHTWODWORDINTREE(0x01400000,0x00000000)}}, {VT_exponent,22,0xf78eb,{DOUBLEWITHTWODWORDINTREE(0x01500000,0x00000000)}}, {VT_exponent,22,0xf78ec,{DOUBLEWITHTWODWORDINTREE(0x01600000,0x00000000)}}, {VT_exponent,22,0xf78ed,{DOUBLEWITHTWODWORDINTREE(0x01700000,0x00000000)}}, {VT_exponent,22,0xf78ee,{DOUBLEWITHTWODWORDINTREE(0x01800000,0x00000000)}}, {VT_exponent,22,0xf78ef,{DOUBLEWITHTWODWORDINTREE(0x01900000,0x00000000)}}, {VT_exponent,22,0xf78f0,{DOUBLEWITHTWODWORDINTREE(0x01a00000,0x00000000)}}, {VT_exponent,22,0xf78f1,{DOUBLEWITHTWODWORDINTREE(0x01b00000,0x00000000)}}, {VT_exponent,22,0xf78f2,{DOUBLEWITHTWODWORDINTREE(0x01c00000,0x00000000)}}, {VT_exponent,22,0xf78f3,{DOUBLEWITHTWODWORDINTREE(0x01d00000,0x00000000)}}, {VT_exponent,22,0xf78f4,{DOUBLEWITHTWODWORDINTREE(0x01e00000,0x00000000)}}, {VT_exponent,22,0xf78f5,{DOUBLEWITHTWODWORDINTREE(0x01f00000,0x00000000)}}, {VT_exponent,22,0xf78f6,{DOUBLEWITHTWODWORDINTREE(0x02000000,0x00000000)}}, {VT_exponent,22,0xf78f7,{DOUBLEWITHTWODWORDINTREE(0x02100000,0x00000000)}}, {VT_exponent,22,0xf78f8,{DOUBLEWITHTWODWORDINTREE(0x02200000,0x00000000)}}, {VT_exponent,22,0xf78f9,{DOUBLEWITHTWODWORDINTREE(0x02300000,0x00000000)}}, {VT_exponent,22,0xf78fa,{DOUBLEWITHTWODWORDINTREE(0x02400000,0x00000000)}}, {VT_exponent,22,0xf78fb,{DOUBLEWITHTWODWORDINTREE(0x02500000,0x00000000)}}, {VT_exponent,22,0xf78fc,{DOUBLEWITHTWODWORDINTREE(0x02600000,0x00000000)}}, {VT_exponent,22,0xf78fd,{DOUBLEWITHTWODWORDINTREE(0x02700000,0x00000000)}}, {VT_exponent,22,0xf78fe,{DOUBLEWITHTWODWORDINTREE(0x02800000,0x00000000)}}, {VT_exponent,22,0xf78ff,{DOUBLEWITHTWODWORDINTREE(0x02900000,0x00000000)}}, {VT_exponent,22,0x3a8300,{DOUBLEWITHTWODWORDINTREE(0x02a00000,0x00000000)}}, {VT_exponent,22,0x3a8301,{DOUBLEWITHTWODWORDINTREE(0x02b00000,0x00000000)}}, {VT_exponent,22,0x3a8302,{DOUBLEWITHTWODWORDINTREE(0x02c00000,0x00000000)}}, {VT_exponent,22,0x3a8303,{DOUBLEWITHTWODWORDINTREE(0x02d00000,0x00000000)}}, {VT_exponent,22,0x3a8304,{DOUBLEWITHTWODWORDINTREE(0x02e00000,0x00000000)}}, {VT_exponent,22,0x3a8305,{DOUBLEWITHTWODWORDINTREE(0x02f00000,0x00000000)}}, {VT_exponent,22,0x3a8306,{DOUBLEWITHTWODWORDINTREE(0x03000000,0x00000000)}}, {VT_exponent,22,0x3a8307,{DOUBLEWITHTWODWORDINTREE(0x03100000,0x00000000)}}, {VT_exponent,22,0x3a8308,{DOUBLEWITHTWODWORDINTREE(0x03200000,0x00000000)}}, {VT_exponent,22,0x3a8309,{DOUBLEWITHTWODWORDINTREE(0x03300000,0x00000000)}}, {VT_exponent,22,0x3a830a,{DOUBLEWITHTWODWORDINTREE(0x03400000,0x00000000)}}, {VT_exponent,22,0x3a830b,{DOUBLEWITHTWODWORDINTREE(0x03500000,0x00000000)}}, {VT_exponent,22,0x3a830c,{DOUBLEWITHTWODWORDINTREE(0x03600000,0x00000000)}}, {VT_exponent,22,0x3a830d,{DOUBLEWITHTWODWORDINTREE(0x03700000,0x00000000)}}, {VT_exponent,22,0x3a830e,{DOUBLEWITHTWODWORDINTREE(0x03800000,0x00000000)}}, {VT_exponent,22,0x3a830f,{DOUBLEWITHTWODWORDINTREE(0x03900000,0x00000000)}}, {VT_exponent,22,0x3a8310,{DOUBLEWITHTWODWORDINTREE(0x03a00000,0x00000000)}}, {VT_exponent,22,0x3a8311,{DOUBLEWITHTWODWORDINTREE(0x03b00000,0x00000000)}}, {VT_exponent,22,0x3a8312,{DOUBLEWITHTWODWORDINTREE(0x03c00000,0x00000000)}}, {VT_exponent,22,0x3a8313,{DOUBLEWITHTWODWORDINTREE(0x03d00000,0x00000000)}}, {VT_exponent,22,0x3a8314,{DOUBLEWITHTWODWORDINTREE(0x03e00000,0x00000000)}}, {VT_exponent,22,0x3a8315,{DOUBLEWITHTWODWORDINTREE(0x03f00000,0x00000000)}}, {VT_exponent,22,0x3a8316,{DOUBLEWITHTWODWORDINTREE(0x04000000,0x00000000)}}, {VT_exponent,22,0x3a8317,{DOUBLEWITHTWODWORDINTREE(0x04100000,0x00000000)}}, {VT_exponent,22,0x3a8318,{DOUBLEWITHTWODWORDINTREE(0x04200000,0x00000000)}}, {VT_exponent,22,0x3a8319,{DOUBLEWITHTWODWORDINTREE(0x04300000,0x00000000)}}, {VT_exponent,22,0x3a831a,{DOUBLEWITHTWODWORDINTREE(0x04400000,0x00000000)}}, {VT_exponent,22,0x3a831b,{DOUBLEWITHTWODWORDINTREE(0x04500000,0x00000000)}}, {VT_exponent,22,0x3a831c,{DOUBLEWITHTWODWORDINTREE(0x04600000,0x00000000)}}, {VT_exponent,22,0x3a831d,{DOUBLEWITHTWODWORDINTREE(0x04700000,0x00000000)}}, {VT_exponent,22,0x3a831e,{DOUBLEWITHTWODWORDINTREE(0x04800000,0x00000000)}}, {VT_exponent,22,0x3a831f,{DOUBLEWITHTWODWORDINTREE(0x04900000,0x00000000)}}, {VT_exponent,22,0x3a8320,{DOUBLEWITHTWODWORDINTREE(0x04a00000,0x00000000)}}, {VT_exponent,22,0x3a8321,{DOUBLEWITHTWODWORDINTREE(0x04b00000,0x00000000)}}, {VT_exponent,22,0x3a8322,{DOUBLEWITHTWODWORDINTREE(0x04c00000,0x00000000)}}, {VT_exponent,22,0x3a8323,{DOUBLEWITHTWODWORDINTREE(0x04d00000,0x00000000)}}, {VT_exponent,22,0x3a8324,{DOUBLEWITHTWODWORDINTREE(0x04e00000,0x00000000)}}, {VT_exponent,22,0x3a8325,{DOUBLEWITHTWODWORDINTREE(0x04f00000,0x00000000)}}, {VT_exponent,22,0x3a8326,{DOUBLEWITHTWODWORDINTREE(0x05000000,0x00000000)}}, {VT_exponent,22,0x3a8327,{DOUBLEWITHTWODWORDINTREE(0x05100000,0x00000000)}}, {VT_exponent,22,0x3a8328,{DOUBLEWITHTWODWORDINTREE(0x05200000,0x00000000)}}, {VT_exponent,22,0x3a8329,{DOUBLEWITHTWODWORDINTREE(0x05300000,0x00000000)}}, {VT_exponent,22,0x3a832a,{DOUBLEWITHTWODWORDINTREE(0x05400000,0x00000000)}}, {VT_exponent,22,0x3a832b,{DOUBLEWITHTWODWORDINTREE(0x05500000,0x00000000)}}, {VT_exponent,22,0x3a832c,{DOUBLEWITHTWODWORDINTREE(0x05600000,0x00000000)}}, {VT_exponent,22,0x3a832d,{DOUBLEWITHTWODWORDINTREE(0x05700000,0x00000000)}}, {VT_exponent,22,0x3a832e,{DOUBLEWITHTWODWORDINTREE(0x05800000,0x00000000)}}, {VT_exponent,22,0x3a832f,{DOUBLEWITHTWODWORDINTREE(0x05900000,0x00000000)}}, {VT_exponent,22,0x3a8330,{DOUBLEWITHTWODWORDINTREE(0x05a00000,0x00000000)}}, {VT_exponent,22,0x3a8331,{DOUBLEWITHTWODWORDINTREE(0x05b00000,0x00000000)}}, {VT_exponent,22,0x3a8332,{DOUBLEWITHTWODWORDINTREE(0x05c00000,0x00000000)}}, {VT_exponent,22,0x3a8333,{DOUBLEWITHTWODWORDINTREE(0x05d00000,0x00000000)}}, {VT_exponent,22,0x3a8334,{DOUBLEWITHTWODWORDINTREE(0x05e00000,0x00000000)}}, {VT_exponent,22,0x3a8335,{DOUBLEWITHTWODWORDINTREE(0x05f00000,0x00000000)}}, {VT_exponent,22,0x3a8336,{DOUBLEWITHTWODWORDINTREE(0x06000000,0x00000000)}}, {VT_exponent,22,0x3a8337,{DOUBLEWITHTWODWORDINTREE(0x06100000,0x00000000)}}, {VT_exponent,22,0x3a8338,{DOUBLEWITHTWODWORDINTREE(0x06200000,0x00000000)}}, {VT_exponent,22,0x3a8339,{DOUBLEWITHTWODWORDINTREE(0x06300000,0x00000000)}}, {VT_exponent,22,0x3a833a,{DOUBLEWITHTWODWORDINTREE(0x06400000,0x00000000)}}, {VT_exponent,22,0x3a833b,{DOUBLEWITHTWODWORDINTREE(0x06500000,0x00000000)}}, {VT_exponent,22,0x3a833c,{DOUBLEWITHTWODWORDINTREE(0x06600000,0x00000000)}}, {VT_exponent,22,0x3a833d,{DOUBLEWITHTWODWORDINTREE(0x06700000,0x00000000)}}, {VT_exponent,22,0x3a833e,{DOUBLEWITHTWODWORDINTREE(0x06800000,0x00000000)}}, {VT_exponent,22,0x3a833f,{DOUBLEWITHTWODWORDINTREE(0x06900000,0x00000000)}}, {VT_exponent,22,0x3a8340,{DOUBLEWITHTWODWORDINTREE(0x06a00000,0x00000000)}}, {VT_exponent,22,0x3a8341,{DOUBLEWITHTWODWORDINTREE(0x06b00000,0x00000000)}}, {VT_exponent,22,0x3a8342,{DOUBLEWITHTWODWORDINTREE(0x06c00000,0x00000000)}}, {VT_exponent,22,0x3a8343,{DOUBLEWITHTWODWORDINTREE(0x06d00000,0x00000000)}}, {VT_exponent,22,0x3a8344,{DOUBLEWITHTWODWORDINTREE(0x06e00000,0x00000000)}}, {VT_exponent,22,0x3a8345,{DOUBLEWITHTWODWORDINTREE(0x06f00000,0x00000000)}}, {VT_exponent,22,0x3a8346,{DOUBLEWITHTWODWORDINTREE(0x07000000,0x00000000)}}, {VT_exponent,22,0x3a8347,{DOUBLEWITHTWODWORDINTREE(0x07100000,0x00000000)}}, {VT_exponent,22,0x3a8348,{DOUBLEWITHTWODWORDINTREE(0x07200000,0x00000000)}}, {VT_exponent,22,0x3a8349,{DOUBLEWITHTWODWORDINTREE(0x07300000,0x00000000)}}, {VT_exponent,22,0x3a834a,{DOUBLEWITHTWODWORDINTREE(0x07400000,0x00000000)}}, {VT_exponent,22,0x3a834b,{DOUBLEWITHTWODWORDINTREE(0x07500000,0x00000000)}}, {VT_exponent,22,0x3a834c,{DOUBLEWITHTWODWORDINTREE(0x07600000,0x00000000)}}, {VT_exponent,22,0x3a834d,{DOUBLEWITHTWODWORDINTREE(0x07700000,0x00000000)}}, {VT_exponent,22,0x3a834e,{DOUBLEWITHTWODWORDINTREE(0x07800000,0x00000000)}}, {VT_exponent,22,0x3a834f,{DOUBLEWITHTWODWORDINTREE(0x07900000,0x00000000)}}, {VT_exponent,22,0x3a8350,{DOUBLEWITHTWODWORDINTREE(0x07a00000,0x00000000)}}, {VT_exponent,22,0x3a8351,{DOUBLEWITHTWODWORDINTREE(0x07b00000,0x00000000)}}, {VT_exponent,22,0x3a8352,{DOUBLEWITHTWODWORDINTREE(0x07c00000,0x00000000)}}, {VT_exponent,22,0x3a8353,{DOUBLEWITHTWODWORDINTREE(0x07d00000,0x00000000)}}, {VT_exponent,22,0x3a8354,{DOUBLEWITHTWODWORDINTREE(0x07e00000,0x00000000)}}, {VT_exponent,22,0x3a8355,{DOUBLEWITHTWODWORDINTREE(0x07f00000,0x00000000)}}, {VT_exponent,22,0x3a8356,{DOUBLEWITHTWODWORDINTREE(0x08000000,0x00000000)}}, {VT_exponent,22,0x3a8357,{DOUBLEWITHTWODWORDINTREE(0x08100000,0x00000000)}}, {VT_exponent,22,0x3a8358,{DOUBLEWITHTWODWORDINTREE(0x08200000,0x00000000)}}, {VT_exponent,22,0x3a8359,{DOUBLEWITHTWODWORDINTREE(0x08300000,0x00000000)}}, {VT_exponent,22,0x3a835a,{DOUBLEWITHTWODWORDINTREE(0x08400000,0x00000000)}}, {VT_exponent,22,0x3a835b,{DOUBLEWITHTWODWORDINTREE(0x08500000,0x00000000)}}, {VT_exponent,22,0x3a835c,{DOUBLEWITHTWODWORDINTREE(0x08600000,0x00000000)}}, {VT_exponent,22,0x3a835d,{DOUBLEWITHTWODWORDINTREE(0x08700000,0x00000000)}}, {VT_exponent,22,0x3a835e,{DOUBLEWITHTWODWORDINTREE(0x08800000,0x00000000)}}, {VT_exponent,22,0x3a835f,{DOUBLEWITHTWODWORDINTREE(0x08900000,0x00000000)}}, {VT_exponent,22,0x3a8360,{DOUBLEWITHTWODWORDINTREE(0x08a00000,0x00000000)}}, {VT_exponent,22,0x3a8361,{DOUBLEWITHTWODWORDINTREE(0x08b00000,0x00000000)}}, {VT_exponent,22,0x3a8362,{DOUBLEWITHTWODWORDINTREE(0x08c00000,0x00000000)}}, {VT_exponent,22,0x3a8363,{DOUBLEWITHTWODWORDINTREE(0x08d00000,0x00000000)}}, {VT_exponent,22,0x3a8364,{DOUBLEWITHTWODWORDINTREE(0x08e00000,0x00000000)}}, {VT_exponent,22,0x3a8365,{DOUBLEWITHTWODWORDINTREE(0x08f00000,0x00000000)}}, {VT_exponent,22,0x3a8366,{DOUBLEWITHTWODWORDINTREE(0x09000000,0x00000000)}}, {VT_exponent,22,0x3a8367,{DOUBLEWITHTWODWORDINTREE(0x09100000,0x00000000)}}, {VT_exponent,22,0x3a8368,{DOUBLEWITHTWODWORDINTREE(0x09200000,0x00000000)}}, {VT_exponent,22,0x3a8369,{DOUBLEWITHTWODWORDINTREE(0x09300000,0x00000000)}}, {VT_exponent,22,0x3a836a,{DOUBLEWITHTWODWORDINTREE(0x09400000,0x00000000)}}, {VT_exponent,22,0x3a836b,{DOUBLEWITHTWODWORDINTREE(0x09500000,0x00000000)}}, {VT_exponent,22,0x3a836c,{DOUBLEWITHTWODWORDINTREE(0x09600000,0x00000000)}}, {VT_exponent,22,0x3a836d,{DOUBLEWITHTWODWORDINTREE(0x09700000,0x00000000)}}, {VT_exponent,22,0x3a836e,{DOUBLEWITHTWODWORDINTREE(0x09800000,0x00000000)}}, {VT_exponent,22,0x3a836f,{DOUBLEWITHTWODWORDINTREE(0x09900000,0x00000000)}}, {VT_exponent,22,0x3a8370,{DOUBLEWITHTWODWORDINTREE(0x09a00000,0x00000000)}}, {VT_exponent,22,0x3a8371,{DOUBLEWITHTWODWORDINTREE(0x09b00000,0x00000000)}}, {VT_exponent,22,0x3a8372,{DOUBLEWITHTWODWORDINTREE(0x09c00000,0x00000000)}}, {VT_exponent,22,0x3a8373,{DOUBLEWITHTWODWORDINTREE(0x09d00000,0x00000000)}}, {VT_exponent,22,0x3a8374,{DOUBLEWITHTWODWORDINTREE(0x09e00000,0x00000000)}}, {VT_exponent,22,0x3a8375,{DOUBLEWITHTWODWORDINTREE(0x09f00000,0x00000000)}}, {VT_exponent,22,0x3a8376,{DOUBLEWITHTWODWORDINTREE(0x0a000000,0x00000000)}}, {VT_exponent,22,0x3a8377,{DOUBLEWITHTWODWORDINTREE(0x0a100000,0x00000000)}}, {VT_exponent,22,0x3a8378,{DOUBLEWITHTWODWORDINTREE(0x0a200000,0x00000000)}}, {VT_exponent,22,0x3a8379,{DOUBLEWITHTWODWORDINTREE(0x0a300000,0x00000000)}}, {VT_exponent,22,0x3a837a,{DOUBLEWITHTWODWORDINTREE(0x0a400000,0x00000000)}}, {VT_exponent,22,0x3a837b,{DOUBLEWITHTWODWORDINTREE(0x0a500000,0x00000000)}}, {VT_exponent,22,0x3a837c,{DOUBLEWITHTWODWORDINTREE(0x0a600000,0x00000000)}}, {VT_exponent,22,0x3a837d,{DOUBLEWITHTWODWORDINTREE(0x0a700000,0x00000000)}}, {VT_exponent,22,0x3a837e,{DOUBLEWITHTWODWORDINTREE(0x0a800000,0x00000000)}}, {VT_exponent,22,0x3a837f,{DOUBLEWITHTWODWORDINTREE(0x0a900000,0x00000000)}}, {VT_exponent,22,0x3a8380,{DOUBLEWITHTWODWORDINTREE(0x0aa00000,0x00000000)}}, {VT_exponent,22,0x3a8381,{DOUBLEWITHTWODWORDINTREE(0x0ab00000,0x00000000)}}, {VT_exponent,22,0x3a8382,{DOUBLEWITHTWODWORDINTREE(0x0ac00000,0x00000000)}}, {VT_exponent,22,0x3a8383,{DOUBLEWITHTWODWORDINTREE(0x0ad00000,0x00000000)}}, {VT_exponent,22,0x3a8384,{DOUBLEWITHTWODWORDINTREE(0x0ae00000,0x00000000)}}, {VT_exponent,22,0x3a8385,{DOUBLEWITHTWODWORDINTREE(0x0af00000,0x00000000)}}, {VT_exponent,22,0x3a8386,{DOUBLEWITHTWODWORDINTREE(0x0b000000,0x00000000)}}, {VT_exponent,22,0x3a8387,{DOUBLEWITHTWODWORDINTREE(0x0b100000,0x00000000)}}, {VT_exponent,22,0x3a8388,{DOUBLEWITHTWODWORDINTREE(0x0b200000,0x00000000)}}, {VT_exponent,22,0x3a8389,{DOUBLEWITHTWODWORDINTREE(0x0b300000,0x00000000)}}, {VT_exponent,22,0x3a838a,{DOUBLEWITHTWODWORDINTREE(0x0b400000,0x00000000)}}, {VT_exponent,22,0x3a838b,{DOUBLEWITHTWODWORDINTREE(0x0b500000,0x00000000)}}, {VT_exponent,22,0x3a838c,{DOUBLEWITHTWODWORDINTREE(0x0b600000,0x00000000)}}, {VT_exponent,22,0x3a838d,{DOUBLEWITHTWODWORDINTREE(0x0b700000,0x00000000)}}, {VT_exponent,22,0x3a838e,{DOUBLEWITHTWODWORDINTREE(0x0b800000,0x00000000)}}, {VT_exponent,22,0x3a838f,{DOUBLEWITHTWODWORDINTREE(0x0b900000,0x00000000)}}, {VT_exponent,22,0x3a8390,{DOUBLEWITHTWODWORDINTREE(0x0ba00000,0x00000000)}}, {VT_exponent,22,0x3a8391,{DOUBLEWITHTWODWORDINTREE(0x0bb00000,0x00000000)}}, {VT_exponent,22,0x3a8392,{DOUBLEWITHTWODWORDINTREE(0x0bc00000,0x00000000)}}, {VT_exponent,22,0x3a8393,{DOUBLEWITHTWODWORDINTREE(0x0bd00000,0x00000000)}}, {VT_exponent,22,0x3a8394,{DOUBLEWITHTWODWORDINTREE(0x0be00000,0x00000000)}}, {VT_exponent,22,0x3a8395,{DOUBLEWITHTWODWORDINTREE(0x0bf00000,0x00000000)}}, {VT_exponent,22,0x3a8396,{DOUBLEWITHTWODWORDINTREE(0x0c000000,0x00000000)}}, {VT_exponent,22,0x3a8397,{DOUBLEWITHTWODWORDINTREE(0x0c100000,0x00000000)}}, {VT_exponent,22,0x3a8398,{DOUBLEWITHTWODWORDINTREE(0x0c200000,0x00000000)}}, {VT_exponent,22,0x3a8399,{DOUBLEWITHTWODWORDINTREE(0x0c300000,0x00000000)}}, {VT_exponent,22,0x3a839a,{DOUBLEWITHTWODWORDINTREE(0x0c400000,0x00000000)}}, {VT_exponent,22,0x3a839b,{DOUBLEWITHTWODWORDINTREE(0x0c500000,0x00000000)}}, {VT_exponent,22,0x3a839c,{DOUBLEWITHTWODWORDINTREE(0x0c600000,0x00000000)}}, {VT_exponent,22,0x3a839d,{DOUBLEWITHTWODWORDINTREE(0x0c700000,0x00000000)}}, {VT_exponent,22,0x3a839e,{DOUBLEWITHTWODWORDINTREE(0x0c800000,0x00000000)}}, {VT_exponent,22,0x3a839f,{DOUBLEWITHTWODWORDINTREE(0x0c900000,0x00000000)}}, {VT_exponent,22,0x3a83a0,{DOUBLEWITHTWODWORDINTREE(0x0ca00000,0x00000000)}}, {VT_exponent,22,0x3a83a1,{DOUBLEWITHTWODWORDINTREE(0x0cb00000,0x00000000)}}, {VT_exponent,22,0x3a83a2,{DOUBLEWITHTWODWORDINTREE(0x0cc00000,0x00000000)}}, {VT_exponent,22,0x3a83a3,{DOUBLEWITHTWODWORDINTREE(0x0cd00000,0x00000000)}}, {VT_exponent,22,0x3a83a4,{DOUBLEWITHTWODWORDINTREE(0x0ce00000,0x00000000)}}, {VT_exponent,22,0x3a83a5,{DOUBLEWITHTWODWORDINTREE(0x0cf00000,0x00000000)}}, {VT_exponent,22,0x3a83a6,{DOUBLEWITHTWODWORDINTREE(0x0d000000,0x00000000)}}, {VT_exponent,22,0x3a83a7,{DOUBLEWITHTWODWORDINTREE(0x0d100000,0x00000000)}}, {VT_exponent,22,0x3a83a8,{DOUBLEWITHTWODWORDINTREE(0x0d200000,0x00000000)}}, {VT_exponent,22,0x3a83a9,{DOUBLEWITHTWODWORDINTREE(0x0d300000,0x00000000)}}, {VT_exponent,22,0x3a83aa,{DOUBLEWITHTWODWORDINTREE(0x0d400000,0x00000000)}}, {VT_exponent,22,0x3a83ab,{DOUBLEWITHTWODWORDINTREE(0x0d500000,0x00000000)}}, {VT_exponent,22,0x3a83ac,{DOUBLEWITHTWODWORDINTREE(0x0d600000,0x00000000)}}, {VT_exponent,22,0x3a83ad,{DOUBLEWITHTWODWORDINTREE(0x0d700000,0x00000000)}}, {VT_exponent,22,0x3a83ae,{DOUBLEWITHTWODWORDINTREE(0x0d800000,0x00000000)}}, {VT_exponent,22,0x3a83af,{DOUBLEWITHTWODWORDINTREE(0x0d900000,0x00000000)}}, {VT_exponent,22,0x3a83b0,{DOUBLEWITHTWODWORDINTREE(0x0da00000,0x00000000)}}, {VT_exponent,22,0x3a83b1,{DOUBLEWITHTWODWORDINTREE(0x0db00000,0x00000000)}}, {VT_exponent,22,0x3a83b2,{DOUBLEWITHTWODWORDINTREE(0x0dc00000,0x00000000)}}, {VT_exponent,22,0x3a83b3,{DOUBLEWITHTWODWORDINTREE(0x0dd00000,0x00000000)}}, {VT_exponent,22,0x3a83b4,{DOUBLEWITHTWODWORDINTREE(0x0de00000,0x00000000)}}, {VT_exponent,22,0x3a83b5,{DOUBLEWITHTWODWORDINTREE(0x0df00000,0x00000000)}}, {VT_exponent,22,0x3a83b6,{DOUBLEWITHTWODWORDINTREE(0x0e000000,0x00000000)}}, {VT_exponent,22,0x3a83b7,{DOUBLEWITHTWODWORDINTREE(0x0e100000,0x00000000)}}, {VT_exponent,22,0x3a83b8,{DOUBLEWITHTWODWORDINTREE(0x0e200000,0x00000000)}}, {VT_exponent,22,0x3a83b9,{DOUBLEWITHTWODWORDINTREE(0x0e300000,0x00000000)}}, {VT_exponent,22,0x3a83ba,{DOUBLEWITHTWODWORDINTREE(0x0e400000,0x00000000)}}, {VT_exponent,22,0x3a83bb,{DOUBLEWITHTWODWORDINTREE(0x0e500000,0x00000000)}}, {VT_exponent,22,0x3a83bc,{DOUBLEWITHTWODWORDINTREE(0x0e600000,0x00000000)}}, {VT_exponent,22,0x3a83bd,{DOUBLEWITHTWODWORDINTREE(0x0e700000,0x00000000)}}, {VT_exponent,22,0x3a83be,{DOUBLEWITHTWODWORDINTREE(0x0e800000,0x00000000)}}, {VT_exponent,22,0x3a83bf,{DOUBLEWITHTWODWORDINTREE(0x0e900000,0x00000000)}}, {VT_exponent,22,0x3a83c0,{DOUBLEWITHTWODWORDINTREE(0x0ea00000,0x00000000)}}, {VT_exponent,22,0x3a83c1,{DOUBLEWITHTWODWORDINTREE(0x0eb00000,0x00000000)}}, {VT_exponent,22,0x3a83c2,{DOUBLEWITHTWODWORDINTREE(0x0ec00000,0x00000000)}}, {VT_exponent,22,0x3a83c3,{DOUBLEWITHTWODWORDINTREE(0x0ed00000,0x00000000)}}, {VT_exponent,22,0x3a83c4,{DOUBLEWITHTWODWORDINTREE(0x0ee00000,0x00000000)}}, {VT_exponent,22,0x3a83c5,{DOUBLEWITHTWODWORDINTREE(0x0ef00000,0x00000000)}}, {VT_exponent,22,0x3a83c6,{DOUBLEWITHTWODWORDINTREE(0x0f000000,0x00000000)}}, {VT_exponent,22,0x3a83c7,{DOUBLEWITHTWODWORDINTREE(0x0f100000,0x00000000)}}, {VT_exponent,22,0x3a83c8,{DOUBLEWITHTWODWORDINTREE(0x0f200000,0x00000000)}}, {VT_exponent,22,0x3a83c9,{DOUBLEWITHTWODWORDINTREE(0x0f300000,0x00000000)}}, {VT_exponent,22,0x3a83ca,{DOUBLEWITHTWODWORDINTREE(0x0f400000,0x00000000)}}, {VT_exponent,22,0x3a83cb,{DOUBLEWITHTWODWORDINTREE(0x0f500000,0x00000000)}}, {VT_exponent,22,0x3a83cc,{DOUBLEWITHTWODWORDINTREE(0x0f600000,0x00000000)}}, {VT_exponent,22,0x3a83cd,{DOUBLEWITHTWODWORDINTREE(0x0f700000,0x00000000)}}, {VT_exponent,22,0x3a83ce,{DOUBLEWITHTWODWORDINTREE(0x0f800000,0x00000000)}}, {VT_exponent,22,0x3a83cf,{DOUBLEWITHTWODWORDINTREE(0x0f900000,0x00000000)}}, {VT_exponent,22,0x3a83d0,{DOUBLEWITHTWODWORDINTREE(0x0fa00000,0x00000000)}}, {VT_exponent,22,0x3a83d1,{DOUBLEWITHTWODWORDINTREE(0x0fb00000,0x00000000)}}, {VT_exponent,22,0x3a83d2,{DOUBLEWITHTWODWORDINTREE(0x0fc00000,0x00000000)}}, {VT_exponent,22,0x3a83d3,{DOUBLEWITHTWODWORDINTREE(0x0fd00000,0x00000000)}}, {VT_exponent,22,0x3a83d4,{DOUBLEWITHTWODWORDINTREE(0x0fe00000,0x00000000)}}, {VT_exponent,22,0x3a83d5,{DOUBLEWITHTWODWORDINTREE(0x0ff00000,0x00000000)}}, {VT_exponent,22,0x3a83d6,{DOUBLEWITHTWODWORDINTREE(0x10000000,0x00000000)}}, {VT_exponent,22,0x3a83d7,{DOUBLEWITHTWODWORDINTREE(0x10100000,0x00000000)}}, {VT_exponent,22,0x3a83d8,{DOUBLEWITHTWODWORDINTREE(0x10200000,0x00000000)}}, {VT_exponent,22,0x3a83d9,{DOUBLEWITHTWODWORDINTREE(0x10300000,0x00000000)}}, {VT_exponent,22,0x3a83da,{DOUBLEWITHTWODWORDINTREE(0x10400000,0x00000000)}}, {VT_exponent,22,0x3a83db,{DOUBLEWITHTWODWORDINTREE(0x10500000,0x00000000)}}, {VT_exponent,22,0x3a83dc,{DOUBLEWITHTWODWORDINTREE(0x10600000,0x00000000)}}, {VT_exponent,22,0x3a83dd,{DOUBLEWITHTWODWORDINTREE(0x10700000,0x00000000)}}, {VT_exponent,22,0x3a83de,{DOUBLEWITHTWODWORDINTREE(0x10800000,0x00000000)}}, {VT_exponent,22,0x3a83df,{DOUBLEWITHTWODWORDINTREE(0x10900000,0x00000000)}}, {VT_exponent,22,0x3a83e0,{DOUBLEWITHTWODWORDINTREE(0x10a00000,0x00000000)}}, {VT_exponent,22,0x3a83e1,{DOUBLEWITHTWODWORDINTREE(0x10b00000,0x00000000)}}, {VT_exponent,22,0x3a83e2,{DOUBLEWITHTWODWORDINTREE(0x10c00000,0x00000000)}}, {VT_exponent,22,0x3a83e3,{DOUBLEWITHTWODWORDINTREE(0x10d00000,0x00000000)}}, {VT_exponent,22,0x3a83e4,{DOUBLEWITHTWODWORDINTREE(0x10e00000,0x00000000)}}, {VT_exponent,22,0x3a83e5,{DOUBLEWITHTWODWORDINTREE(0x10f00000,0x00000000)}}, {VT_exponent,22,0x3a83e6,{DOUBLEWITHTWODWORDINTREE(0x11000000,0x00000000)}}, {VT_exponent,22,0x3a83e7,{DOUBLEWITHTWODWORDINTREE(0x11100000,0x00000000)}}, {VT_exponent,22,0x3a83e8,{DOUBLEWITHTWODWORDINTREE(0x11200000,0x00000000)}}, {VT_exponent,22,0x3a83e9,{DOUBLEWITHTWODWORDINTREE(0x11300000,0x00000000)}}, {VT_exponent,22,0x3a83ea,{DOUBLEWITHTWODWORDINTREE(0x11400000,0x00000000)}}, {VT_exponent,22,0x3a83eb,{DOUBLEWITHTWODWORDINTREE(0x11500000,0x00000000)}}, {VT_exponent,22,0x3a83ec,{DOUBLEWITHTWODWORDINTREE(0x11600000,0x00000000)}}, {VT_exponent,22,0x3a83ed,{DOUBLEWITHTWODWORDINTREE(0x11700000,0x00000000)}}, {VT_exponent,22,0x3a83ee,{DOUBLEWITHTWODWORDINTREE(0x11800000,0x00000000)}}, {VT_exponent,22,0x3a83ef,{DOUBLEWITHTWODWORDINTREE(0x11900000,0x00000000)}}, {VT_exponent,22,0x3a83f0,{DOUBLEWITHTWODWORDINTREE(0x11a00000,0x00000000)}}, {VT_exponent,22,0x3a83f1,{DOUBLEWITHTWODWORDINTREE(0x11b00000,0x00000000)}}, {VT_exponent,22,0x3a83f2,{DOUBLEWITHTWODWORDINTREE(0x11c00000,0x00000000)}}, {VT_exponent,22,0x3a83f3,{DOUBLEWITHTWODWORDINTREE(0x11d00000,0x00000000)}}, {VT_exponent,22,0x3a83f4,{DOUBLEWITHTWODWORDINTREE(0x11e00000,0x00000000)}}, {VT_exponent,22,0x3a83f5,{DOUBLEWITHTWODWORDINTREE(0x11f00000,0x00000000)}}, {VT_exponent,22,0x3a83f6,{DOUBLEWITHTWODWORDINTREE(0x12000000,0x00000000)}}, {VT_exponent,22,0x3a83f7,{DOUBLEWITHTWODWORDINTREE(0x12100000,0x00000000)}}, {VT_exponent,22,0x3a83f8,{DOUBLEWITHTWODWORDINTREE(0x12200000,0x00000000)}}, {VT_exponent,22,0x3a83f9,{DOUBLEWITHTWODWORDINTREE(0x12300000,0x00000000)}}, {VT_exponent,22,0x3a83fa,{DOUBLEWITHTWODWORDINTREE(0x12400000,0x00000000)}}, {VT_exponent,22,0x3a83fb,{DOUBLEWITHTWODWORDINTREE(0x12500000,0x00000000)}}, {VT_exponent,22,0x3a83fc,{DOUBLEWITHTWODWORDINTREE(0x12600000,0x00000000)}}, {VT_exponent,22,0x3a83fd,{DOUBLEWITHTWODWORDINTREE(0x12700000,0x00000000)}}, {VT_exponent,22,0x3a83fe,{DOUBLEWITHTWODWORDINTREE(0x12800000,0x00000000)}}, {VT_exponent,22,0x3a83ff,{DOUBLEWITHTWODWORDINTREE(0x12900000,0x00000000)}}, {VT_exponent,22,0x3a8400,{DOUBLEWITHTWODWORDINTREE(0x12a00000,0x00000000)}}, {VT_exponent,22,0x3a8401,{DOUBLEWITHTWODWORDINTREE(0x12b00000,0x00000000)}}, {VT_exponent,22,0x3a8402,{DOUBLEWITHTWODWORDINTREE(0x12c00000,0x00000000)}}, {VT_exponent,22,0x3a8403,{DOUBLEWITHTWODWORDINTREE(0x12d00000,0x00000000)}}, {VT_exponent,22,0x3a8404,{DOUBLEWITHTWODWORDINTREE(0x12e00000,0x00000000)}}, {VT_exponent,22,0x3a8405,{DOUBLEWITHTWODWORDINTREE(0x12f00000,0x00000000)}}, {VT_exponent,22,0x3a8406,{DOUBLEWITHTWODWORDINTREE(0x13000000,0x00000000)}}, {VT_exponent,22,0x3a8407,{DOUBLEWITHTWODWORDINTREE(0x13100000,0x00000000)}}, {VT_exponent,22,0x3a8408,{DOUBLEWITHTWODWORDINTREE(0x13200000,0x00000000)}}, {VT_exponent,22,0x3a8409,{DOUBLEWITHTWODWORDINTREE(0x13300000,0x00000000)}}, {VT_exponent,22,0x3a840a,{DOUBLEWITHTWODWORDINTREE(0x13400000,0x00000000)}}, {VT_exponent,22,0x3a840b,{DOUBLEWITHTWODWORDINTREE(0x13500000,0x00000000)}}, {VT_exponent,22,0x3a840c,{DOUBLEWITHTWODWORDINTREE(0x13600000,0x00000000)}}, {VT_exponent,22,0x3a840d,{DOUBLEWITHTWODWORDINTREE(0x13700000,0x00000000)}}, {VT_exponent,22,0x3a840e,{DOUBLEWITHTWODWORDINTREE(0x13800000,0x00000000)}}, {VT_exponent,22,0x3a840f,{DOUBLEWITHTWODWORDINTREE(0x13900000,0x00000000)}}, {VT_exponent,22,0x3a8410,{DOUBLEWITHTWODWORDINTREE(0x13a00000,0x00000000)}}, {VT_exponent,22,0x3a8411,{DOUBLEWITHTWODWORDINTREE(0x13b00000,0x00000000)}}, {VT_exponent,22,0x3a8412,{DOUBLEWITHTWODWORDINTREE(0x13c00000,0x00000000)}}, {VT_exponent,22,0x3a8413,{DOUBLEWITHTWODWORDINTREE(0x13d00000,0x00000000)}}, {VT_exponent,22,0x3a8414,{DOUBLEWITHTWODWORDINTREE(0x13e00000,0x00000000)}}, {VT_exponent,22,0x3a8415,{DOUBLEWITHTWODWORDINTREE(0x13f00000,0x00000000)}}, {VT_exponent,22,0x3a8416,{DOUBLEWITHTWODWORDINTREE(0x14000000,0x00000000)}}, {VT_exponent,22,0x3a8417,{DOUBLEWITHTWODWORDINTREE(0x14100000,0x00000000)}}, {VT_exponent,22,0x3a8418,{DOUBLEWITHTWODWORDINTREE(0x14200000,0x00000000)}}, {VT_exponent,22,0x3a8419,{DOUBLEWITHTWODWORDINTREE(0x14300000,0x00000000)}}, {VT_exponent,22,0x3a841a,{DOUBLEWITHTWODWORDINTREE(0x14400000,0x00000000)}}, {VT_exponent,22,0x3a841b,{DOUBLEWITHTWODWORDINTREE(0x14500000,0x00000000)}}, {VT_exponent,22,0x3a841c,{DOUBLEWITHTWODWORDINTREE(0x14600000,0x00000000)}}, {VT_exponent,22,0x3a841d,{DOUBLEWITHTWODWORDINTREE(0x14700000,0x00000000)}}, {VT_exponent,22,0x3a841e,{DOUBLEWITHTWODWORDINTREE(0x14800000,0x00000000)}}, {VT_exponent,22,0x3a841f,{DOUBLEWITHTWODWORDINTREE(0x14900000,0x00000000)}}, {VT_exponent,22,0x3a8420,{DOUBLEWITHTWODWORDINTREE(0x14a00000,0x00000000)}}, {VT_exponent,22,0x3a8421,{DOUBLEWITHTWODWORDINTREE(0x14b00000,0x00000000)}}, {VT_exponent,22,0x3a8422,{DOUBLEWITHTWODWORDINTREE(0x14c00000,0x00000000)}}, {VT_exponent,22,0x3a8423,{DOUBLEWITHTWODWORDINTREE(0x14d00000,0x00000000)}}, {VT_exponent,22,0x3a8424,{DOUBLEWITHTWODWORDINTREE(0x14e00000,0x00000000)}}, {VT_exponent,22,0x3a8425,{DOUBLEWITHTWODWORDINTREE(0x14f00000,0x00000000)}}, {VT_exponent,22,0x3a8426,{DOUBLEWITHTWODWORDINTREE(0x15000000,0x00000000)}}, {VT_exponent,22,0x3a8427,{DOUBLEWITHTWODWORDINTREE(0x15100000,0x00000000)}}, {VT_exponent,22,0x3a8428,{DOUBLEWITHTWODWORDINTREE(0x15200000,0x00000000)}}, {VT_exponent,22,0x3a8429,{DOUBLEWITHTWODWORDINTREE(0x15300000,0x00000000)}}, {VT_exponent,22,0x3a842a,{DOUBLEWITHTWODWORDINTREE(0x15400000,0x00000000)}}, {VT_exponent,22,0x3a842b,{DOUBLEWITHTWODWORDINTREE(0x15500000,0x00000000)}}, {VT_exponent,22,0x3a842c,{DOUBLEWITHTWODWORDINTREE(0x15600000,0x00000000)}}, {VT_exponent,22,0x3a842d,{DOUBLEWITHTWODWORDINTREE(0x15700000,0x00000000)}}, {VT_exponent,22,0x3a842e,{DOUBLEWITHTWODWORDINTREE(0x15800000,0x00000000)}}, {VT_exponent,22,0x3a842f,{DOUBLEWITHTWODWORDINTREE(0x15900000,0x00000000)}}, {VT_exponent,22,0x3a8430,{DOUBLEWITHTWODWORDINTREE(0x15a00000,0x00000000)}}, {VT_exponent,22,0x3a8431,{DOUBLEWITHTWODWORDINTREE(0x15b00000,0x00000000)}}, {VT_exponent,22,0x3a8432,{DOUBLEWITHTWODWORDINTREE(0x15c00000,0x00000000)}}, {VT_exponent,22,0x3a8433,{DOUBLEWITHTWODWORDINTREE(0x15d00000,0x00000000)}}, {VT_exponent,22,0x3a8434,{DOUBLEWITHTWODWORDINTREE(0x15e00000,0x00000000)}}, {VT_exponent,22,0x3a8435,{DOUBLEWITHTWODWORDINTREE(0x15f00000,0x00000000)}}, {VT_exponent,22,0x3a8436,{DOUBLEWITHTWODWORDINTREE(0x16000000,0x00000000)}}, {VT_exponent,22,0x3a8437,{DOUBLEWITHTWODWORDINTREE(0x16100000,0x00000000)}}, {VT_exponent,22,0x3a8438,{DOUBLEWITHTWODWORDINTREE(0x16200000,0x00000000)}}, {VT_exponent,22,0x3a8439,{DOUBLEWITHTWODWORDINTREE(0x16300000,0x00000000)}}, {VT_exponent,22,0x3a843a,{DOUBLEWITHTWODWORDINTREE(0x16400000,0x00000000)}}, {VT_exponent,22,0x3a843b,{DOUBLEWITHTWODWORDINTREE(0x16500000,0x00000000)}}, {VT_exponent,22,0x3a843c,{DOUBLEWITHTWODWORDINTREE(0x16600000,0x00000000)}}, {VT_exponent,22,0x3a843d,{DOUBLEWITHTWODWORDINTREE(0x16700000,0x00000000)}}, {VT_exponent,22,0x3a843e,{DOUBLEWITHTWODWORDINTREE(0x16800000,0x00000000)}}, {VT_exponent,22,0x3a843f,{DOUBLEWITHTWODWORDINTREE(0x16900000,0x00000000)}}, {VT_exponent,22,0x3a8440,{DOUBLEWITHTWODWORDINTREE(0x16a00000,0x00000000)}}, {VT_exponent,22,0x3a8441,{DOUBLEWITHTWODWORDINTREE(0x16b00000,0x00000000)}}, {VT_exponent,22,0x3a8442,{DOUBLEWITHTWODWORDINTREE(0x16c00000,0x00000000)}}, {VT_exponent,22,0x3a8443,{DOUBLEWITHTWODWORDINTREE(0x16d00000,0x00000000)}}, {VT_exponent,22,0x3a8444,{DOUBLEWITHTWODWORDINTREE(0x16e00000,0x00000000)}}, {VT_exponent,22,0x3a8445,{DOUBLEWITHTWODWORDINTREE(0x16f00000,0x00000000)}}, {VT_exponent,22,0x3a8446,{DOUBLEWITHTWODWORDINTREE(0x17000000,0x00000000)}}, {VT_exponent,22,0x3a8447,{DOUBLEWITHTWODWORDINTREE(0x17100000,0x00000000)}}, {VT_exponent,22,0x3a8448,{DOUBLEWITHTWODWORDINTREE(0x17200000,0x00000000)}}, {VT_exponent,22,0x3a8449,{DOUBLEWITHTWODWORDINTREE(0x17300000,0x00000000)}}, {VT_exponent,22,0x3a844a,{DOUBLEWITHTWODWORDINTREE(0x17400000,0x00000000)}}, {VT_exponent,22,0x3a844b,{DOUBLEWITHTWODWORDINTREE(0x17500000,0x00000000)}}, {VT_exponent,22,0x3a844c,{DOUBLEWITHTWODWORDINTREE(0x17600000,0x00000000)}}, {VT_exponent,22,0x3a844d,{DOUBLEWITHTWODWORDINTREE(0x17700000,0x00000000)}}, {VT_exponent,22,0x3a844e,{DOUBLEWITHTWODWORDINTREE(0x17800000,0x00000000)}}, {VT_exponent,22,0x3a844f,{DOUBLEWITHTWODWORDINTREE(0x17900000,0x00000000)}}, {VT_exponent,22,0x3a8450,{DOUBLEWITHTWODWORDINTREE(0x17a00000,0x00000000)}}, {VT_exponent,22,0x3a8451,{DOUBLEWITHTWODWORDINTREE(0x17b00000,0x00000000)}}, {VT_exponent,22,0x3a8452,{DOUBLEWITHTWODWORDINTREE(0x17c00000,0x00000000)}}, {VT_exponent,22,0x3a8453,{DOUBLEWITHTWODWORDINTREE(0x17d00000,0x00000000)}}, {VT_exponent,22,0x3a8454,{DOUBLEWITHTWODWORDINTREE(0x17e00000,0x00000000)}}, {VT_exponent,22,0x3a8455,{DOUBLEWITHTWODWORDINTREE(0x17f00000,0x00000000)}}, {VT_exponent,22,0x3a8456,{DOUBLEWITHTWODWORDINTREE(0x18000000,0x00000000)}}, {VT_exponent,22,0x3a8457,{DOUBLEWITHTWODWORDINTREE(0x18100000,0x00000000)}}, {VT_exponent,22,0x3a8458,{DOUBLEWITHTWODWORDINTREE(0x18200000,0x00000000)}}, {VT_exponent,22,0x3a8459,{DOUBLEWITHTWODWORDINTREE(0x18300000,0x00000000)}}, {VT_exponent,22,0x3a845a,{DOUBLEWITHTWODWORDINTREE(0x18400000,0x00000000)}}, {VT_exponent,22,0x3a845b,{DOUBLEWITHTWODWORDINTREE(0x18500000,0x00000000)}}, {VT_exponent,22,0x3a845c,{DOUBLEWITHTWODWORDINTREE(0x18600000,0x00000000)}}, {VT_exponent,22,0x3a845d,{DOUBLEWITHTWODWORDINTREE(0x18700000,0x00000000)}}, {VT_exponent,22,0x3a845e,{DOUBLEWITHTWODWORDINTREE(0x18800000,0x00000000)}}, {VT_exponent,22,0x3a845f,{DOUBLEWITHTWODWORDINTREE(0x18900000,0x00000000)}}, {VT_exponent,22,0x3a8460,{DOUBLEWITHTWODWORDINTREE(0x18a00000,0x00000000)}}, {VT_exponent,22,0x3a8461,{DOUBLEWITHTWODWORDINTREE(0x18b00000,0x00000000)}}, {VT_exponent,22,0x3a8462,{DOUBLEWITHTWODWORDINTREE(0x18c00000,0x00000000)}}, {VT_exponent,22,0x3a8463,{DOUBLEWITHTWODWORDINTREE(0x18d00000,0x00000000)}}, {VT_exponent,22,0x3a8464,{DOUBLEWITHTWODWORDINTREE(0x18e00000,0x00000000)}}, {VT_exponent,22,0x3a8465,{DOUBLEWITHTWODWORDINTREE(0x18f00000,0x00000000)}}, {VT_exponent,22,0x3a8466,{DOUBLEWITHTWODWORDINTREE(0x19000000,0x00000000)}}, {VT_exponent,22,0x3a8467,{DOUBLEWITHTWODWORDINTREE(0x19100000,0x00000000)}}, {VT_exponent,22,0x3a8468,{DOUBLEWITHTWODWORDINTREE(0x19200000,0x00000000)}}, {VT_exponent,22,0x3a8469,{DOUBLEWITHTWODWORDINTREE(0x19300000,0x00000000)}}, {VT_exponent,22,0x3a846a,{DOUBLEWITHTWODWORDINTREE(0x19400000,0x00000000)}}, {VT_exponent,22,0x3a846b,{DOUBLEWITHTWODWORDINTREE(0x19500000,0x00000000)}}, {VT_exponent,22,0x3a846c,{DOUBLEWITHTWODWORDINTREE(0x19600000,0x00000000)}}, {VT_exponent,22,0x3a846d,{DOUBLEWITHTWODWORDINTREE(0x19700000,0x00000000)}}, {VT_exponent,22,0x3a846e,{DOUBLEWITHTWODWORDINTREE(0x19800000,0x00000000)}}, {VT_exponent,22,0x3a846f,{DOUBLEWITHTWODWORDINTREE(0x19900000,0x00000000)}}, {VT_exponent,22,0x3a8470,{DOUBLEWITHTWODWORDINTREE(0x19a00000,0x00000000)}}, {VT_exponent,22,0x3a8471,{DOUBLEWITHTWODWORDINTREE(0x19b00000,0x00000000)}}, {VT_exponent,22,0x3a8472,{DOUBLEWITHTWODWORDINTREE(0x19c00000,0x00000000)}}, {VT_exponent,22,0x3a8473,{DOUBLEWITHTWODWORDINTREE(0x19d00000,0x00000000)}}, {VT_exponent,22,0x3a8474,{DOUBLEWITHTWODWORDINTREE(0x19e00000,0x00000000)}}, {VT_exponent,22,0x3a8475,{DOUBLEWITHTWODWORDINTREE(0x19f00000,0x00000000)}}, {VT_exponent,22,0x3a8476,{DOUBLEWITHTWODWORDINTREE(0x1a000000,0x00000000)}}, {VT_exponent,22,0x3a8477,{DOUBLEWITHTWODWORDINTREE(0x1a100000,0x00000000)}}, {VT_exponent,22,0x3a8478,{DOUBLEWITHTWODWORDINTREE(0x1a200000,0x00000000)}}, {VT_exponent,22,0x3a8479,{DOUBLEWITHTWODWORDINTREE(0x1a300000,0x00000000)}}, {VT_exponent,22,0x3a847a,{DOUBLEWITHTWODWORDINTREE(0x1a400000,0x00000000)}}, {VT_exponent,22,0x3a847b,{DOUBLEWITHTWODWORDINTREE(0x1a500000,0x00000000)}}, {VT_exponent,22,0x3a847c,{DOUBLEWITHTWODWORDINTREE(0x1a600000,0x00000000)}}, {VT_exponent,22,0x3a847d,{DOUBLEWITHTWODWORDINTREE(0x1a700000,0x00000000)}}, {VT_exponent,22,0x3a847e,{DOUBLEWITHTWODWORDINTREE(0x1a800000,0x00000000)}}, {VT_exponent,22,0x3a847f,{DOUBLEWITHTWODWORDINTREE(0x1a900000,0x00000000)}}, {VT_exponent,22,0x3a8480,{DOUBLEWITHTWODWORDINTREE(0x1aa00000,0x00000000)}}, {VT_exponent,22,0x3a8481,{DOUBLEWITHTWODWORDINTREE(0x1ab00000,0x00000000)}}, {VT_exponent,22,0x3a8482,{DOUBLEWITHTWODWORDINTREE(0x1ac00000,0x00000000)}}, {VT_exponent,22,0x3a8483,{DOUBLEWITHTWODWORDINTREE(0x1ad00000,0x00000000)}}, {VT_exponent,22,0x3a8484,{DOUBLEWITHTWODWORDINTREE(0x1ae00000,0x00000000)}}, {VT_exponent,22,0x3a8485,{DOUBLEWITHTWODWORDINTREE(0x1af00000,0x00000000)}}, {VT_exponent,22,0x3a8486,{DOUBLEWITHTWODWORDINTREE(0x1b000000,0x00000000)}}, {VT_exponent,22,0x3a8487,{DOUBLEWITHTWODWORDINTREE(0x1b100000,0x00000000)}}, {VT_exponent,22,0x3a8488,{DOUBLEWITHTWODWORDINTREE(0x1b200000,0x00000000)}}, {VT_exponent,22,0x3a8489,{DOUBLEWITHTWODWORDINTREE(0x1b300000,0x00000000)}}, {VT_exponent,22,0x3a848a,{DOUBLEWITHTWODWORDINTREE(0x1b400000,0x00000000)}}, {VT_exponent,22,0x3a848b,{DOUBLEWITHTWODWORDINTREE(0x1b500000,0x00000000)}}, {VT_exponent,22,0x3a848c,{DOUBLEWITHTWODWORDINTREE(0x1b600000,0x00000000)}}, {VT_exponent,22,0x3a848d,{DOUBLEWITHTWODWORDINTREE(0x1b700000,0x00000000)}}, {VT_exponent,22,0x3a848e,{DOUBLEWITHTWODWORDINTREE(0x1b800000,0x00000000)}}, {VT_exponent,22,0x3a848f,{DOUBLEWITHTWODWORDINTREE(0x1b900000,0x00000000)}}, {VT_exponent,22,0x3a8490,{DOUBLEWITHTWODWORDINTREE(0x1ba00000,0x00000000)}}, {VT_exponent,22,0x3a8491,{DOUBLEWITHTWODWORDINTREE(0x1bb00000,0x00000000)}}, {VT_exponent,22,0x3a8492,{DOUBLEWITHTWODWORDINTREE(0x1bc00000,0x00000000)}}, {VT_exponent,22,0x3a8493,{DOUBLEWITHTWODWORDINTREE(0x1bd00000,0x00000000)}}, {VT_exponent,22,0x3a8494,{DOUBLEWITHTWODWORDINTREE(0x1be00000,0x00000000)}}, {VT_exponent,22,0x3a8495,{DOUBLEWITHTWODWORDINTREE(0x1bf00000,0x00000000)}}, {VT_exponent,22,0x3a8496,{DOUBLEWITHTWODWORDINTREE(0x1c000000,0x00000000)}}, {VT_exponent,22,0x3a8497,{DOUBLEWITHTWODWORDINTREE(0x1c100000,0x00000000)}}, {VT_exponent,22,0x3a8498,{DOUBLEWITHTWODWORDINTREE(0x1c200000,0x00000000)}}, {VT_exponent,22,0x3a8499,{DOUBLEWITHTWODWORDINTREE(0x1c300000,0x00000000)}}, {VT_exponent,22,0x3a849a,{DOUBLEWITHTWODWORDINTREE(0x1c400000,0x00000000)}}, {VT_exponent,22,0x3a849b,{DOUBLEWITHTWODWORDINTREE(0x1c500000,0x00000000)}}, {VT_exponent,22,0x3a849c,{DOUBLEWITHTWODWORDINTREE(0x1c600000,0x00000000)}}, {VT_exponent,22,0x3a849d,{DOUBLEWITHTWODWORDINTREE(0x1c700000,0x00000000)}}, {VT_exponent,22,0x3a849e,{DOUBLEWITHTWODWORDINTREE(0x1c800000,0x00000000)}}, {VT_exponent,22,0x3a849f,{DOUBLEWITHTWODWORDINTREE(0x1c900000,0x00000000)}}, {VT_exponent,22,0x3a84a0,{DOUBLEWITHTWODWORDINTREE(0x1ca00000,0x00000000)}}, {VT_exponent,22,0x3a84a1,{DOUBLEWITHTWODWORDINTREE(0x1cb00000,0x00000000)}}, {VT_exponent,22,0x3a84a2,{DOUBLEWITHTWODWORDINTREE(0x1cc00000,0x00000000)}}, {VT_exponent,22,0x3a84a3,{DOUBLEWITHTWODWORDINTREE(0x1cd00000,0x00000000)}}, {VT_exponent,22,0x3a84a4,{DOUBLEWITHTWODWORDINTREE(0x1ce00000,0x00000000)}}, {VT_exponent,22,0x3a84a5,{DOUBLEWITHTWODWORDINTREE(0x1cf00000,0x00000000)}}, {VT_exponent,22,0x3a84a6,{DOUBLEWITHTWODWORDINTREE(0x1d000000,0x00000000)}}, {VT_exponent,22,0x3a84a7,{DOUBLEWITHTWODWORDINTREE(0x1d100000,0x00000000)}}, {VT_exponent,22,0x3a84a8,{DOUBLEWITHTWODWORDINTREE(0x1d200000,0x00000000)}}, {VT_exponent,22,0x3a84a9,{DOUBLEWITHTWODWORDINTREE(0x1d300000,0x00000000)}}, {VT_exponent,22,0x3a84aa,{DOUBLEWITHTWODWORDINTREE(0x1d400000,0x00000000)}}, {VT_exponent,22,0x3a84ab,{DOUBLEWITHTWODWORDINTREE(0x1d500000,0x00000000)}}, {VT_exponent,22,0x3a84ac,{DOUBLEWITHTWODWORDINTREE(0x1d600000,0x00000000)}}, {VT_exponent,22,0x3a84ad,{DOUBLEWITHTWODWORDINTREE(0x1d700000,0x00000000)}}, {VT_exponent,22,0x3a84ae,{DOUBLEWITHTWODWORDINTREE(0x1d800000,0x00000000)}}, {VT_exponent,22,0x3a84af,{DOUBLEWITHTWODWORDINTREE(0x1d900000,0x00000000)}}, {VT_exponent,22,0x3a84b0,{DOUBLEWITHTWODWORDINTREE(0x1da00000,0x00000000)}}, {VT_exponent,22,0x3a84b1,{DOUBLEWITHTWODWORDINTREE(0x1db00000,0x00000000)}}, {VT_exponent,22,0x3a84b2,{DOUBLEWITHTWODWORDINTREE(0x1dc00000,0x00000000)}}, {VT_exponent,22,0x3a84b3,{DOUBLEWITHTWODWORDINTREE(0x1dd00000,0x00000000)}}, {VT_exponent,22,0x3a84b4,{DOUBLEWITHTWODWORDINTREE(0x1de00000,0x00000000)}}, {VT_exponent,22,0x3a84b5,{DOUBLEWITHTWODWORDINTREE(0x1df00000,0x00000000)}}, {VT_exponent,22,0x3a84b6,{DOUBLEWITHTWODWORDINTREE(0x1e000000,0x00000000)}}, {VT_exponent,22,0x3a84b7,{DOUBLEWITHTWODWORDINTREE(0x1e100000,0x00000000)}}, {VT_exponent,22,0x3a84b8,{DOUBLEWITHTWODWORDINTREE(0x1e200000,0x00000000)}}, {VT_exponent,22,0x3a84b9,{DOUBLEWITHTWODWORDINTREE(0x1e300000,0x00000000)}}, {VT_exponent,22,0x3a84ba,{DOUBLEWITHTWODWORDINTREE(0x1e400000,0x00000000)}}, {VT_exponent,22,0x3a84bb,{DOUBLEWITHTWODWORDINTREE(0x1e500000,0x00000000)}}, {VT_exponent,22,0x3a84bc,{DOUBLEWITHTWODWORDINTREE(0x1e600000,0x00000000)}}, {VT_exponent,22,0x3a84bd,{DOUBLEWITHTWODWORDINTREE(0x1e700000,0x00000000)}}, {VT_exponent,22,0x3a84be,{DOUBLEWITHTWODWORDINTREE(0x1e800000,0x00000000)}}, {VT_exponent,22,0x3a84bf,{DOUBLEWITHTWODWORDINTREE(0x1e900000,0x00000000)}}, {VT_exponent,22,0x3a84c0,{DOUBLEWITHTWODWORDINTREE(0x1ea00000,0x00000000)}}, {VT_exponent,22,0x3a84c1,{DOUBLEWITHTWODWORDINTREE(0x1eb00000,0x00000000)}}, {VT_exponent,22,0x3a84c2,{DOUBLEWITHTWODWORDINTREE(0x1ec00000,0x00000000)}}, {VT_exponent,22,0x3a84c3,{DOUBLEWITHTWODWORDINTREE(0x1ed00000,0x00000000)}}, {VT_exponent,22,0x3a84c4,{DOUBLEWITHTWODWORDINTREE(0x1ee00000,0x00000000)}}, {VT_exponent,22,0x3a84c5,{DOUBLEWITHTWODWORDINTREE(0x1ef00000,0x00000000)}}, {VT_exponent,22,0x3a84c6,{DOUBLEWITHTWODWORDINTREE(0x1f000000,0x00000000)}}, {VT_exponent,22,0x3a84c7,{DOUBLEWITHTWODWORDINTREE(0x1f100000,0x00000000)}}, {VT_exponent,22,0x3a84c8,{DOUBLEWITHTWODWORDINTREE(0x1f200000,0x00000000)}}, {VT_exponent,22,0x3a84c9,{DOUBLEWITHTWODWORDINTREE(0x1f300000,0x00000000)}}, {VT_exponent,22,0x3a84ca,{DOUBLEWITHTWODWORDINTREE(0x1f400000,0x00000000)}}, {VT_exponent,22,0x3a84cb,{DOUBLEWITHTWODWORDINTREE(0x1f500000,0x00000000)}}, {VT_exponent,22,0x3a84cc,{DOUBLEWITHTWODWORDINTREE(0x1f600000,0x00000000)}}, {VT_exponent,22,0x3a84cd,{DOUBLEWITHTWODWORDINTREE(0x1f700000,0x00000000)}}, {VT_exponent,22,0x3a84ce,{DOUBLEWITHTWODWORDINTREE(0x1f800000,0x00000000)}}, {VT_exponent,22,0x3a84cf,{DOUBLEWITHTWODWORDINTREE(0x1f900000,0x00000000)}}, {VT_exponent,22,0x3a84d0,{DOUBLEWITHTWODWORDINTREE(0x1fa00000,0x00000000)}}, {VT_exponent,22,0x3a84d1,{DOUBLEWITHTWODWORDINTREE(0x1fb00000,0x00000000)}}, {VT_exponent,22,0x3a84d2,{DOUBLEWITHTWODWORDINTREE(0x1fc00000,0x00000000)}}, {VT_exponent,22,0x3a84d3,{DOUBLEWITHTWODWORDINTREE(0x1fd00000,0x00000000)}}, {VT_exponent,22,0x3a84d4,{DOUBLEWITHTWODWORDINTREE(0x1fe00000,0x00000000)}}, {VT_exponent,22,0x3a84d5,{DOUBLEWITHTWODWORDINTREE(0x1ff00000,0x00000000)}}, {VT_exponent,22,0x3a84d6,{DOUBLEWITHTWODWORDINTREE(0x20000000,0x00000000)}}, {VT_exponent,22,0x3a84d7,{DOUBLEWITHTWODWORDINTREE(0x20100000,0x00000000)}}, {VT_exponent,22,0x3a84d8,{DOUBLEWITHTWODWORDINTREE(0x20200000,0x00000000)}}, {VT_exponent,22,0x3a84d9,{DOUBLEWITHTWODWORDINTREE(0x20300000,0x00000000)}}, {VT_exponent,22,0x3a84da,{DOUBLEWITHTWODWORDINTREE(0x20400000,0x00000000)}}, {VT_exponent,22,0x3a84db,{DOUBLEWITHTWODWORDINTREE(0x20500000,0x00000000)}}, {VT_exponent,22,0x3a84dc,{DOUBLEWITHTWODWORDINTREE(0x20600000,0x00000000)}}, {VT_exponent,22,0x3a84dd,{DOUBLEWITHTWODWORDINTREE(0x20700000,0x00000000)}}, {VT_exponent,22,0x3a84de,{DOUBLEWITHTWODWORDINTREE(0x20800000,0x00000000)}}, {VT_exponent,22,0x3a84df,{DOUBLEWITHTWODWORDINTREE(0x20900000,0x00000000)}}, {VT_exponent,22,0x3a84e0,{DOUBLEWITHTWODWORDINTREE(0x20a00000,0x00000000)}}, {VT_exponent,22,0x3a84e1,{DOUBLEWITHTWODWORDINTREE(0x20b00000,0x00000000)}}, {VT_exponent,22,0x3a84e2,{DOUBLEWITHTWODWORDINTREE(0x20c00000,0x00000000)}}, {VT_exponent,22,0x3a84e3,{DOUBLEWITHTWODWORDINTREE(0x20d00000,0x00000000)}}, {VT_exponent,22,0x3a84e4,{DOUBLEWITHTWODWORDINTREE(0x20e00000,0x00000000)}}, {VT_exponent,22,0x3a84e5,{DOUBLEWITHTWODWORDINTREE(0x20f00000,0x00000000)}}, {VT_exponent,22,0x3a84e6,{DOUBLEWITHTWODWORDINTREE(0x21000000,0x00000000)}}, {VT_exponent,22,0x3a84e7,{DOUBLEWITHTWODWORDINTREE(0x21100000,0x00000000)}}, {VT_exponent,22,0x3a84e8,{DOUBLEWITHTWODWORDINTREE(0x21200000,0x00000000)}}, {VT_exponent,22,0x3a84e9,{DOUBLEWITHTWODWORDINTREE(0x21300000,0x00000000)}}, {VT_exponent,22,0x3a84ea,{DOUBLEWITHTWODWORDINTREE(0x21400000,0x00000000)}}, {VT_exponent,22,0x3a84eb,{DOUBLEWITHTWODWORDINTREE(0x21500000,0x00000000)}}, {VT_exponent,22,0x3a84ec,{DOUBLEWITHTWODWORDINTREE(0x21600000,0x00000000)}}, {VT_exponent,22,0x3a84ed,{DOUBLEWITHTWODWORDINTREE(0x21700000,0x00000000)}}, {VT_exponent,22,0x3a84ee,{DOUBLEWITHTWODWORDINTREE(0x21800000,0x00000000)}}, {VT_exponent,22,0x3a84ef,{DOUBLEWITHTWODWORDINTREE(0x21900000,0x00000000)}}, {VT_exponent,22,0x3a84f0,{DOUBLEWITHTWODWORDINTREE(0x21a00000,0x00000000)}}, {VT_exponent,22,0x3a84f1,{DOUBLEWITHTWODWORDINTREE(0x21b00000,0x00000000)}}, {VT_exponent,22,0x3a84f2,{DOUBLEWITHTWODWORDINTREE(0x21c00000,0x00000000)}}, {VT_exponent,22,0x3a84f3,{DOUBLEWITHTWODWORDINTREE(0x21d00000,0x00000000)}}, {VT_exponent,22,0x3a84f4,{DOUBLEWITHTWODWORDINTREE(0x21e00000,0x00000000)}}, {VT_exponent,22,0x3a84f5,{DOUBLEWITHTWODWORDINTREE(0x21f00000,0x00000000)}}, {VT_exponent,22,0x3a84f6,{DOUBLEWITHTWODWORDINTREE(0x22000000,0x00000000)}}, {VT_exponent,22,0x3a84f7,{DOUBLEWITHTWODWORDINTREE(0x22100000,0x00000000)}}, {VT_exponent,22,0x3a84f8,{DOUBLEWITHTWODWORDINTREE(0x22200000,0x00000000)}}, {VT_exponent,22,0x3a84f9,{DOUBLEWITHTWODWORDINTREE(0x22300000,0x00000000)}}, {VT_exponent,22,0x3a84fa,{DOUBLEWITHTWODWORDINTREE(0x22400000,0x00000000)}}, {VT_exponent,22,0x3a84fb,{DOUBLEWITHTWODWORDINTREE(0x22500000,0x00000000)}}, {VT_exponent,22,0x3a84fc,{DOUBLEWITHTWODWORDINTREE(0x22600000,0x00000000)}}, {VT_exponent,22,0x3a84fd,{DOUBLEWITHTWODWORDINTREE(0x22700000,0x00000000)}}, {VT_exponent,22,0x3a84fe,{DOUBLEWITHTWODWORDINTREE(0x22800000,0x00000000)}}, {VT_exponent,22,0x3a84ff,{DOUBLEWITHTWODWORDINTREE(0x22900000,0x00000000)}}, {VT_exponent,22,0x3a8500,{DOUBLEWITHTWODWORDINTREE(0x22a00000,0x00000000)}}, {VT_exponent,22,0x3a8501,{DOUBLEWITHTWODWORDINTREE(0x22b00000,0x00000000)}}, {VT_exponent,22,0x3a8502,{DOUBLEWITHTWODWORDINTREE(0x22c00000,0x00000000)}}, {VT_exponent,22,0x3a8503,{DOUBLEWITHTWODWORDINTREE(0x22d00000,0x00000000)}}, {VT_exponent,22,0x3a8504,{DOUBLEWITHTWODWORDINTREE(0x22e00000,0x00000000)}}, {VT_exponent,22,0x3a8505,{DOUBLEWITHTWODWORDINTREE(0x22f00000,0x00000000)}}, {VT_exponent,22,0x3a8506,{DOUBLEWITHTWODWORDINTREE(0x23000000,0x00000000)}}, {VT_exponent,22,0x3a8507,{DOUBLEWITHTWODWORDINTREE(0x23100000,0x00000000)}}, {VT_exponent,22,0x3a8508,{DOUBLEWITHTWODWORDINTREE(0x23200000,0x00000000)}}, {VT_exponent,22,0x3a8509,{DOUBLEWITHTWODWORDINTREE(0x23300000,0x00000000)}}, {VT_exponent,22,0x3a850a,{DOUBLEWITHTWODWORDINTREE(0x23400000,0x00000000)}}, {VT_exponent,22,0x3a850b,{DOUBLEWITHTWODWORDINTREE(0x23500000,0x00000000)}}, {VT_exponent,22,0x3a850c,{DOUBLEWITHTWODWORDINTREE(0x23600000,0x00000000)}}, {VT_exponent,22,0x3a850d,{DOUBLEWITHTWODWORDINTREE(0x23700000,0x00000000)}}, {VT_exponent,22,0x3a850e,{DOUBLEWITHTWODWORDINTREE(0x23800000,0x00000000)}}, {VT_exponent,22,0x3a850f,{DOUBLEWITHTWODWORDINTREE(0x23900000,0x00000000)}}, {VT_exponent,22,0x3a8510,{DOUBLEWITHTWODWORDINTREE(0x23a00000,0x00000000)}}, {VT_exponent,22,0x3a8511,{DOUBLEWITHTWODWORDINTREE(0x23b00000,0x00000000)}}, {VT_exponent,22,0x3a8512,{DOUBLEWITHTWODWORDINTREE(0x23c00000,0x00000000)}}, {VT_exponent,22,0x3a8513,{DOUBLEWITHTWODWORDINTREE(0x23d00000,0x00000000)}}, {VT_exponent,22,0x3a8514,{DOUBLEWITHTWODWORDINTREE(0x23e00000,0x00000000)}}, {VT_exponent,22,0x3a8515,{DOUBLEWITHTWODWORDINTREE(0x23f00000,0x00000000)}}, {VT_exponent,22,0x3a8516,{DOUBLEWITHTWODWORDINTREE(0x24000000,0x00000000)}}, {VT_exponent,22,0x3a8517,{DOUBLEWITHTWODWORDINTREE(0x24100000,0x00000000)}}, {VT_exponent,22,0x3a8518,{DOUBLEWITHTWODWORDINTREE(0x24200000,0x00000000)}}, {VT_exponent,22,0x3a8519,{DOUBLEWITHTWODWORDINTREE(0x24300000,0x00000000)}}, {VT_exponent,22,0x3a851a,{DOUBLEWITHTWODWORDINTREE(0x24400000,0x00000000)}}, {VT_exponent,22,0x3a851b,{DOUBLEWITHTWODWORDINTREE(0x24500000,0x00000000)}}, {VT_exponent,22,0x3a851c,{DOUBLEWITHTWODWORDINTREE(0x24600000,0x00000000)}}, {VT_exponent,22,0x3a851d,{DOUBLEWITHTWODWORDINTREE(0x24700000,0x00000000)}}, {VT_exponent,22,0x3a851e,{DOUBLEWITHTWODWORDINTREE(0x24800000,0x00000000)}}, {VT_exponent,22,0x3a851f,{DOUBLEWITHTWODWORDINTREE(0x24900000,0x00000000)}}, {VT_exponent,22,0x3a8520,{DOUBLEWITHTWODWORDINTREE(0x24a00000,0x00000000)}}, {VT_exponent,22,0x3a8521,{DOUBLEWITHTWODWORDINTREE(0x24b00000,0x00000000)}}, {VT_exponent,22,0x3a8522,{DOUBLEWITHTWODWORDINTREE(0x24c00000,0x00000000)}}, {VT_exponent,22,0x3a8523,{DOUBLEWITHTWODWORDINTREE(0x24d00000,0x00000000)}}, {VT_exponent,22,0x3a8524,{DOUBLEWITHTWODWORDINTREE(0x24e00000,0x00000000)}}, {VT_exponent,22,0x3a8525,{DOUBLEWITHTWODWORDINTREE(0x24f00000,0x00000000)}}, {VT_exponent,22,0x3a8526,{DOUBLEWITHTWODWORDINTREE(0x25000000,0x00000000)}}, {VT_exponent,22,0x3a8527,{DOUBLEWITHTWODWORDINTREE(0x25100000,0x00000000)}}, {VT_exponent,22,0x3a8528,{DOUBLEWITHTWODWORDINTREE(0x25200000,0x00000000)}}, {VT_exponent,22,0x3a8529,{DOUBLEWITHTWODWORDINTREE(0x25300000,0x00000000)}}, {VT_exponent,22,0x3a852a,{DOUBLEWITHTWODWORDINTREE(0x25400000,0x00000000)}}, {VT_exponent,22,0x3a852b,{DOUBLEWITHTWODWORDINTREE(0x25500000,0x00000000)}}, {VT_exponent,22,0x3a852c,{DOUBLEWITHTWODWORDINTREE(0x25600000,0x00000000)}}, {VT_exponent,22,0x3a852d,{DOUBLEWITHTWODWORDINTREE(0x25700000,0x00000000)}}, {VT_exponent,22,0x3a852e,{DOUBLEWITHTWODWORDINTREE(0x25800000,0x00000000)}}, {VT_exponent,22,0x3a852f,{DOUBLEWITHTWODWORDINTREE(0x25900000,0x00000000)}}, {VT_exponent,22,0x3a8530,{DOUBLEWITHTWODWORDINTREE(0x25a00000,0x00000000)}}, {VT_exponent,22,0x3a8531,{DOUBLEWITHTWODWORDINTREE(0x25b00000,0x00000000)}}, {VT_exponent,22,0x3a8532,{DOUBLEWITHTWODWORDINTREE(0x25c00000,0x00000000)}}, {VT_exponent,22,0x3a8533,{DOUBLEWITHTWODWORDINTREE(0x25d00000,0x00000000)}}, {VT_exponent,22,0x3a8534,{DOUBLEWITHTWODWORDINTREE(0x25e00000,0x00000000)}}, {VT_exponent,22,0x3a8535,{DOUBLEWITHTWODWORDINTREE(0x25f00000,0x00000000)}}, {VT_exponent,22,0x3a8536,{DOUBLEWITHTWODWORDINTREE(0x26000000,0x00000000)}}, {VT_exponent,22,0x3a8537,{DOUBLEWITHTWODWORDINTREE(0x26100000,0x00000000)}}, {VT_exponent,22,0x3a8538,{DOUBLEWITHTWODWORDINTREE(0x26200000,0x00000000)}}, {VT_exponent,22,0x3a8539,{DOUBLEWITHTWODWORDINTREE(0x26300000,0x00000000)}}, {VT_exponent,22,0x3a853a,{DOUBLEWITHTWODWORDINTREE(0x26400000,0x00000000)}}, {VT_exponent,22,0x3a853b,{DOUBLEWITHTWODWORDINTREE(0x26500000,0x00000000)}}, {VT_exponent,22,0x3a853c,{DOUBLEWITHTWODWORDINTREE(0x26600000,0x00000000)}}, {VT_exponent,22,0x3a853d,{DOUBLEWITHTWODWORDINTREE(0x26700000,0x00000000)}}, {VT_exponent,22,0x3a853e,{DOUBLEWITHTWODWORDINTREE(0x26800000,0x00000000)}}, {VT_exponent,22,0x3a853f,{DOUBLEWITHTWODWORDINTREE(0x26900000,0x00000000)}}, {VT_exponent,22,0x3a8540,{DOUBLEWITHTWODWORDINTREE(0x26a00000,0x00000000)}}, {VT_exponent,22,0x3a8541,{DOUBLEWITHTWODWORDINTREE(0x26b00000,0x00000000)}}, {VT_exponent,22,0x3a8542,{DOUBLEWITHTWODWORDINTREE(0x26c00000,0x00000000)}}, {VT_exponent,22,0x3a8543,{DOUBLEWITHTWODWORDINTREE(0x26d00000,0x00000000)}}, {VT_exponent,22,0x3a8544,{DOUBLEWITHTWODWORDINTREE(0x26e00000,0x00000000)}}, {VT_exponent,22,0x3a8545,{DOUBLEWITHTWODWORDINTREE(0x26f00000,0x00000000)}}, {VT_exponent,22,0x3a8546,{DOUBLEWITHTWODWORDINTREE(0x27000000,0x00000000)}}, {VT_exponent,22,0x3a8547,{DOUBLEWITHTWODWORDINTREE(0x27100000,0x00000000)}}, {VT_exponent,22,0x3a8548,{DOUBLEWITHTWODWORDINTREE(0x27200000,0x00000000)}}, {VT_exponent,22,0x3a8549,{DOUBLEWITHTWODWORDINTREE(0x27300000,0x00000000)}}, {VT_exponent,22,0x3a854a,{DOUBLEWITHTWODWORDINTREE(0x27400000,0x00000000)}}, {VT_exponent,22,0x3a854b,{DOUBLEWITHTWODWORDINTREE(0x27500000,0x00000000)}}, {VT_exponent,22,0x3a854c,{DOUBLEWITHTWODWORDINTREE(0x27600000,0x00000000)}}, {VT_exponent,22,0x3a854d,{DOUBLEWITHTWODWORDINTREE(0x27700000,0x00000000)}}, {VT_exponent,22,0x3a854e,{DOUBLEWITHTWODWORDINTREE(0x27800000,0x00000000)}}, {VT_exponent,22,0x3a854f,{DOUBLEWITHTWODWORDINTREE(0x27900000,0x00000000)}}, {VT_exponent,22,0x3a8550,{DOUBLEWITHTWODWORDINTREE(0x27a00000,0x00000000)}}, {VT_exponent,22,0x3a8551,{DOUBLEWITHTWODWORDINTREE(0x27b00000,0x00000000)}}, {VT_exponent,22,0x3a8552,{DOUBLEWITHTWODWORDINTREE(0x27c00000,0x00000000)}}, {VT_exponent,22,0x3a8553,{DOUBLEWITHTWODWORDINTREE(0x27d00000,0x00000000)}}, {VT_exponent,22,0x3a8554,{DOUBLEWITHTWODWORDINTREE(0x27e00000,0x00000000)}}, {VT_exponent,22,0x3a8555,{DOUBLEWITHTWODWORDINTREE(0x27f00000,0x00000000)}}, {VT_exponent,22,0x3a8556,{DOUBLEWITHTWODWORDINTREE(0x28000000,0x00000000)}}, {VT_exponent,22,0x3a8557,{DOUBLEWITHTWODWORDINTREE(0x28100000,0x00000000)}}, {VT_exponent,22,0x3a8558,{DOUBLEWITHTWODWORDINTREE(0x28200000,0x00000000)}}, {VT_exponent,22,0x3a8559,{DOUBLEWITHTWODWORDINTREE(0x28300000,0x00000000)}}, {VT_exponent,22,0x3a855a,{DOUBLEWITHTWODWORDINTREE(0x28400000,0x00000000)}}, {VT_exponent,22,0x3a855b,{DOUBLEWITHTWODWORDINTREE(0x28500000,0x00000000)}}, {VT_exponent,22,0x3a855c,{DOUBLEWITHTWODWORDINTREE(0x28600000,0x00000000)}}, {VT_exponent,22,0x3a855d,{DOUBLEWITHTWODWORDINTREE(0x28700000,0x00000000)}}, {VT_exponent,22,0x3a855e,{DOUBLEWITHTWODWORDINTREE(0x28800000,0x00000000)}}, {VT_exponent,22,0x3a855f,{DOUBLEWITHTWODWORDINTREE(0x28900000,0x00000000)}}, {VT_exponent,22,0x3a8560,{DOUBLEWITHTWODWORDINTREE(0x28a00000,0x00000000)}}, {VT_exponent,22,0x3a8561,{DOUBLEWITHTWODWORDINTREE(0x28b00000,0x00000000)}}, {VT_exponent,22,0x3a8562,{DOUBLEWITHTWODWORDINTREE(0x28c00000,0x00000000)}}, {VT_exponent,22,0x3a8563,{DOUBLEWITHTWODWORDINTREE(0x28d00000,0x00000000)}}, {VT_exponent,22,0x3a8564,{DOUBLEWITHTWODWORDINTREE(0x28e00000,0x00000000)}}, {VT_exponent,22,0x3a8565,{DOUBLEWITHTWODWORDINTREE(0x28f00000,0x00000000)}}, {VT_exponent,22,0x3a8566,{DOUBLEWITHTWODWORDINTREE(0x29000000,0x00000000)}}, {VT_exponent,22,0x3a8567,{DOUBLEWITHTWODWORDINTREE(0x29100000,0x00000000)}}, {VT_exponent,22,0x3a8568,{DOUBLEWITHTWODWORDINTREE(0x29200000,0x00000000)}}, {VT_exponent,22,0x3a8569,{DOUBLEWITHTWODWORDINTREE(0x29300000,0x00000000)}}, {VT_exponent,22,0x3a856a,{DOUBLEWITHTWODWORDINTREE(0x29400000,0x00000000)}}, {VT_exponent,22,0x3a856b,{DOUBLEWITHTWODWORDINTREE(0x29500000,0x00000000)}}, {VT_exponent,22,0x3a856c,{DOUBLEWITHTWODWORDINTREE(0x29600000,0x00000000)}}, {VT_exponent,22,0x3a856d,{DOUBLEWITHTWODWORDINTREE(0x29700000,0x00000000)}}, {VT_exponent,22,0x3a856e,{DOUBLEWITHTWODWORDINTREE(0x29800000,0x00000000)}}, {VT_exponent,22,0x3a856f,{DOUBLEWITHTWODWORDINTREE(0x29900000,0x00000000)}}, {VT_exponent,22,0x3a8570,{DOUBLEWITHTWODWORDINTREE(0x29a00000,0x00000000)}}, {VT_exponent,22,0x3a8571,{DOUBLEWITHTWODWORDINTREE(0x29b00000,0x00000000)}}, {VT_exponent,22,0x3a8572,{DOUBLEWITHTWODWORDINTREE(0x29c00000,0x00000000)}}, {VT_exponent,22,0x3a8573,{DOUBLEWITHTWODWORDINTREE(0x29d00000,0x00000000)}}, {VT_exponent,22,0x3a8574,{DOUBLEWITHTWODWORDINTREE(0x29e00000,0x00000000)}}, {VT_exponent,22,0x3a8575,{DOUBLEWITHTWODWORDINTREE(0x29f00000,0x00000000)}}, {VT_exponent,22,0x3a8576,{DOUBLEWITHTWODWORDINTREE(0x2a000000,0x00000000)}}, {VT_exponent,22,0x3a8577,{DOUBLEWITHTWODWORDINTREE(0x2a100000,0x00000000)}}, {VT_exponent,22,0x3a8578,{DOUBLEWITHTWODWORDINTREE(0x2a200000,0x00000000)}}, {VT_exponent,22,0x3a8579,{DOUBLEWITHTWODWORDINTREE(0x2a300000,0x00000000)}}, {VT_exponent,22,0x3a857a,{DOUBLEWITHTWODWORDINTREE(0x2a400000,0x00000000)}}, {VT_exponent,22,0x3a857b,{DOUBLEWITHTWODWORDINTREE(0x2a500000,0x00000000)}}, {VT_exponent,22,0x3a857c,{DOUBLEWITHTWODWORDINTREE(0x2a600000,0x00000000)}}, {VT_exponent,22,0x3a857d,{DOUBLEWITHTWODWORDINTREE(0x2a700000,0x00000000)}}, {VT_exponent,22,0x3a857e,{DOUBLEWITHTWODWORDINTREE(0x2a800000,0x00000000)}}, {VT_exponent,22,0x3a857f,{DOUBLEWITHTWODWORDINTREE(0x2a900000,0x00000000)}}, {VT_exponent,22,0x3a8580,{DOUBLEWITHTWODWORDINTREE(0x2aa00000,0x00000000)}}, {VT_exponent,22,0x3a8581,{DOUBLEWITHTWODWORDINTREE(0x2ab00000,0x00000000)}}, {VT_exponent,22,0x3a8582,{DOUBLEWITHTWODWORDINTREE(0x2ac00000,0x00000000)}}, {VT_exponent,22,0x3a8583,{DOUBLEWITHTWODWORDINTREE(0x2ad00000,0x00000000)}}, {VT_exponent,22,0x3a8584,{DOUBLEWITHTWODWORDINTREE(0x2ae00000,0x00000000)}}, {VT_exponent,22,0x3a8585,{DOUBLEWITHTWODWORDINTREE(0x2af00000,0x00000000)}}, {VT_exponent,22,0x3a8586,{DOUBLEWITHTWODWORDINTREE(0x2b000000,0x00000000)}}, {VT_exponent,22,0x3a8587,{DOUBLEWITHTWODWORDINTREE(0x2b100000,0x00000000)}}, {VT_exponent,22,0x3a8588,{DOUBLEWITHTWODWORDINTREE(0x2b200000,0x00000000)}}, {VT_exponent,22,0x3a8589,{DOUBLEWITHTWODWORDINTREE(0x2b300000,0x00000000)}}, {VT_exponent,22,0x3a858a,{DOUBLEWITHTWODWORDINTREE(0x2b400000,0x00000000)}}, {VT_exponent,22,0x3a858b,{DOUBLEWITHTWODWORDINTREE(0x2b500000,0x00000000)}}, {VT_exponent,22,0x3a858c,{DOUBLEWITHTWODWORDINTREE(0x2b600000,0x00000000)}}, {VT_exponent,22,0x3a858d,{DOUBLEWITHTWODWORDINTREE(0x2b700000,0x00000000)}}, {VT_exponent,22,0x3a858e,{DOUBLEWITHTWODWORDINTREE(0x2b800000,0x00000000)}}, {VT_exponent,22,0x3a858f,{DOUBLEWITHTWODWORDINTREE(0x2b900000,0x00000000)}}, {VT_exponent,22,0x3a8590,{DOUBLEWITHTWODWORDINTREE(0x2ba00000,0x00000000)}}, {VT_exponent,22,0x3a8591,{DOUBLEWITHTWODWORDINTREE(0x2bb00000,0x00000000)}}, {VT_exponent,22,0x3a8592,{DOUBLEWITHTWODWORDINTREE(0x2bc00000,0x00000000)}}, {VT_exponent,22,0x3a8593,{DOUBLEWITHTWODWORDINTREE(0x2bd00000,0x00000000)}}, {VT_exponent,22,0x3a8594,{DOUBLEWITHTWODWORDINTREE(0x2be00000,0x00000000)}}, {VT_exponent,22,0x3a8595,{DOUBLEWITHTWODWORDINTREE(0x2bf00000,0x00000000)}}, {VT_exponent,22,0x3a8596,{DOUBLEWITHTWODWORDINTREE(0x2c000000,0x00000000)}}, {VT_exponent,22,0x3a8597,{DOUBLEWITHTWODWORDINTREE(0x2c100000,0x00000000)}}, {VT_exponent,22,0x3a8598,{DOUBLEWITHTWODWORDINTREE(0x2c200000,0x00000000)}}, {VT_exponent,22,0x3a8599,{DOUBLEWITHTWODWORDINTREE(0x2c300000,0x00000000)}}, {VT_exponent,22,0x3a859a,{DOUBLEWITHTWODWORDINTREE(0x2c400000,0x00000000)}}, {VT_exponent,22,0x3a859b,{DOUBLEWITHTWODWORDINTREE(0x2c500000,0x00000000)}}, {VT_exponent,22,0x3a859c,{DOUBLEWITHTWODWORDINTREE(0x2c600000,0x00000000)}}, {VT_exponent,22,0x3a859d,{DOUBLEWITHTWODWORDINTREE(0x2c700000,0x00000000)}}, {VT_exponent,22,0x3a859e,{DOUBLEWITHTWODWORDINTREE(0x2c800000,0x00000000)}}, {VT_exponent,22,0x3a859f,{DOUBLEWITHTWODWORDINTREE(0x2c900000,0x00000000)}}, {VT_exponent,22,0x3a85a0,{DOUBLEWITHTWODWORDINTREE(0x2ca00000,0x00000000)}}, {VT_exponent,22,0x3a85a1,{DOUBLEWITHTWODWORDINTREE(0x2cb00000,0x00000000)}}, {VT_exponent,22,0x3a85a2,{DOUBLEWITHTWODWORDINTREE(0x2cc00000,0x00000000)}}, {VT_exponent,22,0x3a85a3,{DOUBLEWITHTWODWORDINTREE(0x2cd00000,0x00000000)}}, {VT_exponent,22,0x3a85a4,{DOUBLEWITHTWODWORDINTREE(0x2ce00000,0x00000000)}}, {VT_exponent,22,0x3a85a5,{DOUBLEWITHTWODWORDINTREE(0x2cf00000,0x00000000)}}, {VT_exponent,22,0x3a85a6,{DOUBLEWITHTWODWORDINTREE(0x2d000000,0x00000000)}}, {VT_exponent,22,0x3a85a7,{DOUBLEWITHTWODWORDINTREE(0x2d100000,0x00000000)}}, {VT_exponent,22,0x3a85a8,{DOUBLEWITHTWODWORDINTREE(0x2d200000,0x00000000)}}, {VT_exponent,22,0x3a85a9,{DOUBLEWITHTWODWORDINTREE(0x2d300000,0x00000000)}}, {VT_exponent,22,0x3a85aa,{DOUBLEWITHTWODWORDINTREE(0x2d400000,0x00000000)}}, {VT_exponent,22,0x3a85ab,{DOUBLEWITHTWODWORDINTREE(0x2d500000,0x00000000)}}, {VT_exponent,22,0x3a85ac,{DOUBLEWITHTWODWORDINTREE(0x2d600000,0x00000000)}}, {VT_exponent,22,0x3a85ad,{DOUBLEWITHTWODWORDINTREE(0x2d700000,0x00000000)}}, {VT_exponent,22,0x3a85ae,{DOUBLEWITHTWODWORDINTREE(0x2d800000,0x00000000)}}, {VT_exponent,22,0x3a85af,{DOUBLEWITHTWODWORDINTREE(0x2d900000,0x00000000)}}, {VT_exponent,22,0x3a85b0,{DOUBLEWITHTWODWORDINTREE(0x2da00000,0x00000000)}}, {VT_exponent,22,0x3a85b1,{DOUBLEWITHTWODWORDINTREE(0x2db00000,0x00000000)}}, {VT_exponent,22,0x3a85b2,{DOUBLEWITHTWODWORDINTREE(0x2dc00000,0x00000000)}}, {VT_exponent,22,0x3a85b3,{DOUBLEWITHTWODWORDINTREE(0x2dd00000,0x00000000)}}, {VT_exponent,22,0x3a85b4,{DOUBLEWITHTWODWORDINTREE(0x2de00000,0x00000000)}}, {VT_exponent,22,0x3a85b5,{DOUBLEWITHTWODWORDINTREE(0x2df00000,0x00000000)}}, {VT_exponent,22,0x3a85b6,{DOUBLEWITHTWODWORDINTREE(0x2e000000,0x00000000)}}, {VT_exponent,22,0x3a85b7,{DOUBLEWITHTWODWORDINTREE(0x2e100000,0x00000000)}}, {VT_exponent,22,0x3a85b8,{DOUBLEWITHTWODWORDINTREE(0x2e200000,0x00000000)}}, {VT_exponent,22,0x3a85b9,{DOUBLEWITHTWODWORDINTREE(0x2e300000,0x00000000)}}, {VT_exponent,22,0x3a85ba,{DOUBLEWITHTWODWORDINTREE(0x2e400000,0x00000000)}}, {VT_exponent,22,0x3a85bb,{DOUBLEWITHTWODWORDINTREE(0x2e500000,0x00000000)}}, {VT_exponent,22,0x3a85bc,{DOUBLEWITHTWODWORDINTREE(0x2e600000,0x00000000)}}, {VT_exponent,22,0x3a85bd,{DOUBLEWITHTWODWORDINTREE(0x2e700000,0x00000000)}}, {VT_exponent,22,0x3a85be,{DOUBLEWITHTWODWORDINTREE(0x2e800000,0x00000000)}}, {VT_exponent,22,0x3a85bf,{DOUBLEWITHTWODWORDINTREE(0x2e900000,0x00000000)}}, {VT_exponent,22,0x3a85c0,{DOUBLEWITHTWODWORDINTREE(0x2ea00000,0x00000000)}}, {VT_exponent,22,0x3a85c1,{DOUBLEWITHTWODWORDINTREE(0x2eb00000,0x00000000)}}, {VT_exponent,22,0x3a85c2,{DOUBLEWITHTWODWORDINTREE(0x2ec00000,0x00000000)}}, {VT_exponent,22,0x3a85c3,{DOUBLEWITHTWODWORDINTREE(0x2ed00000,0x00000000)}}, {VT_exponent,22,0x3a85c4,{DOUBLEWITHTWODWORDINTREE(0x2ee00000,0x00000000)}}, {VT_exponent,22,0x3a85c5,{DOUBLEWITHTWODWORDINTREE(0x2ef00000,0x00000000)}}, {VT_exponent,22,0x3a85c6,{DOUBLEWITHTWODWORDINTREE(0x2f000000,0x00000000)}}, {VT_exponent,22,0x3a85c7,{DOUBLEWITHTWODWORDINTREE(0x2f100000,0x00000000)}}, {VT_exponent,22,0x3a85c8,{DOUBLEWITHTWODWORDINTREE(0x2f200000,0x00000000)}}, {VT_exponent,22,0x3a85c9,{DOUBLEWITHTWODWORDINTREE(0x2f300000,0x00000000)}}, {VT_exponent,22,0x3a85ca,{DOUBLEWITHTWODWORDINTREE(0x2f400000,0x00000000)}}, {VT_exponent,22,0x3a85cb,{DOUBLEWITHTWODWORDINTREE(0x2f500000,0x00000000)}}, {VT_exponent,22,0x3a85cc,{DOUBLEWITHTWODWORDINTREE(0x2f600000,0x00000000)}}, {VT_exponent,22,0x3a85cd,{DOUBLEWITHTWODWORDINTREE(0x2f700000,0x00000000)}}, {VT_exponent,22,0x3a85ce,{DOUBLEWITHTWODWORDINTREE(0x2f800000,0x00000000)}}, {VT_exponent,22,0x3a85cf,{DOUBLEWITHTWODWORDINTREE(0x2f900000,0x00000000)}}, {VT_exponent,22,0x3a85d0,{DOUBLEWITHTWODWORDINTREE(0x2fa00000,0x00000000)}}, {VT_exponent,22,0x3a85d1,{DOUBLEWITHTWODWORDINTREE(0x2fb00000,0x00000000)}}, {VT_exponent,22,0x3a85d2,{DOUBLEWITHTWODWORDINTREE(0x2fc00000,0x00000000)}}, {VT_exponent,22,0x3a85d3,{DOUBLEWITHTWODWORDINTREE(0x2fd00000,0x00000000)}}, {VT_exponent,22,0x3a85d4,{DOUBLEWITHTWODWORDINTREE(0x2fe00000,0x00000000)}}, {VT_exponent,22,0x3a85d5,{DOUBLEWITHTWODWORDINTREE(0x2ff00000,0x00000000)}}, {VT_exponent,22,0x3a85d6,{DOUBLEWITHTWODWORDINTREE(0x30000000,0x00000000)}}, {VT_exponent,22,0x3a85d7,{DOUBLEWITHTWODWORDINTREE(0x30100000,0x00000000)}}, {VT_exponent,22,0x3a85d8,{DOUBLEWITHTWODWORDINTREE(0x30200000,0x00000000)}}, {VT_exponent,22,0x3a85d9,{DOUBLEWITHTWODWORDINTREE(0x30300000,0x00000000)}}, {VT_exponent,22,0x3a85da,{DOUBLEWITHTWODWORDINTREE(0x30400000,0x00000000)}}, {VT_exponent,22,0x3a85db,{DOUBLEWITHTWODWORDINTREE(0x30500000,0x00000000)}}, {VT_exponent,22,0x3a85dc,{DOUBLEWITHTWODWORDINTREE(0x30600000,0x00000000)}}, {VT_exponent,22,0x3a85dd,{DOUBLEWITHTWODWORDINTREE(0x30700000,0x00000000)}}, {VT_exponent,22,0x3a85de,{DOUBLEWITHTWODWORDINTREE(0x30800000,0x00000000)}}, {VT_exponent,22,0x3a85df,{DOUBLEWITHTWODWORDINTREE(0x30900000,0x00000000)}}, {VT_exponent,22,0x3a85e0,{DOUBLEWITHTWODWORDINTREE(0x30a00000,0x00000000)}}, {VT_exponent,22,0x3a85e1,{DOUBLEWITHTWODWORDINTREE(0x30b00000,0x00000000)}}, {VT_exponent,22,0x3a85e2,{DOUBLEWITHTWODWORDINTREE(0x30c00000,0x00000000)}}, {VT_exponent,22,0x3a85e3,{DOUBLEWITHTWODWORDINTREE(0x30d00000,0x00000000)}}, {VT_exponent,22,0x3a85e4,{DOUBLEWITHTWODWORDINTREE(0x30e00000,0x00000000)}}, {VT_exponent,22,0x3a85e5,{DOUBLEWITHTWODWORDINTREE(0x30f00000,0x00000000)}}, {VT_exponent,22,0x3a85e6,{DOUBLEWITHTWODWORDINTREE(0x31000000,0x00000000)}}, {VT_exponent,22,0x3a85e7,{DOUBLEWITHTWODWORDINTREE(0x31100000,0x00000000)}}, {VT_exponent,22,0x3a85e8,{DOUBLEWITHTWODWORDINTREE(0x31200000,0x00000000)}}, {VT_exponent,22,0x3a85e9,{DOUBLEWITHTWODWORDINTREE(0x31300000,0x00000000)}}, {VT_exponent,22,0x3a85ea,{DOUBLEWITHTWODWORDINTREE(0x31400000,0x00000000)}}, {VT_exponent,22,0x3a85eb,{DOUBLEWITHTWODWORDINTREE(0x31500000,0x00000000)}}, {VT_exponent,22,0x3a85ec,{DOUBLEWITHTWODWORDINTREE(0x31600000,0x00000000)}}, {VT_exponent,22,0x3a85ed,{DOUBLEWITHTWODWORDINTREE(0x31700000,0x00000000)}}, {VT_exponent,22,0x3a85ee,{DOUBLEWITHTWODWORDINTREE(0x31800000,0x00000000)}}, {VT_exponent,22,0x3a85ef,{DOUBLEWITHTWODWORDINTREE(0x31900000,0x00000000)}}, {VT_exponent,22,0x3a85f0,{DOUBLEWITHTWODWORDINTREE(0x31a00000,0x00000000)}}, {VT_exponent,22,0x3a85f1,{DOUBLEWITHTWODWORDINTREE(0x31b00000,0x00000000)}}, {VT_exponent,22,0x3a85f2,{DOUBLEWITHTWODWORDINTREE(0x31c00000,0x00000000)}}, {VT_exponent,22,0x3a85f3,{DOUBLEWITHTWODWORDINTREE(0x31d00000,0x00000000)}}, {VT_exponent,22,0x3a85f4,{DOUBLEWITHTWODWORDINTREE(0x31e00000,0x00000000)}}, {VT_exponent,22,0x3a85f5,{DOUBLEWITHTWODWORDINTREE(0x31f00000,0x00000000)}}, {VT_exponent,22,0x3a85f6,{DOUBLEWITHTWODWORDINTREE(0x32000000,0x00000000)}}, {VT_exponent,22,0x3a85f7,{DOUBLEWITHTWODWORDINTREE(0x32100000,0x00000000)}}, {VT_exponent,22,0x3a85f8,{DOUBLEWITHTWODWORDINTREE(0x32200000,0x00000000)}}, {VT_exponent,22,0x3a85f9,{DOUBLEWITHTWODWORDINTREE(0x32300000,0x00000000)}}, {VT_exponent,22,0x3a85fa,{DOUBLEWITHTWODWORDINTREE(0x32400000,0x00000000)}}, {VT_exponent,22,0x3a85fb,{DOUBLEWITHTWODWORDINTREE(0x32500000,0x00000000)}}, {VT_exponent,22,0x3a85fc,{DOUBLEWITHTWODWORDINTREE(0x32600000,0x00000000)}}, {VT_exponent,22,0x3a85fd,{DOUBLEWITHTWODWORDINTREE(0x32700000,0x00000000)}}, {VT_exponent,22,0x3a85fe,{DOUBLEWITHTWODWORDINTREE(0x32800000,0x00000000)}}, {VT_exponent,22,0x3a85ff,{DOUBLEWITHTWODWORDINTREE(0x32900000,0x00000000)}}, {VT_exponent,22,0x3a8600,{DOUBLEWITHTWODWORDINTREE(0x32a00000,0x00000000)}}, {VT_exponent,22,0x3a8601,{DOUBLEWITHTWODWORDINTREE(0x32b00000,0x00000000)}}, {VT_exponent,22,0x3a8602,{DOUBLEWITHTWODWORDINTREE(0x32c00000,0x00000000)}}, {VT_exponent,22,0x3a8603,{DOUBLEWITHTWODWORDINTREE(0x32d00000,0x00000000)}}, {VT_exponent,22,0x3a8604,{DOUBLEWITHTWODWORDINTREE(0x32e00000,0x00000000)}}, {VT_exponent,22,0x3a8605,{DOUBLEWITHTWODWORDINTREE(0x32f00000,0x00000000)}}, {VT_exponent,22,0x3a8606,{DOUBLEWITHTWODWORDINTREE(0x33000000,0x00000000)}}, {VT_exponent,22,0x3a8607,{DOUBLEWITHTWODWORDINTREE(0x33100000,0x00000000)}}, {VT_exponent,22,0x3a8608,{DOUBLEWITHTWODWORDINTREE(0x33200000,0x00000000)}}, {VT_exponent,22,0x3a8609,{DOUBLEWITHTWODWORDINTREE(0x33300000,0x00000000)}}, {VT_exponent,22,0x3a860a,{DOUBLEWITHTWODWORDINTREE(0x33400000,0x00000000)}}, {VT_exponent,22,0x3a860b,{DOUBLEWITHTWODWORDINTREE(0x33500000,0x00000000)}}, {VT_exponent,22,0x3a860c,{DOUBLEWITHTWODWORDINTREE(0x33600000,0x00000000)}}, {VT_exponent,22,0x3a860d,{DOUBLEWITHTWODWORDINTREE(0x33700000,0x00000000)}}, {VT_exponent,22,0x3a860e,{DOUBLEWITHTWODWORDINTREE(0x33800000,0x00000000)}}, {VT_exponent,22,0x3a860f,{DOUBLEWITHTWODWORDINTREE(0x33900000,0x00000000)}}, {VT_exponent,22,0x3a8610,{DOUBLEWITHTWODWORDINTREE(0x33a00000,0x00000000)}}, {VT_exponent,22,0x3a8611,{DOUBLEWITHTWODWORDINTREE(0x33b00000,0x00000000)}}, {VT_exponent,22,0x3a8612,{DOUBLEWITHTWODWORDINTREE(0x33c00000,0x00000000)}}, {VT_exponent,22,0x3a8613,{DOUBLEWITHTWODWORDINTREE(0x33d00000,0x00000000)}}, {VT_exponent,22,0x3a8614,{DOUBLEWITHTWODWORDINTREE(0x33e00000,0x00000000)}}, {VT_exponent,22,0x3a8615,{DOUBLEWITHTWODWORDINTREE(0x33f00000,0x00000000)}}, {VT_exponent,22,0x3a8616,{DOUBLEWITHTWODWORDINTREE(0x34000000,0x00000000)}}, {VT_exponent,22,0x3a8617,{DOUBLEWITHTWODWORDINTREE(0x34100000,0x00000000)}}, {VT_exponent,22,0x3a8618,{DOUBLEWITHTWODWORDINTREE(0x34200000,0x00000000)}}, {VT_exponent,22,0x3a8619,{DOUBLEWITHTWODWORDINTREE(0x34300000,0x00000000)}}, {VT_exponent,22,0x3a861a,{DOUBLEWITHTWODWORDINTREE(0x34400000,0x00000000)}}, {VT_exponent,22,0x3a861b,{DOUBLEWITHTWODWORDINTREE(0x34500000,0x00000000)}}, {VT_exponent,22,0x3a861c,{DOUBLEWITHTWODWORDINTREE(0x34600000,0x00000000)}}, {VT_exponent,22,0x3a861d,{DOUBLEWITHTWODWORDINTREE(0x34700000,0x00000000)}}, {VT_exponent,22,0x3a861e,{DOUBLEWITHTWODWORDINTREE(0x34800000,0x00000000)}}, {VT_exponent,22,0x3a861f,{DOUBLEWITHTWODWORDINTREE(0x34900000,0x00000000)}}, {VT_exponent,22,0x3a8620,{DOUBLEWITHTWODWORDINTREE(0x34a00000,0x00000000)}}, {VT_exponent,22,0x3a8621,{DOUBLEWITHTWODWORDINTREE(0x34b00000,0x00000000)}}, {VT_exponent,22,0x3a8622,{DOUBLEWITHTWODWORDINTREE(0x34c00000,0x00000000)}}, {VT_exponent,22,0x3a8623,{DOUBLEWITHTWODWORDINTREE(0x34d00000,0x00000000)}}, {VT_exponent,22,0x3a8624,{DOUBLEWITHTWODWORDINTREE(0x34e00000,0x00000000)}}, {VT_exponent,22,0x3a8625,{DOUBLEWITHTWODWORDINTREE(0x34f00000,0x00000000)}}, {VT_exponent,22,0x3a8626,{DOUBLEWITHTWODWORDINTREE(0x35000000,0x00000000)}}, {VT_exponent,22,0x3a8627,{DOUBLEWITHTWODWORDINTREE(0x35100000,0x00000000)}}, {VT_exponent,22,0x3a8628,{DOUBLEWITHTWODWORDINTREE(0x35200000,0x00000000)}}, {VT_exponent,22,0x3a8629,{DOUBLEWITHTWODWORDINTREE(0x35300000,0x00000000)}}, {VT_exponent,18,0xf787,{DOUBLEWITHTWODWORDINTREE(0x35400000,0x00000000)}}, {VT_exponent,18,0xd1d4,{DOUBLEWITHTWODWORDINTREE(0x35500000,0x00000000)}}, {VT_exponent,19,0x77f9f,{DOUBLEWITHTWODWORDINTREE(0x35600000,0x00000000)}}, {VT_exponent,18,0x3b8fb,{DOUBLEWITHTWODWORDINTREE(0x35700000,0x00000000)}}, {VT_exponent,19,0x1ef1a,{DOUBLEWITHTWODWORDINTREE(0x35800000,0x00000000)}}, {VT_exponent,21,0x1d4315,{DOUBLEWITHTWODWORDINTREE(0x35900000,0x00000000)}}, {VT_exponent,16,0x3de2,{DOUBLEWITHTWODWORDINTREE(0x35a00000,0x00000000)}}, {VT_exponent,22,0x3a862c,{DOUBLEWITHTWODWORDINTREE(0x35b00000,0x00000000)}}, {VT_exponent,22,0x3a862d,{DOUBLEWITHTWODWORDINTREE(0x35c00000,0x00000000)}}, {VT_exponent,22,0x3a862e,{DOUBLEWITHTWODWORDINTREE(0x35d00000,0x00000000)}}, {VT_exponent,22,0x3a862f,{DOUBLEWITHTWODWORDINTREE(0x35e00000,0x00000000)}}, {VT_exponent,22,0x3a8630,{DOUBLEWITHTWODWORDINTREE(0x35f00000,0x00000000)}}, {VT_exponent,22,0x3a8631,{DOUBLEWITHTWODWORDINTREE(0x36000000,0x00000000)}}, {VT_exponent,22,0x3a8632,{DOUBLEWITHTWODWORDINTREE(0x36100000,0x00000000)}}, {VT_exponent,22,0x3a8633,{DOUBLEWITHTWODWORDINTREE(0x36200000,0x00000000)}}, {VT_exponent,22,0x3a8634,{DOUBLEWITHTWODWORDINTREE(0x36300000,0x00000000)}}, {VT_exponent,22,0x3a8635,{DOUBLEWITHTWODWORDINTREE(0x36400000,0x00000000)}}, {VT_exponent,22,0x3a8636,{DOUBLEWITHTWODWORDINTREE(0x36500000,0x00000000)}}, {VT_exponent,22,0x3a8637,{DOUBLEWITHTWODWORDINTREE(0x36600000,0x00000000)}}, {VT_exponent,22,0x3a8638,{DOUBLEWITHTWODWORDINTREE(0x36700000,0x00000000)}}, {VT_exponent,21,0x1d431d,{DOUBLEWITHTWODWORDINTREE(0x36800000,0x00000000)}}, {VT_exponent,22,0x3a8639,{DOUBLEWITHTWODWORDINTREE(0x36900000,0x00000000)}}, {VT_exponent,22,0x3a863c,{DOUBLEWITHTWODWORDINTREE(0x36a00000,0x00000000)}}, {VT_exponent,16,0x3de0,{DOUBLEWITHTWODWORDINTREE(0x36b00000,0x00000000)}}, {VT_exponent,18,0x3a95e,{DOUBLEWITHTWODWORDINTREE(0x36c00000,0x00000000)}}, {VT_exponent,21,0x1d431f,{DOUBLEWITHTWODWORDINTREE(0x36d00000,0x00000000)}}, {VT_exponent,22,0x3a863d,{DOUBLEWITHTWODWORDINTREE(0x36e00000,0x00000000)}}, {VT_exponent,22,0x3a8640,{DOUBLEWITHTWODWORDINTREE(0x36f00000,0x00000000)}}, {VT_exponent,20,0x34749,{DOUBLEWITHTWODWORDINTREE(0x37000000,0x00000000)}}, {VT_exponent,20,0x3474d,{DOUBLEWITHTWODWORDINTREE(0x37100000,0x00000000)}}, {VT_exponent,22,0x3a8641,{DOUBLEWITHTWODWORDINTREE(0x37200000,0x00000000)}}, {VT_exponent,22,0x3a8642,{DOUBLEWITHTWODWORDINTREE(0x37300000,0x00000000)}}, {VT_exponent,22,0x3a8643,{DOUBLEWITHTWODWORDINTREE(0x37400000,0x00000000)}}, {VT_exponent,22,0x3a8644,{DOUBLEWITHTWODWORDINTREE(0x37500000,0x00000000)}}, {VT_exponent,22,0x3a8645,{DOUBLEWITHTWODWORDINTREE(0x37600000,0x00000000)}}, {VT_exponent,22,0x3a8646,{DOUBLEWITHTWODWORDINTREE(0x37700000,0x00000000)}}, {VT_exponent,22,0x3a8647,{DOUBLEWITHTWODWORDINTREE(0x37800000,0x00000000)}}, {VT_exponent,22,0x3a8648,{DOUBLEWITHTWODWORDINTREE(0x37900000,0x00000000)}}, {VT_exponent,22,0x3a8649,{DOUBLEWITHTWODWORDINTREE(0x37a00000,0x00000000)}}, {VT_exponent,22,0x3a864a,{DOUBLEWITHTWODWORDINTREE(0x37b00000,0x00000000)}}, {VT_exponent,22,0x3a864b,{DOUBLEWITHTWODWORDINTREE(0x37c00000,0x00000000)}}, {VT_exponent,22,0x3a864c,{DOUBLEWITHTWODWORDINTREE(0x37d00000,0x00000000)}}, {VT_exponent,22,0x3a864d,{DOUBLEWITHTWODWORDINTREE(0x37e00000,0x00000000)}}, {VT_exponent,22,0x3a864e,{DOUBLEWITHTWODWORDINTREE(0x37f00000,0x00000000)}}, {VT_exponent,22,0x3a864f,{DOUBLEWITHTWODWORDINTREE(0x38000000,0x00000000)}}, {VT_exponent,22,0x3a8650,{DOUBLEWITHTWODWORDINTREE(0x38100000,0x00000000)}}, {VT_exponent,22,0x3a8651,{DOUBLEWITHTWODWORDINTREE(0x38200000,0x00000000)}}, {VT_exponent,22,0x3a8652,{DOUBLEWITHTWODWORDINTREE(0x38300000,0x00000000)}}, {VT_exponent,22,0x3a8653,{DOUBLEWITHTWODWORDINTREE(0x38400000,0x00000000)}}, {VT_exponent,22,0x3a8654,{DOUBLEWITHTWODWORDINTREE(0x38500000,0x00000000)}}, {VT_exponent,22,0x3a8655,{DOUBLEWITHTWODWORDINTREE(0x38600000,0x00000000)}}, {VT_exponent,22,0x3a8656,{DOUBLEWITHTWODWORDINTREE(0x38700000,0x00000000)}}, {VT_exponent,22,0x3a8657,{DOUBLEWITHTWODWORDINTREE(0x38800000,0x00000000)}}, {VT_exponent,22,0x3a8658,{DOUBLEWITHTWODWORDINTREE(0x38900000,0x00000000)}}, {VT_exponent,22,0x3a8659,{DOUBLEWITHTWODWORDINTREE(0x38a00000,0x00000000)}}, {VT_exponent,22,0x3a865a,{DOUBLEWITHTWODWORDINTREE(0x38b00000,0x00000000)}}, {VT_exponent,22,0x3a865b,{DOUBLEWITHTWODWORDINTREE(0x38c00000,0x00000000)}}, {VT_exponent,22,0x3a865c,{DOUBLEWITHTWODWORDINTREE(0x38d00000,0x00000000)}}, {VT_exponent,22,0x3a865d,{DOUBLEWITHTWODWORDINTREE(0x38e00000,0x00000000)}}, {VT_exponent,21,0x1d432f,{DOUBLEWITHTWODWORDINTREE(0x38f00000,0x00000000)}}, {VT_exponent,22,0x3a8660,{DOUBLEWITHTWODWORDINTREE(0x39000000,0x00000000)}}, {VT_exponent,22,0x3a8661,{DOUBLEWITHTWODWORDINTREE(0x39100000,0x00000000)}}, {VT_exponent,22,0x3a8662,{DOUBLEWITHTWODWORDINTREE(0x39200000,0x00000000)}}, {VT_exponent,21,0x1d4332,{DOUBLEWITHTWODWORDINTREE(0x39300000,0x00000000)}}, {VT_exponent,18,0xd1d5,{DOUBLEWITHTWODWORDINTREE(0x39400000,0x00000000)}}, {VT_exponent,18,0x3bfda,{DOUBLEWITHTWODWORDINTREE(0x39500000,0x00000000)}}, {VT_exponent,15,0x7528,{DOUBLEWITHTWODWORDINTREE(0x39600000,0x00000000)}}, {VT_exponent,15,0x7529,{DOUBLEWITHTWODWORDINTREE(0x39700000,0x00000000)}}, {VT_exponent,18,0x3a95f,{DOUBLEWITHTWODWORDINTREE(0x39800000,0x00000000)}}, {VT_exponent,17,0x1d434,{DOUBLEWITHTWODWORDINTREE(0x39900000,0x00000000)}}, {VT_exponent,19,0x750cd,{DOUBLEWITHTWODWORDINTREE(0x39a00000,0x00000000)}}, {VT_exponent,18,0x3a867,{DOUBLEWITHTWODWORDINTREE(0x39b00000,0x00000000)}}, {VT_exponent,19,0x771fd,{DOUBLEWITHTWODWORDINTREE(0x39c00000,0x00000000)}}, {VT_exponent,15,0x7764,{DOUBLEWITHTWODWORDINTREE(0x39d00000,0x00000000)}}, {VT_exponent,20,0xee3f9,{DOUBLEWITHTWODWORDINTREE(0x39e00000,0x00000000)}}, {VT_exponent,18,0x3bfdb,{DOUBLEWITHTWODWORDINTREE(0x39f00000,0x00000000)}}, {VT_exponent,16,0xeff7,{DOUBLEWITHTWODWORDINTREE(0x3a000000,0x00000000)}}, {VT_exponent,18,0xd1d6,{DOUBLEWITHTWODWORDINTREE(0x3a100000,0x00000000)}}, {VT_exponent,22,0x3a8663,{DOUBLEWITHTWODWORDINTREE(0x3a200000,0x00000000)}}, {VT_exponent,22,0x3a8666,{DOUBLEWITHTWODWORDINTREE(0x3a300000,0x00000000)}}, {VT_exponent,18,0x3b8fa,{DOUBLEWITHTWODWORDINTREE(0x3a400000,0x00000000)}}, {VT_exponent,17,0x1d435,{DOUBLEWITHTWODWORDINTREE(0x3a500000,0x00000000)}}, {VT_exponent,17,0x1dfe4,{DOUBLEWITHTWODWORDINTREE(0x3a600000,0x00000000)}}, {VT_exponent,19,0x750d8,{DOUBLEWITHTWODWORDINTREE(0x3a700000,0x00000000)}}, {VT_exponent,18,0x3a95b,{DOUBLEWITHTWODWORDINTREE(0x3a800000,0x00000000)}}, {VT_exponent,19,0x77f9e,{DOUBLEWITHTWODWORDINTREE(0x3a900000,0x00000000)}}, {VT_exponent,19,0x750d9,{DOUBLEWITHTWODWORDINTREE(0x3aa00000,0x00000000)}}, {VT_exponent,18,0xd1d7,{DOUBLEWITHTWODWORDINTREE(0x3ab00000,0x00000000)}}, {VT_exponent,18,0x3b8ff,{DOUBLEWITHTWODWORDINTREE(0x3ac00000,0x00000000)}}, {VT_exponent,17,0x1dc7c,{DOUBLEWITHTWODWORDINTREE(0x3ad00000,0x00000000)}}, {VT_exponent,19,0x750da,{DOUBLEWITHTWODWORDINTREE(0x3ae00000,0x00000000)}}, {VT_exponent,17,0x7bc2,{DOUBLEWITHTWODWORDINTREE(0x3af00000,0x00000000)}}, {VT_exponent,18,0x3bfca,{DOUBLEWITHTWODWORDINTREE(0x3b000000,0x00000000)}}, {VT_exponent,19,0x1a3a5,{DOUBLEWITHTWODWORDINTREE(0x3b100000,0x00000000)}}, {VT_exponent,17,0x1d4ac,{DOUBLEWITHTWODWORDINTREE(0x3b200000,0x00000000)}}, {VT_exponent,18,0x3a86e,{DOUBLEWITHTWODWORDINTREE(0x3b300000,0x00000000)}}, {VT_exponent,17,0x1d438,{DOUBLEWITHTWODWORDINTREE(0x3b400000,0x00000000)}}, {VT_exponent,18,0x3bfcb,{DOUBLEWITHTWODWORDINTREE(0x3b500000,0x00000000)}}, {VT_exponent,19,0x1a3a7,{DOUBLEWITHTWODWORDINTREE(0x3b600000,0x00000000)}}, {VT_exponent,17,0x1d4ae,{DOUBLEWITHTWODWORDINTREE(0x3b700000,0x00000000)}}, {VT_exponent,18,0x3bfce,{DOUBLEWITHTWODWORDINTREE(0x3b800000,0x00000000)}}, {VT_exponent,18,0xf78c,{DOUBLEWITHTWODWORDINTREE(0x3b900000,0x00000000)}}, {VT_exponent,17,0x1dfec,{DOUBLEWITHTWODWORDINTREE(0x3ba00000,0x00000000)}}, {VT_exponent,17,0x1d439,{DOUBLEWITHTWODWORDINTREE(0x3bb00000,0x00000000)}}, {VT_exponent,17,0x68e8,{DOUBLEWITHTWODWORDINTREE(0x3bc00000,0x00000000)}}, {VT_exponent,18,0xf786,{DOUBLEWITHTWODWORDINTREE(0x3bd00000,0x00000000)}}, {VT_exponent,15,0x771e,{DOUBLEWITHTWODWORDINTREE(0x3be00000,0x00000000)}}, {VT_exponent,17,0x1dfe6,{DOUBLEWITHTWODWORDINTREE(0x3bf00000,0x00000000)}}, {VT_exponent,15,0x77f8,{DOUBLEWITHTWODWORDINTREE(0x3c000000,0x00000000)}}, {VT_exponent,14,0x3bb3,{DOUBLEWITHTWODWORDINTREE(0x3c100000,0x00000000)}}, {VT_exponent,14,0x3b8e,{DOUBLEWITHTWODWORDINTREE(0x3c200000,0x00000000)}}, {VT_exponent,14,0x3a82,{DOUBLEWITHTWODWORDINTREE(0x3c300000,0x00000000)}}, {VT_exponent,14,0x3b96,{DOUBLEWITHTWODWORDINTREE(0x3c400000,0x00000000)}}, {VT_exponent,13,0x68f,{DOUBLEWITHTWODWORDINTREE(0x3c500000,0x00000000)}}, {VT_exponent,12,0x3d4,{DOUBLEWITHTWODWORDINTREE(0x3c600000,0x00000000)}}, {VT_exponent,13,0x1dca,{DOUBLEWITHTWODWORDINTREE(0x3c700000,0x00000000)}}, {VT_exponent,12,0x346,{DOUBLEWITHTWODWORDINTREE(0x3c800000,0x00000000)}}, {VT_exponent,12,0xee7,{DOUBLEWITHTWODWORDINTREE(0x3c900000,0x00000000)}}, {VT_exponent,12,0xeea,{DOUBLEWITHTWODWORDINTREE(0x3ca00000,0x00000000)}}, {VT_exponent,11,0x1ed,{DOUBLEWITHTWODWORDINTREE(0x3cb00000,0x00000000)}}, {VT_exponent,12,0x3df,{DOUBLEWITHTWODWORDINTREE(0x3cc00000,0x00000000)}}, {VT_exponent,11,0x1a2,{DOUBLEWITHTWODWORDINTREE(0x3cd00000,0x00000000)}}, {VT_exponent,11,0x56f,{DOUBLEWITHTWODWORDINTREE(0x3ce00000,0x00000000)}}, {VT_exponent,11,0xb9,{DOUBLEWITHTWODWORDINTREE(0x3cf00000,0x00000000)}}, {VT_exponent,13,0x7b2,{DOUBLEWITHTWODWORDINTREE(0x3d000000,0x00000000)}}, {VT_exponent,13,0x1dd8,{DOUBLEWITHTWODWORDINTREE(0x3d100000,0x00000000)}}, {VT_exponent,13,0x15ba,{DOUBLEWITHTWODWORDINTREE(0x3d200000,0x00000000)}}, {VT_exponent,12,0xee6,{DOUBLEWITHTWODWORDINTREE(0x3d300000,0x00000000)}}, {VT_exponent,13,0x15b8,{DOUBLEWITHTWODWORDINTREE(0x3d400000,0x00000000)}}, {VT_exponent,14,0xf79,{DOUBLEWITHTWODWORDINTREE(0x3d500000,0x00000000)}}, {VT_exponent,14,0x3a81,{DOUBLEWITHTWODWORDINTREE(0x3d600000,0x00000000)}}, {VT_exponent,14,0xd1c,{DOUBLEWITHTWODWORDINTREE(0x3d700000,0x00000000)}}, {VT_exponent,15,0x7765,{DOUBLEWITHTWODWORDINTREE(0x3d800000,0x00000000)}}, {VT_exponent,14,0xf54,{DOUBLEWITHTWODWORDINTREE(0x3d900000,0x00000000)}}, {VT_exponent,13,0x15b9,{DOUBLEWITHTWODWORDINTREE(0x3da00000,0x00000000)}}, {VT_exponent,13,0x7ab,{DOUBLEWITHTWODWORDINTREE(0x3db00000,0x00000000)}}, {VT_exponent,15,0x7500,{DOUBLEWITHTWODWORDINTREE(0x3dc00000,0x00000000)}}, {VT_exponent,15,0x1eaa,{DOUBLEWITHTWODWORDINTREE(0x3dd00000,0x00000000)}}, {VT_exponent,15,0x7501,{DOUBLEWITHTWODWORDINTREE(0x3de00000,0x00000000)}}, {VT_exponent,15,0x1eab,{DOUBLEWITHTWODWORDINTREE(0x3df00000,0x00000000)}}, {VT_exponent,14,0x3b97,{DOUBLEWITHTWODWORDINTREE(0x3e000000,0x00000000)}}, {VT_exponent,15,0x752a,{DOUBLEWITHTWODWORDINTREE(0x3e100000,0x00000000)}}, {VT_exponent,15,0x77fa,{DOUBLEWITHTWODWORDINTREE(0x3e200000,0x00000000)}}, {VT_double,10,0xf4,{DOUBLEWITHTWODWORDINTREE(0x3e35798e,0xe2308c3a)}}, {VT_exponent,14,0x3a93,{DOUBLEWITHTWODWORDINTREE(0x3e300000,0x00000000)}}, {VT_double,11,0x77c,{DOUBLEWITHTWODWORDINTREE(0x3e45798e,0xe2308c3a)}}, {VT_exponent,13,0x1dc6,{DOUBLEWITHTWODWORDINTREE(0x3e400000,0x00000000)}}, {VT_exponent,13,0x7bd,{DOUBLEWITHTWODWORDINTREE(0x3e500000,0x00000000)}}, {VT_exponent,13,0x1dff,{DOUBLEWITHTWODWORDINTREE(0x3e600000,0x00000000)}}, {VT_exponent,12,0xefe,{DOUBLEWITHTWODWORDINTREE(0x3e700000,0x00000000)}}, {VT_double,8,0xaf,{DOUBLEWITHTWODWORDINTREE(0x3e8ad7f2,0x9abcaf4a)}}, {VT_exponent,12,0xeed,{DOUBLEWITHTWODWORDINTREE(0x3e800000,0x00000000)}}, {VT_exponent,11,0xb8,{DOUBLEWITHTWODWORDINTREE(0x3e900000,0x00000000)}}, {VT_exponent,12,0x3d8,{DOUBLEWITHTWODWORDINTREE(0x3ea00000,0x00000000)}}, {VT_exponent,11,0x1eb,{DOUBLEWITHTWODWORDINTREE(0x3eb00000,0x00000000)}}, {VT_double,9,0x1d2,{DOUBLEWITHTWODWORDINTREE(0x3ec0c6f7,0xa0b5ed8e)}}, {VT_exponent,13,0x1d4b,{DOUBLEWITHTWODWORDINTREE(0x3ec00000,0x00000000)}}, {VT_exponent,13,0x7b3,{DOUBLEWITHTWODWORDINTREE(0x3ed00000,0x00000000)}}, {VT_exponent,10,0x5d,{DOUBLEWITHTWODWORDINTREE(0x3ee00000,0x00000000)}}, {VT_exponent,12,0xeeb,{DOUBLEWITHTWODWORDINTREE(0x3ef00000,0x00000000)}}, {VT_exponent,11,0x1ee,{DOUBLEWITHTWODWORDINTREE(0x3f000000,0x00000000)}}, {VT_exponent,10,0x5f,{DOUBLEWITHTWODWORDINTREE(0x3f100000,0x00000000)}}, {VT_exponent,10,0x2b6,{DOUBLEWITHTWODWORDINTREE(0x3f200000,0x00000000)}}, {VT_exponent,9,0x1de,{DOUBLEWITHTWODWORDINTREE(0x3f300000,0x00000000)}}, {VT_double,10,0xd0,{DOUBLEWITHTWODWORDINTREE(0x3f454c98,0x5f06f694)}}, {VT_double,6,0x9,{DOUBLEWITHTWODWORDINTREE(0x3f4a36e2,0xeb1c432d)}}, {VT_exponent,8,0xe8,{DOUBLEWITHTWODWORDINTREE(0x3f400000,0x00000000)}}, {VT_double,4,0xf,{DOUBLEWITHTWODWORDINTREE(0x3f50624d,0xd2f1a9fc)}}, {VT_exponent,8,0xae,{DOUBLEWITHTWODWORDINTREE(0x3f500000,0x00000000)}}, {VT_double,5,0x16,{DOUBLEWITHTWODWORDINTREE(0x3f60624d,0xd2f1a9fc)}}, {VT_exponent,7,0x1b,{DOUBLEWITHTWODWORDINTREE(0x3f600000,0x00000000)}}, {VT_exponent,7,0x76,{DOUBLEWITHTWODWORDINTREE(0x3f700000,0x00000000)}}, {VT_exponent,7,0xa,{DOUBLEWITHTWODWORDINTREE(0x3f800000,0x00000000)}}, {VT_exponent,6,0x8,{DOUBLEWITHTWODWORDINTREE(0x3f900000,0x00000000)}}, {VT_exponent,6,0xe,{DOUBLEWITHTWODWORDINTREE(0x3fa00000,0x00000000)}}, {VT_double,11,0x751,{DOUBLEWITHTWODWORDINTREE(0x3fbe69ad,0x42c3c9ee)}}, {VT_exponent,6,0x4,{DOUBLEWITHTWODWORDINTREE(0x3fb00000,0x00000000)}}, {VT_exponent,6,0xc,{DOUBLEWITHTWODWORDINTREE(0x3fc00000,0x00000000)}}, {VT_exponent,5,0x3,{DOUBLEWITHTWODWORDINTREE(0x3fd00000,0x00000000)}}, {VT_double,11,0x777,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}}, {VT_double,9,0x1d6,{DOUBLEWITHTWODWORDINTREE(0x3fefffff,0xf8000002)}}, {VT_exponent,4,0x8,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}}, {VT_double,4,0x0,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}}, {VT_exponent,5,0x13,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}}, {VT_exponent,5,0x1b,{DOUBLEWITHTWODWORDINTREE(0x40000000,0x00000000)}}, {VT_double,9,0x15a,{DOUBLEWITHTWODWORDINTREE(0x401921fb,0x54442d18)}}, {VT_exponent,5,0x17,{DOUBLEWITHTWODWORDINTREE(0x40100000,0x00000000)}}, {VT_exponent,5,0x12,{DOUBLEWITHTWODWORDINTREE(0x40200000,0x00000000)}}, {VT_double,11,0x774,{DOUBLEWITHTWODWORDINTREE(0x4035ee14,0x80000000)}}, {VT_exponent,5,0x19,{DOUBLEWITHTWODWORDINTREE(0x40300000,0x00000000)}}, {VT_double,9,0x1d3,{DOUBLEWITHTWODWORDINTREE(0x404ca5dc,0x1a63c1f8)}}, {VT_exponent,5,0x1a,{DOUBLEWITHTWODWORDINTREE(0x40400000,0x00000000)}}, {VT_double,11,0x77e,{DOUBLEWITHTWODWORDINTREE(0x405bb32f,0xe0000000)}}, {VT_double,10,0x5e,{DOUBLEWITHTWODWORDINTREE(0x405c332f,0xe0000000)}}, {VT_exponent,5,0x18,{DOUBLEWITHTWODWORDINTREE(0x40500000,0x00000000)}}, {VT_double,9,0x1d7,{DOUBLEWITHTWODWORDINTREE(0x40668000,0x00000000)}}, {VT_exponent,5,0x1c,{DOUBLEWITHTWODWORDINTREE(0x40600000,0x00000000)}}, {VT_double,9,0x1d5,{DOUBLEWITHTWODWORDINTREE(0x40768000,0x00000000)}}, {VT_exponent,5,0x14,{DOUBLEWITHTWODWORDINTREE(0x40700000,0x00000000)}}, {VT_double,11,0x77d,{DOUBLEWITHTWODWORDINTREE(0x408f4000,0x00000000)}}, {VT_exponent,5,0x5,{DOUBLEWITHTWODWORDINTREE(0x40800000,0x00000000)}}, {VT_double,10,0xd2,{DOUBLEWITHTWODWORDINTREE(0x409233ff,0xffffffff)}}, {VT_double,8,0x3c,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000000)}}, {VT_double,11,0x753,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000001)}}, {VT_double,10,0xd3,{DOUBLEWITHTWODWORDINTREE(0x4092abff,0xffffffff)}}, {VT_double,8,0x35,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000000)}}, {VT_double,11,0x770,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000001)}}, {VT_exponent,8,0x16,{DOUBLEWITHTWODWORDINTREE(0x40900000,0x00000000)}}, {VT_exponent,12,0xee2,{DOUBLEWITHTWODWORDINTREE(0x40a00000,0x00000000)}}, {VT_exponent,12,0xee4,{DOUBLEWITHTWODWORDINTREE(0x40b00000,0x00000000)}}, {VT_double,7,0x1f,{DOUBLEWITHTWODWORDINTREE(0x40c81c80,0x00000000)}}, {VT_exponent,8,0xac,{DOUBLEWITHTWODWORDINTREE(0x40c00000,0x00000000)}}, {VT_exponent,13,0x15bb,{DOUBLEWITHTWODWORDINTREE(0x40d00000,0x00000000)}}, {VT_exponent,22,0x3a8667,{DOUBLEWITHTWODWORDINTREE(0x40e00000,0x00000000)}}, {VT_exponent,22,0x3a86d8,{DOUBLEWITHTWODWORDINTREE(0x40f00000,0x00000000)}}, {VT_exponent,22,0x3a86d9,{DOUBLEWITHTWODWORDINTREE(0x41000000,0x00000000)}}, {VT_exponent,22,0x3a86da,{DOUBLEWITHTWODWORDINTREE(0x41100000,0x00000000)}}, {VT_exponent,17,0x1dc7e,{DOUBLEWITHTWODWORDINTREE(0x41200000,0x00000000)}}, {VT_exponent,22,0x3a86db,{DOUBLEWITHTWODWORDINTREE(0x41300000,0x00000000)}}, {VT_exponent,22,0x3a86dc,{DOUBLEWITHTWODWORDINTREE(0x41400000,0x00000000)}}, {VT_exponent,22,0x3a86dd,{DOUBLEWITHTWODWORDINTREE(0x41500000,0x00000000)}}, {VT_exponent,22,0x3a86de,{DOUBLEWITHTWODWORDINTREE(0x41600000,0x00000000)}}, {VT_exponent,22,0x3a86df,{DOUBLEWITHTWODWORDINTREE(0x41700000,0x00000000)}}, {VT_exponent,22,0x3a86f0,{DOUBLEWITHTWODWORDINTREE(0x41800000,0x00000000)}}, {VT_exponent,22,0x3a86f1,{DOUBLEWITHTWODWORDINTREE(0x41900000,0x00000000)}}, {VT_exponent,22,0x3a86f2,{DOUBLEWITHTWODWORDINTREE(0x41a00000,0x00000000)}}, {VT_exponent,22,0x3a86f3,{DOUBLEWITHTWODWORDINTREE(0x41b00000,0x00000000)}}, {VT_double,6,0x2a,{DOUBLEWITHTWODWORDINTREE(0x41cdcd64,0xff800000)}}, {VT_exponent,22,0x3a86f4,{DOUBLEWITHTWODWORDINTREE(0x41c00000,0x00000000)}}, {VT_exponent,22,0x3a86f5,{DOUBLEWITHTWODWORDINTREE(0x41d00000,0x00000000)}}, {VT_exponent,22,0x3a86f6,{DOUBLEWITHTWODWORDINTREE(0x41e00000,0x00000000)}}, {VT_exponent,22,0x3a86f7,{DOUBLEWITHTWODWORDINTREE(0x41f00000,0x00000000)}}, {VT_exponent,22,0x3a86f8,{DOUBLEWITHTWODWORDINTREE(0x42000000,0x00000000)}}, {VT_exponent,22,0x3a86f9,{DOUBLEWITHTWODWORDINTREE(0x42100000,0x00000000)}}, {VT_exponent,22,0x3a86fa,{DOUBLEWITHTWODWORDINTREE(0x42200000,0x00000000)}}, {VT_exponent,22,0x3a86fb,{DOUBLEWITHTWODWORDINTREE(0x42300000,0x00000000)}}, {VT_exponent,22,0x3a86fc,{DOUBLEWITHTWODWORDINTREE(0x42400000,0x00000000)}}, {VT_exponent,22,0x3a86fd,{DOUBLEWITHTWODWORDINTREE(0x42500000,0x00000000)}}, {VT_exponent,22,0x3a86fe,{DOUBLEWITHTWODWORDINTREE(0x42600000,0x00000000)}}, {VT_exponent,22,0x3a86ff,{DOUBLEWITHTWODWORDINTREE(0x42700000,0x00000000)}}, {VT_exponent,22,0x3a8740,{DOUBLEWITHTWODWORDINTREE(0x42800000,0x00000000)}}, {VT_exponent,22,0x3a8741,{DOUBLEWITHTWODWORDINTREE(0x42900000,0x00000000)}}, {VT_exponent,22,0x3a8742,{DOUBLEWITHTWODWORDINTREE(0x42a00000,0x00000000)}}, {VT_exponent,22,0x3a8743,{DOUBLEWITHTWODWORDINTREE(0x42b00000,0x00000000)}}, {VT_exponent,22,0x3a8744,{DOUBLEWITHTWODWORDINTREE(0x42c00000,0x00000000)}}, {VT_exponent,22,0x3a8745,{DOUBLEWITHTWODWORDINTREE(0x42d00000,0x00000000)}}, {VT_exponent,22,0x3a8746,{DOUBLEWITHTWODWORDINTREE(0x42e00000,0x00000000)}}, {VT_exponent,22,0x3a8747,{DOUBLEWITHTWODWORDINTREE(0x42f00000,0x00000000)}}, {VT_exponent,22,0x3a8748,{DOUBLEWITHTWODWORDINTREE(0x43000000,0x00000000)}}, {VT_exponent,22,0x3a8749,{DOUBLEWITHTWODWORDINTREE(0x43100000,0x00000000)}}, {VT_exponent,22,0x3a874a,{DOUBLEWITHTWODWORDINTREE(0x43200000,0x00000000)}}, {VT_exponent,22,0x3a874b,{DOUBLEWITHTWODWORDINTREE(0x43300000,0x00000000)}}, {VT_exponent,22,0x3a874c,{DOUBLEWITHTWODWORDINTREE(0x43400000,0x00000000)}}, {VT_exponent,22,0x3a874d,{DOUBLEWITHTWODWORDINTREE(0x43500000,0x00000000)}}, {VT_exponent,22,0x3a874e,{DOUBLEWITHTWODWORDINTREE(0x43600000,0x00000000)}}, {VT_exponent,22,0x3a874f,{DOUBLEWITHTWODWORDINTREE(0x43700000,0x00000000)}}, {VT_exponent,22,0x3a8750,{DOUBLEWITHTWODWORDINTREE(0x43800000,0x00000000)}}, {VT_exponent,22,0x3a8751,{DOUBLEWITHTWODWORDINTREE(0x43900000,0x00000000)}}, {VT_exponent,22,0x3a8752,{DOUBLEWITHTWODWORDINTREE(0x43a00000,0x00000000)}}, {VT_exponent,22,0x3a8753,{DOUBLEWITHTWODWORDINTREE(0x43b00000,0x00000000)}}, {VT_exponent,22,0x3a8754,{DOUBLEWITHTWODWORDINTREE(0x43c00000,0x00000000)}}, {VT_exponent,22,0x3a8755,{DOUBLEWITHTWODWORDINTREE(0x43d00000,0x00000000)}}, {VT_exponent,22,0x3a8756,{DOUBLEWITHTWODWORDINTREE(0x43e00000,0x00000000)}}, {VT_exponent,22,0x3a8757,{DOUBLEWITHTWODWORDINTREE(0x43f00000,0x00000000)}}, {VT_exponent,22,0x3a8758,{DOUBLEWITHTWODWORDINTREE(0x44000000,0x00000000)}}, {VT_exponent,15,0x1a3b,{DOUBLEWITHTWODWORDINTREE(0x44100000,0x00000000)}}, {VT_exponent,22,0x3a8759,{DOUBLEWITHTWODWORDINTREE(0x44200000,0x00000000)}}, {VT_exponent,22,0x3a875a,{DOUBLEWITHTWODWORDINTREE(0x44300000,0x00000000)}}, {VT_exponent,22,0x3a875b,{DOUBLEWITHTWODWORDINTREE(0x44400000,0x00000000)}}, {VT_exponent,22,0x3a875c,{DOUBLEWITHTWODWORDINTREE(0x44500000,0x00000000)}}, {VT_exponent,22,0x3a875d,{DOUBLEWITHTWODWORDINTREE(0x44600000,0x00000000)}}, {VT_exponent,22,0x3a875e,{DOUBLEWITHTWODWORDINTREE(0x44700000,0x00000000)}}, {VT_exponent,22,0x3a875f,{DOUBLEWITHTWODWORDINTREE(0x44800000,0x00000000)}}, {VT_exponent,22,0x3a8760,{DOUBLEWITHTWODWORDINTREE(0x44900000,0x00000000)}}, {VT_exponent,22,0x3a8761,{DOUBLEWITHTWODWORDINTREE(0x44a00000,0x00000000)}}, {VT_exponent,22,0x3a8762,{DOUBLEWITHTWODWORDINTREE(0x44b00000,0x00000000)}}, {VT_exponent,22,0x3a8763,{DOUBLEWITHTWODWORDINTREE(0x44c00000,0x00000000)}}, {VT_exponent,22,0x3a8764,{DOUBLEWITHTWODWORDINTREE(0x44d00000,0x00000000)}}, {VT_exponent,22,0x3a8765,{DOUBLEWITHTWODWORDINTREE(0x44e00000,0x00000000)}}, {VT_exponent,22,0x3a8766,{DOUBLEWITHTWODWORDINTREE(0x44f00000,0x00000000)}}, {VT_exponent,22,0x3a8767,{DOUBLEWITHTWODWORDINTREE(0x45000000,0x00000000)}}, {VT_exponent,22,0x3a8768,{DOUBLEWITHTWODWORDINTREE(0x45100000,0x00000000)}}, {VT_exponent,22,0x3a8769,{DOUBLEWITHTWODWORDINTREE(0x45200000,0x00000000)}}, {VT_exponent,22,0x3a876a,{DOUBLEWITHTWODWORDINTREE(0x45300000,0x00000000)}}, {VT_exponent,22,0x3a876b,{DOUBLEWITHTWODWORDINTREE(0x45400000,0x00000000)}}, {VT_exponent,22,0x3a876c,{DOUBLEWITHTWODWORDINTREE(0x45500000,0x00000000)}}, {VT_exponent,22,0x3a876d,{DOUBLEWITHTWODWORDINTREE(0x45600000,0x00000000)}}, {VT_exponent,22,0x3a876e,{DOUBLEWITHTWODWORDINTREE(0x45700000,0x00000000)}}, {VT_exponent,22,0x3a876f,{DOUBLEWITHTWODWORDINTREE(0x45800000,0x00000000)}}, {VT_exponent,22,0x3a8770,{DOUBLEWITHTWODWORDINTREE(0x45900000,0x00000000)}}, {VT_exponent,22,0x3a8771,{DOUBLEWITHTWODWORDINTREE(0x45a00000,0x00000000)}}, {VT_exponent,22,0x3a8772,{DOUBLEWITHTWODWORDINTREE(0x45b00000,0x00000000)}}, {VT_exponent,22,0x3a8773,{DOUBLEWITHTWODWORDINTREE(0x45c00000,0x00000000)}}, {VT_exponent,22,0x3a8774,{DOUBLEWITHTWODWORDINTREE(0x45d00000,0x00000000)}}, {VT_exponent,22,0x3a8775,{DOUBLEWITHTWODWORDINTREE(0x45e00000,0x00000000)}}, {VT_exponent,22,0x3a8776,{DOUBLEWITHTWODWORDINTREE(0x45f00000,0x00000000)}}, {VT_exponent,22,0x3a8777,{DOUBLEWITHTWODWORDINTREE(0x46000000,0x00000000)}}, {VT_exponent,22,0x3a8778,{DOUBLEWITHTWODWORDINTREE(0x46100000,0x00000000)}}, {VT_exponent,22,0x3a8779,{DOUBLEWITHTWODWORDINTREE(0x46200000,0x00000000)}}, {VT_exponent,22,0x3a877a,{DOUBLEWITHTWODWORDINTREE(0x46300000,0x00000000)}}, {VT_exponent,22,0x3a877b,{DOUBLEWITHTWODWORDINTREE(0x46400000,0x00000000)}}, {VT_exponent,22,0x3a877c,{DOUBLEWITHTWODWORDINTREE(0x46500000,0x00000000)}}, {VT_exponent,22,0x3a877d,{DOUBLEWITHTWODWORDINTREE(0x46600000,0x00000000)}}, {VT_exponent,22,0x3a877e,{DOUBLEWITHTWODWORDINTREE(0x46700000,0x00000000)}}, {VT_exponent,22,0x3a877f,{DOUBLEWITHTWODWORDINTREE(0x46800000,0x00000000)}}, {VT_exponent,22,0x3a8780,{DOUBLEWITHTWODWORDINTREE(0x46900000,0x00000000)}}, {VT_exponent,22,0x3a8781,{DOUBLEWITHTWODWORDINTREE(0x46a00000,0x00000000)}}, {VT_exponent,22,0x3a8782,{DOUBLEWITHTWODWORDINTREE(0x46b00000,0x00000000)}}, {VT_exponent,22,0x3a8783,{DOUBLEWITHTWODWORDINTREE(0x46c00000,0x00000000)}}, {VT_exponent,22,0x3a8784,{DOUBLEWITHTWODWORDINTREE(0x46d00000,0x00000000)}}, {VT_exponent,22,0x3a8785,{DOUBLEWITHTWODWORDINTREE(0x46e00000,0x00000000)}}, {VT_exponent,22,0x3a8786,{DOUBLEWITHTWODWORDINTREE(0x46f00000,0x00000000)}}, {VT_exponent,22,0x3a8787,{DOUBLEWITHTWODWORDINTREE(0x47000000,0x00000000)}}, {VT_exponent,22,0x3a8788,{DOUBLEWITHTWODWORDINTREE(0x47100000,0x00000000)}}, {VT_exponent,22,0x3a8789,{DOUBLEWITHTWODWORDINTREE(0x47200000,0x00000000)}}, {VT_exponent,22,0x3a878a,{DOUBLEWITHTWODWORDINTREE(0x47300000,0x00000000)}}, {VT_exponent,22,0x3a878b,{DOUBLEWITHTWODWORDINTREE(0x47400000,0x00000000)}}, {VT_exponent,22,0x3a878c,{DOUBLEWITHTWODWORDINTREE(0x47500000,0x00000000)}}, {VT_exponent,22,0x3a878d,{DOUBLEWITHTWODWORDINTREE(0x47600000,0x00000000)}}, {VT_exponent,22,0x3a878e,{DOUBLEWITHTWODWORDINTREE(0x47700000,0x00000000)}}, {VT_exponent,22,0x3a878f,{DOUBLEWITHTWODWORDINTREE(0x47800000,0x00000000)}}, {VT_exponent,22,0x3a8790,{DOUBLEWITHTWODWORDINTREE(0x47900000,0x00000000)}}, {VT_exponent,22,0x3a8791,{DOUBLEWITHTWODWORDINTREE(0x47a00000,0x00000000)}}, {VT_exponent,22,0x3a8792,{DOUBLEWITHTWODWORDINTREE(0x47b00000,0x00000000)}}, {VT_exponent,22,0x3a8793,{DOUBLEWITHTWODWORDINTREE(0x47c00000,0x00000000)}}, {VT_exponent,22,0x3a8794,{DOUBLEWITHTWODWORDINTREE(0x47d00000,0x00000000)}}, {VT_exponent,22,0x3a8795,{DOUBLEWITHTWODWORDINTREE(0x47e00000,0x00000000)}}, {VT_exponent,22,0x3a8796,{DOUBLEWITHTWODWORDINTREE(0x47f00000,0x00000000)}}, {VT_exponent,22,0x3a8797,{DOUBLEWITHTWODWORDINTREE(0x48000000,0x00000000)}}, {VT_exponent,22,0x3a8798,{DOUBLEWITHTWODWORDINTREE(0x48100000,0x00000000)}}, {VT_exponent,22,0x3a8799,{DOUBLEWITHTWODWORDINTREE(0x48200000,0x00000000)}}, {VT_exponent,22,0x3a879a,{DOUBLEWITHTWODWORDINTREE(0x48300000,0x00000000)}}, {VT_exponent,22,0x3a879b,{DOUBLEWITHTWODWORDINTREE(0x48400000,0x00000000)}}, {VT_exponent,22,0x3a879c,{DOUBLEWITHTWODWORDINTREE(0x48500000,0x00000000)}}, {VT_exponent,22,0x3a879d,{DOUBLEWITHTWODWORDINTREE(0x48600000,0x00000000)}}, {VT_exponent,22,0x3a879e,{DOUBLEWITHTWODWORDINTREE(0x48700000,0x00000000)}}, {VT_exponent,22,0x3a879f,{DOUBLEWITHTWODWORDINTREE(0x48800000,0x00000000)}}, {VT_exponent,22,0x3a87a0,{DOUBLEWITHTWODWORDINTREE(0x48900000,0x00000000)}}, {VT_exponent,22,0x3a87a1,{DOUBLEWITHTWODWORDINTREE(0x48a00000,0x00000000)}}, {VT_exponent,22,0x3a87a2,{DOUBLEWITHTWODWORDINTREE(0x48b00000,0x00000000)}}, {VT_exponent,22,0x3a87a3,{DOUBLEWITHTWODWORDINTREE(0x48c00000,0x00000000)}}, {VT_exponent,22,0x3a87a4,{DOUBLEWITHTWODWORDINTREE(0x48d00000,0x00000000)}}, {VT_exponent,22,0x3a87a5,{DOUBLEWITHTWODWORDINTREE(0x48e00000,0x00000000)}}, {VT_exponent,22,0x3a87a6,{DOUBLEWITHTWODWORDINTREE(0x48f00000,0x00000000)}}, {VT_exponent,22,0x3a87a7,{DOUBLEWITHTWODWORDINTREE(0x49000000,0x00000000)}}, {VT_exponent,22,0x3a87a8,{DOUBLEWITHTWODWORDINTREE(0x49100000,0x00000000)}}, {VT_exponent,22,0x3a87a9,{DOUBLEWITHTWODWORDINTREE(0x49200000,0x00000000)}}, {VT_exponent,22,0x3a87aa,{DOUBLEWITHTWODWORDINTREE(0x49300000,0x00000000)}}, {VT_exponent,22,0x3a87ab,{DOUBLEWITHTWODWORDINTREE(0x49400000,0x00000000)}}, {VT_exponent,22,0x3a87ac,{DOUBLEWITHTWODWORDINTREE(0x49500000,0x00000000)}}, {VT_exponent,22,0x3a87ad,{DOUBLEWITHTWODWORDINTREE(0x49600000,0x00000000)}}, {VT_exponent,22,0x3a87ae,{DOUBLEWITHTWODWORDINTREE(0x49700000,0x00000000)}}, {VT_exponent,22,0x3a87af,{DOUBLEWITHTWODWORDINTREE(0x49800000,0x00000000)}}, {VT_exponent,22,0x3a87b0,{DOUBLEWITHTWODWORDINTREE(0x49900000,0x00000000)}}, {VT_exponent,22,0x3a87b1,{DOUBLEWITHTWODWORDINTREE(0x49a00000,0x00000000)}}, {VT_exponent,22,0x3a87b2,{DOUBLEWITHTWODWORDINTREE(0x49b00000,0x00000000)}}, {VT_exponent,22,0x3a87b3,{DOUBLEWITHTWODWORDINTREE(0x49c00000,0x00000000)}}, {VT_exponent,22,0x3a87b4,{DOUBLEWITHTWODWORDINTREE(0x49d00000,0x00000000)}}, {VT_exponent,22,0x3a87b5,{DOUBLEWITHTWODWORDINTREE(0x49e00000,0x00000000)}}, {VT_exponent,22,0x3a87b6,{DOUBLEWITHTWODWORDINTREE(0x49f00000,0x00000000)}}, {VT_exponent,22,0x3a87b7,{DOUBLEWITHTWODWORDINTREE(0x4a000000,0x00000000)}}, {VT_exponent,22,0x3a87b8,{DOUBLEWITHTWODWORDINTREE(0x4a100000,0x00000000)}}, {VT_exponent,22,0x3a87b9,{DOUBLEWITHTWODWORDINTREE(0x4a200000,0x00000000)}}, {VT_exponent,22,0x3a87ba,{DOUBLEWITHTWODWORDINTREE(0x4a300000,0x00000000)}}, {VT_exponent,22,0x3a87bb,{DOUBLEWITHTWODWORDINTREE(0x4a400000,0x00000000)}}, {VT_exponent,22,0x3a87bc,{DOUBLEWITHTWODWORDINTREE(0x4a500000,0x00000000)}}, {VT_exponent,22,0x3a87bd,{DOUBLEWITHTWODWORDINTREE(0x4a600000,0x00000000)}}, {VT_exponent,22,0x3a87be,{DOUBLEWITHTWODWORDINTREE(0x4a700000,0x00000000)}}, {VT_exponent,22,0x3a87bf,{DOUBLEWITHTWODWORDINTREE(0x4a800000,0x00000000)}}, {VT_exponent,22,0x3a87c0,{DOUBLEWITHTWODWORDINTREE(0x4a900000,0x00000000)}}, {VT_exponent,22,0x3a87c1,{DOUBLEWITHTWODWORDINTREE(0x4aa00000,0x00000000)}}, {VT_exponent,22,0x3a87c2,{DOUBLEWITHTWODWORDINTREE(0x4ab00000,0x00000000)}}, {VT_exponent,22,0x3a87c3,{DOUBLEWITHTWODWORDINTREE(0x4ac00000,0x00000000)}}, {VT_exponent,22,0x3a87c4,{DOUBLEWITHTWODWORDINTREE(0x4ad00000,0x00000000)}}, {VT_exponent,22,0x3a87c5,{DOUBLEWITHTWODWORDINTREE(0x4ae00000,0x00000000)}}, {VT_exponent,22,0x3a87c6,{DOUBLEWITHTWODWORDINTREE(0x4af00000,0x00000000)}}, {VT_exponent,22,0x3a87c7,{DOUBLEWITHTWODWORDINTREE(0x4b000000,0x00000000)}}, {VT_exponent,22,0x3a87c8,{DOUBLEWITHTWODWORDINTREE(0x4b100000,0x00000000)}}, {VT_exponent,22,0x3a87c9,{DOUBLEWITHTWODWORDINTREE(0x4b200000,0x00000000)}}, {VT_exponent,22,0x3a87ca,{DOUBLEWITHTWODWORDINTREE(0x4b300000,0x00000000)}}, {VT_exponent,22,0x3a87cb,{DOUBLEWITHTWODWORDINTREE(0x4b400000,0x00000000)}}, {VT_exponent,22,0x3a87cc,{DOUBLEWITHTWODWORDINTREE(0x4b500000,0x00000000)}}, {VT_exponent,22,0x3a87cd,{DOUBLEWITHTWODWORDINTREE(0x4b600000,0x00000000)}}, {VT_exponent,22,0x3a87ce,{DOUBLEWITHTWODWORDINTREE(0x4b700000,0x00000000)}}, {VT_exponent,22,0x3a87cf,{DOUBLEWITHTWODWORDINTREE(0x4b800000,0x00000000)}}, {VT_exponent,22,0x3a87d0,{DOUBLEWITHTWODWORDINTREE(0x4b900000,0x00000000)}}, {VT_exponent,22,0x3a87d1,{DOUBLEWITHTWODWORDINTREE(0x4ba00000,0x00000000)}}, {VT_exponent,22,0x3a87d2,{DOUBLEWITHTWODWORDINTREE(0x4bb00000,0x00000000)}}, {VT_exponent,22,0x3a87d3,{DOUBLEWITHTWODWORDINTREE(0x4bc00000,0x00000000)}}, {VT_exponent,22,0x3a87d4,{DOUBLEWITHTWODWORDINTREE(0x4bd00000,0x00000000)}}, {VT_exponent,22,0x3a87d5,{DOUBLEWITHTWODWORDINTREE(0x4be00000,0x00000000)}}, {VT_exponent,22,0x3a87d6,{DOUBLEWITHTWODWORDINTREE(0x4bf00000,0x00000000)}}, {VT_exponent,22,0x3a87d7,{DOUBLEWITHTWODWORDINTREE(0x4c000000,0x00000000)}}, {VT_exponent,22,0x3a87d8,{DOUBLEWITHTWODWORDINTREE(0x4c100000,0x00000000)}}, {VT_exponent,22,0x3a87d9,{DOUBLEWITHTWODWORDINTREE(0x4c200000,0x00000000)}}, {VT_exponent,22,0x3a87da,{DOUBLEWITHTWODWORDINTREE(0x4c300000,0x00000000)}}, {VT_exponent,22,0x3a87db,{DOUBLEWITHTWODWORDINTREE(0x4c400000,0x00000000)}}, {VT_exponent,22,0x3a87dc,{DOUBLEWITHTWODWORDINTREE(0x4c500000,0x00000000)}}, {VT_exponent,22,0x3a87dd,{DOUBLEWITHTWODWORDINTREE(0x4c600000,0x00000000)}}, {VT_exponent,22,0x3a87de,{DOUBLEWITHTWODWORDINTREE(0x4c700000,0x00000000)}}, {VT_exponent,22,0x3a87df,{DOUBLEWITHTWODWORDINTREE(0x4c800000,0x00000000)}}, {VT_exponent,22,0x3a87e0,{DOUBLEWITHTWODWORDINTREE(0x4c900000,0x00000000)}}, {VT_exponent,22,0x3a87e1,{DOUBLEWITHTWODWORDINTREE(0x4ca00000,0x00000000)}}, {VT_exponent,22,0x3a87e2,{DOUBLEWITHTWODWORDINTREE(0x4cb00000,0x00000000)}}, {VT_exponent,22,0x3a87e3,{DOUBLEWITHTWODWORDINTREE(0x4cc00000,0x00000000)}}, {VT_exponent,22,0x3a87e4,{DOUBLEWITHTWODWORDINTREE(0x4cd00000,0x00000000)}}, {VT_exponent,22,0x3a87e5,{DOUBLEWITHTWODWORDINTREE(0x4ce00000,0x00000000)}}, {VT_exponent,22,0x3a87e6,{DOUBLEWITHTWODWORDINTREE(0x4cf00000,0x00000000)}}, {VT_exponent,22,0x3a87e7,{DOUBLEWITHTWODWORDINTREE(0x4d000000,0x00000000)}}, {VT_exponent,22,0x3a87e8,{DOUBLEWITHTWODWORDINTREE(0x4d100000,0x00000000)}}, {VT_exponent,22,0x3a87e9,{DOUBLEWITHTWODWORDINTREE(0x4d200000,0x00000000)}}, {VT_exponent,22,0x3a87ea,{DOUBLEWITHTWODWORDINTREE(0x4d300000,0x00000000)}}, {VT_exponent,22,0x3a87eb,{DOUBLEWITHTWODWORDINTREE(0x4d400000,0x00000000)}}, {VT_exponent,22,0x3a87ec,{DOUBLEWITHTWODWORDINTREE(0x4d500000,0x00000000)}}, {VT_exponent,22,0x3a87ed,{DOUBLEWITHTWODWORDINTREE(0x4d600000,0x00000000)}}, {VT_exponent,22,0x3a87ee,{DOUBLEWITHTWODWORDINTREE(0x4d700000,0x00000000)}}, {VT_exponent,22,0x3a87ef,{DOUBLEWITHTWODWORDINTREE(0x4d800000,0x00000000)}}, {VT_exponent,22,0x3a87f0,{DOUBLEWITHTWODWORDINTREE(0x4d900000,0x00000000)}}, {VT_exponent,22,0x3a87f1,{DOUBLEWITHTWODWORDINTREE(0x4da00000,0x00000000)}}, {VT_exponent,22,0x3a87f2,{DOUBLEWITHTWODWORDINTREE(0x4db00000,0x00000000)}}, {VT_exponent,22,0x3a87f3,{DOUBLEWITHTWODWORDINTREE(0x4dc00000,0x00000000)}}, {VT_exponent,22,0x3a87f4,{DOUBLEWITHTWODWORDINTREE(0x4dd00000,0x00000000)}}, {VT_exponent,22,0x3a87f5,{DOUBLEWITHTWODWORDINTREE(0x4de00000,0x00000000)}}, {VT_exponent,22,0x3a87f6,{DOUBLEWITHTWODWORDINTREE(0x4df00000,0x00000000)}}, {VT_exponent,22,0x3a87f7,{DOUBLEWITHTWODWORDINTREE(0x4e000000,0x00000000)}}, {VT_exponent,22,0x3a87f8,{DOUBLEWITHTWODWORDINTREE(0x4e100000,0x00000000)}}, {VT_exponent,22,0x3a87f9,{DOUBLEWITHTWODWORDINTREE(0x4e200000,0x00000000)}}, {VT_exponent,22,0x3a87fa,{DOUBLEWITHTWODWORDINTREE(0x4e300000,0x00000000)}}, {VT_exponent,22,0x3a87fb,{DOUBLEWITHTWODWORDINTREE(0x4e400000,0x00000000)}}, {VT_exponent,22,0x3a87fc,{DOUBLEWITHTWODWORDINTREE(0x4e500000,0x00000000)}}, {VT_exponent,22,0x3a87fd,{DOUBLEWITHTWODWORDINTREE(0x4e600000,0x00000000)}}, {VT_exponent,22,0x3a87fe,{DOUBLEWITHTWODWORDINTREE(0x4e700000,0x00000000)}}, {VT_exponent,22,0x3a87ff,{DOUBLEWITHTWODWORDINTREE(0x4e800000,0x00000000)}}, {VT_exponent,22,0x3a9000,{DOUBLEWITHTWODWORDINTREE(0x4e900000,0x00000000)}}, {VT_exponent,22,0x3a9001,{DOUBLEWITHTWODWORDINTREE(0x4ea00000,0x00000000)}}, {VT_exponent,22,0x3a9002,{DOUBLEWITHTWODWORDINTREE(0x4eb00000,0x00000000)}}, {VT_exponent,22,0x3a9003,{DOUBLEWITHTWODWORDINTREE(0x4ec00000,0x00000000)}}, {VT_exponent,22,0x3a9004,{DOUBLEWITHTWODWORDINTREE(0x4ed00000,0x00000000)}}, {VT_exponent,22,0x3a9005,{DOUBLEWITHTWODWORDINTREE(0x4ee00000,0x00000000)}}, {VT_exponent,22,0x3a9006,{DOUBLEWITHTWODWORDINTREE(0x4ef00000,0x00000000)}}, {VT_exponent,22,0x3a9007,{DOUBLEWITHTWODWORDINTREE(0x4f000000,0x00000000)}}, {VT_exponent,22,0x3a9008,{DOUBLEWITHTWODWORDINTREE(0x4f100000,0x00000000)}}, {VT_exponent,22,0x3a9009,{DOUBLEWITHTWODWORDINTREE(0x4f200000,0x00000000)}}, {VT_exponent,22,0x3a900a,{DOUBLEWITHTWODWORDINTREE(0x4f300000,0x00000000)}}, {VT_exponent,22,0x3a900b,{DOUBLEWITHTWODWORDINTREE(0x4f400000,0x00000000)}}, {VT_exponent,22,0x3a900c,{DOUBLEWITHTWODWORDINTREE(0x4f500000,0x00000000)}}, {VT_exponent,22,0x3a900d,{DOUBLEWITHTWODWORDINTREE(0x4f600000,0x00000000)}}, {VT_exponent,22,0x3a900e,{DOUBLEWITHTWODWORDINTREE(0x4f700000,0x00000000)}}, {VT_exponent,22,0x3a900f,{DOUBLEWITHTWODWORDINTREE(0x4f800000,0x00000000)}}, {VT_exponent,22,0x3a9010,{DOUBLEWITHTWODWORDINTREE(0x4f900000,0x00000000)}}, {VT_exponent,22,0x3a9011,{DOUBLEWITHTWODWORDINTREE(0x4fa00000,0x00000000)}}, {VT_exponent,22,0x3a9012,{DOUBLEWITHTWODWORDINTREE(0x4fb00000,0x00000000)}}, {VT_exponent,22,0x3a9013,{DOUBLEWITHTWODWORDINTREE(0x4fc00000,0x00000000)}}, {VT_exponent,22,0x3a9014,{DOUBLEWITHTWODWORDINTREE(0x4fd00000,0x00000000)}}, {VT_exponent,22,0x3a9015,{DOUBLEWITHTWODWORDINTREE(0x4fe00000,0x00000000)}}, {VT_exponent,22,0x3a9016,{DOUBLEWITHTWODWORDINTREE(0x4ff00000,0x00000000)}}, {VT_exponent,22,0x3a9017,{DOUBLEWITHTWODWORDINTREE(0x50000000,0x00000000)}}, {VT_exponent,22,0x3a9018,{DOUBLEWITHTWODWORDINTREE(0x50100000,0x00000000)}}, {VT_exponent,22,0x3a9019,{DOUBLEWITHTWODWORDINTREE(0x50200000,0x00000000)}}, {VT_exponent,22,0x3a901a,{DOUBLEWITHTWODWORDINTREE(0x50300000,0x00000000)}}, {VT_exponent,22,0x3a901b,{DOUBLEWITHTWODWORDINTREE(0x50400000,0x00000000)}}, {VT_exponent,22,0x3a901c,{DOUBLEWITHTWODWORDINTREE(0x50500000,0x00000000)}}, {VT_exponent,22,0x3a901d,{DOUBLEWITHTWODWORDINTREE(0x50600000,0x00000000)}}, {VT_exponent,22,0x3a901e,{DOUBLEWITHTWODWORDINTREE(0x50700000,0x00000000)}}, {VT_exponent,22,0x3a901f,{DOUBLEWITHTWODWORDINTREE(0x50800000,0x00000000)}}, {VT_exponent,22,0x3a9020,{DOUBLEWITHTWODWORDINTREE(0x50900000,0x00000000)}}, {VT_exponent,22,0x3a9021,{DOUBLEWITHTWODWORDINTREE(0x50a00000,0x00000000)}}, {VT_exponent,22,0x3a9022,{DOUBLEWITHTWODWORDINTREE(0x50b00000,0x00000000)}}, {VT_exponent,22,0x3a9023,{DOUBLEWITHTWODWORDINTREE(0x50c00000,0x00000000)}}, {VT_exponent,22,0x3a9024,{DOUBLEWITHTWODWORDINTREE(0x50d00000,0x00000000)}}, {VT_exponent,22,0x3a9025,{DOUBLEWITHTWODWORDINTREE(0x50e00000,0x00000000)}}, {VT_exponent,22,0x3a9026,{DOUBLEWITHTWODWORDINTREE(0x50f00000,0x00000000)}}, {VT_exponent,22,0x3a9027,{DOUBLEWITHTWODWORDINTREE(0x51000000,0x00000000)}}, {VT_exponent,22,0x3a9028,{DOUBLEWITHTWODWORDINTREE(0x51100000,0x00000000)}}, {VT_exponent,22,0x3a9029,{DOUBLEWITHTWODWORDINTREE(0x51200000,0x00000000)}}, {VT_exponent,22,0x3a902a,{DOUBLEWITHTWODWORDINTREE(0x51300000,0x00000000)}}, {VT_exponent,22,0x3a902b,{DOUBLEWITHTWODWORDINTREE(0x51400000,0x00000000)}}, {VT_exponent,22,0x3a902c,{DOUBLEWITHTWODWORDINTREE(0x51500000,0x00000000)}}, {VT_exponent,22,0x3a902d,{DOUBLEWITHTWODWORDINTREE(0x51600000,0x00000000)}}, {VT_exponent,22,0x3a902e,{DOUBLEWITHTWODWORDINTREE(0x51700000,0x00000000)}}, {VT_exponent,22,0x3a902f,{DOUBLEWITHTWODWORDINTREE(0x51800000,0x00000000)}}, {VT_exponent,22,0x3a9030,{DOUBLEWITHTWODWORDINTREE(0x51900000,0x00000000)}}, {VT_exponent,22,0x3a9031,{DOUBLEWITHTWODWORDINTREE(0x51a00000,0x00000000)}}, {VT_exponent,22,0x3a9032,{DOUBLEWITHTWODWORDINTREE(0x51b00000,0x00000000)}}, {VT_exponent,22,0x3a9033,{DOUBLEWITHTWODWORDINTREE(0x51c00000,0x00000000)}}, {VT_exponent,22,0x3a9034,{DOUBLEWITHTWODWORDINTREE(0x51d00000,0x00000000)}}, {VT_exponent,22,0x3a9035,{DOUBLEWITHTWODWORDINTREE(0x51e00000,0x00000000)}}, {VT_exponent,22,0x3a9036,{DOUBLEWITHTWODWORDINTREE(0x51f00000,0x00000000)}}, {VT_exponent,22,0x3a9037,{DOUBLEWITHTWODWORDINTREE(0x52000000,0x00000000)}}, {VT_exponent,22,0x3a9038,{DOUBLEWITHTWODWORDINTREE(0x52100000,0x00000000)}}, {VT_exponent,22,0x3a9039,{DOUBLEWITHTWODWORDINTREE(0x52200000,0x00000000)}}, {VT_exponent,22,0x3a903a,{DOUBLEWITHTWODWORDINTREE(0x52300000,0x00000000)}}, {VT_exponent,22,0x3a903b,{DOUBLEWITHTWODWORDINTREE(0x52400000,0x00000000)}}, {VT_exponent,22,0x3a903c,{DOUBLEWITHTWODWORDINTREE(0x52500000,0x00000000)}}, {VT_exponent,22,0x3a903d,{DOUBLEWITHTWODWORDINTREE(0x52600000,0x00000000)}}, {VT_exponent,22,0x3a903e,{DOUBLEWITHTWODWORDINTREE(0x52700000,0x00000000)}}, {VT_exponent,22,0x3a903f,{DOUBLEWITHTWODWORDINTREE(0x52800000,0x00000000)}}, {VT_exponent,22,0x3a9040,{DOUBLEWITHTWODWORDINTREE(0x52900000,0x00000000)}}, {VT_exponent,22,0x3a9041,{DOUBLEWITHTWODWORDINTREE(0x52a00000,0x00000000)}}, {VT_exponent,22,0x3a9042,{DOUBLEWITHTWODWORDINTREE(0x52b00000,0x00000000)}}, {VT_exponent,22,0x3a9043,{DOUBLEWITHTWODWORDINTREE(0x52c00000,0x00000000)}}, {VT_exponent,22,0x3a9044,{DOUBLEWITHTWODWORDINTREE(0x52d00000,0x00000000)}}, {VT_exponent,22,0x3a9045,{DOUBLEWITHTWODWORDINTREE(0x52e00000,0x00000000)}}, {VT_exponent,22,0x3a9046,{DOUBLEWITHTWODWORDINTREE(0x52f00000,0x00000000)}}, {VT_exponent,22,0x3a9047,{DOUBLEWITHTWODWORDINTREE(0x53000000,0x00000000)}}, {VT_exponent,22,0x3a9048,{DOUBLEWITHTWODWORDINTREE(0x53100000,0x00000000)}}, {VT_exponent,22,0x3a9049,{DOUBLEWITHTWODWORDINTREE(0x53200000,0x00000000)}}, {VT_exponent,22,0x3a904a,{DOUBLEWITHTWODWORDINTREE(0x53300000,0x00000000)}}, {VT_exponent,22,0x3a904b,{DOUBLEWITHTWODWORDINTREE(0x53400000,0x00000000)}}, {VT_exponent,22,0x3a904c,{DOUBLEWITHTWODWORDINTREE(0x53500000,0x00000000)}}, {VT_exponent,22,0x3a904d,{DOUBLEWITHTWODWORDINTREE(0x53600000,0x00000000)}}, {VT_exponent,22,0x3a904e,{DOUBLEWITHTWODWORDINTREE(0x53700000,0x00000000)}}, {VT_exponent,22,0x3a904f,{DOUBLEWITHTWODWORDINTREE(0x53800000,0x00000000)}}, {VT_exponent,22,0x3a9050,{DOUBLEWITHTWODWORDINTREE(0x53900000,0x00000000)}}, {VT_exponent,22,0x3a9051,{DOUBLEWITHTWODWORDINTREE(0x53a00000,0x00000000)}}, {VT_exponent,22,0x3a9052,{DOUBLEWITHTWODWORDINTREE(0x53b00000,0x00000000)}}, {VT_exponent,22,0x3a9053,{DOUBLEWITHTWODWORDINTREE(0x53c00000,0x00000000)}}, {VT_exponent,22,0x3a9054,{DOUBLEWITHTWODWORDINTREE(0x53d00000,0x00000000)}}, {VT_exponent,22,0x3a9055,{DOUBLEWITHTWODWORDINTREE(0x53e00000,0x00000000)}}, {VT_exponent,22,0x3a9056,{DOUBLEWITHTWODWORDINTREE(0x53f00000,0x00000000)}}, {VT_exponent,22,0x3a9057,{DOUBLEWITHTWODWORDINTREE(0x54000000,0x00000000)}}, {VT_exponent,22,0x3a9058,{DOUBLEWITHTWODWORDINTREE(0x54100000,0x00000000)}}, {VT_exponent,22,0x3a9059,{DOUBLEWITHTWODWORDINTREE(0x54200000,0x00000000)}}, {VT_exponent,22,0x3a905a,{DOUBLEWITHTWODWORDINTREE(0x54300000,0x00000000)}}, {VT_exponent,22,0x3a905b,{DOUBLEWITHTWODWORDINTREE(0x54400000,0x00000000)}}, {VT_exponent,22,0x3a905c,{DOUBLEWITHTWODWORDINTREE(0x54500000,0x00000000)}}, {VT_exponent,22,0x3a905d,{DOUBLEWITHTWODWORDINTREE(0x54600000,0x00000000)}}, {VT_exponent,22,0x3a905e,{DOUBLEWITHTWODWORDINTREE(0x54700000,0x00000000)}}, {VT_exponent,22,0x3a905f,{DOUBLEWITHTWODWORDINTREE(0x54800000,0x00000000)}}, {VT_exponent,22,0x3a9060,{DOUBLEWITHTWODWORDINTREE(0x54900000,0x00000000)}}, {VT_exponent,22,0x3a9061,{DOUBLEWITHTWODWORDINTREE(0x54a00000,0x00000000)}}, {VT_exponent,22,0x3a9062,{DOUBLEWITHTWODWORDINTREE(0x54b00000,0x00000000)}}, {VT_exponent,22,0x3a9063,{DOUBLEWITHTWODWORDINTREE(0x54c00000,0x00000000)}}, {VT_exponent,22,0x3a9064,{DOUBLEWITHTWODWORDINTREE(0x54d00000,0x00000000)}}, {VT_exponent,22,0x3a9065,{DOUBLEWITHTWODWORDINTREE(0x54e00000,0x00000000)}}, {VT_exponent,22,0x3a9066,{DOUBLEWITHTWODWORDINTREE(0x54f00000,0x00000000)}}, {VT_exponent,22,0x3a9067,{DOUBLEWITHTWODWORDINTREE(0x55000000,0x00000000)}}, {VT_exponent,22,0x3a9068,{DOUBLEWITHTWODWORDINTREE(0x55100000,0x00000000)}}, {VT_exponent,22,0x3a9069,{DOUBLEWITHTWODWORDINTREE(0x55200000,0x00000000)}}, {VT_exponent,22,0x3a906a,{DOUBLEWITHTWODWORDINTREE(0x55300000,0x00000000)}}, {VT_exponent,22,0x3a906b,{DOUBLEWITHTWODWORDINTREE(0x55400000,0x00000000)}}, {VT_exponent,22,0x3a906c,{DOUBLEWITHTWODWORDINTREE(0x55500000,0x00000000)}}, {VT_exponent,22,0x3a906d,{DOUBLEWITHTWODWORDINTREE(0x55600000,0x00000000)}}, {VT_exponent,22,0x3a906e,{DOUBLEWITHTWODWORDINTREE(0x55700000,0x00000000)}}, {VT_exponent,22,0x3a906f,{DOUBLEWITHTWODWORDINTREE(0x55800000,0x00000000)}}, {VT_exponent,22,0x3a9070,{DOUBLEWITHTWODWORDINTREE(0x55900000,0x00000000)}}, {VT_exponent,22,0x3a9071,{DOUBLEWITHTWODWORDINTREE(0x55a00000,0x00000000)}}, {VT_exponent,22,0x3a9072,{DOUBLEWITHTWODWORDINTREE(0x55b00000,0x00000000)}}, {VT_exponent,22,0x3a9073,{DOUBLEWITHTWODWORDINTREE(0x55c00000,0x00000000)}}, {VT_exponent,22,0x3a9074,{DOUBLEWITHTWODWORDINTREE(0x55d00000,0x00000000)}}, {VT_exponent,22,0x3a9075,{DOUBLEWITHTWODWORDINTREE(0x55e00000,0x00000000)}}, {VT_exponent,22,0x3a9076,{DOUBLEWITHTWODWORDINTREE(0x55f00000,0x00000000)}}, {VT_exponent,22,0x3a9077,{DOUBLEWITHTWODWORDINTREE(0x56000000,0x00000000)}}, {VT_exponent,22,0x3a9078,{DOUBLEWITHTWODWORDINTREE(0x56100000,0x00000000)}}, {VT_exponent,22,0x3a9079,{DOUBLEWITHTWODWORDINTREE(0x56200000,0x00000000)}}, {VT_exponent,22,0x3a907a,{DOUBLEWITHTWODWORDINTREE(0x56300000,0x00000000)}}, {VT_exponent,22,0x3a907b,{DOUBLEWITHTWODWORDINTREE(0x56400000,0x00000000)}}, {VT_exponent,22,0x3a907c,{DOUBLEWITHTWODWORDINTREE(0x56500000,0x00000000)}}, {VT_exponent,22,0x3a907d,{DOUBLEWITHTWODWORDINTREE(0x56600000,0x00000000)}}, {VT_exponent,22,0x3a907e,{DOUBLEWITHTWODWORDINTREE(0x56700000,0x00000000)}}, {VT_exponent,22,0x3a907f,{DOUBLEWITHTWODWORDINTREE(0x56800000,0x00000000)}}, {VT_exponent,22,0x3a9080,{DOUBLEWITHTWODWORDINTREE(0x56900000,0x00000000)}}, {VT_exponent,22,0x3a9081,{DOUBLEWITHTWODWORDINTREE(0x56a00000,0x00000000)}}, {VT_exponent,22,0x3a9082,{DOUBLEWITHTWODWORDINTREE(0x56b00000,0x00000000)}}, {VT_exponent,22,0x3a9083,{DOUBLEWITHTWODWORDINTREE(0x56c00000,0x00000000)}}, {VT_exponent,22,0x3a9084,{DOUBLEWITHTWODWORDINTREE(0x56d00000,0x00000000)}}, {VT_exponent,22,0x3a9085,{DOUBLEWITHTWODWORDINTREE(0x56e00000,0x00000000)}}, {VT_exponent,22,0x3a9086,{DOUBLEWITHTWODWORDINTREE(0x56f00000,0x00000000)}}, {VT_exponent,22,0x3a9087,{DOUBLEWITHTWODWORDINTREE(0x57000000,0x00000000)}}, {VT_exponent,22,0x3a9088,{DOUBLEWITHTWODWORDINTREE(0x57100000,0x00000000)}}, {VT_exponent,22,0x3a9089,{DOUBLEWITHTWODWORDINTREE(0x57200000,0x00000000)}}, {VT_exponent,22,0x3a908a,{DOUBLEWITHTWODWORDINTREE(0x57300000,0x00000000)}}, {VT_exponent,22,0x3a908b,{DOUBLEWITHTWODWORDINTREE(0x57400000,0x00000000)}}, {VT_exponent,22,0x3a908c,{DOUBLEWITHTWODWORDINTREE(0x57500000,0x00000000)}}, {VT_exponent,22,0x3a908d,{DOUBLEWITHTWODWORDINTREE(0x57600000,0x00000000)}}, {VT_exponent,22,0x3a908e,{DOUBLEWITHTWODWORDINTREE(0x57700000,0x00000000)}}, {VT_exponent,22,0x3a908f,{DOUBLEWITHTWODWORDINTREE(0x57800000,0x00000000)}}, {VT_exponent,22,0x3a9090,{DOUBLEWITHTWODWORDINTREE(0x57900000,0x00000000)}}, {VT_exponent,22,0x3a9091,{DOUBLEWITHTWODWORDINTREE(0x57a00000,0x00000000)}}, {VT_exponent,22,0x3a9092,{DOUBLEWITHTWODWORDINTREE(0x57b00000,0x00000000)}}, {VT_exponent,22,0x3a9093,{DOUBLEWITHTWODWORDINTREE(0x57c00000,0x00000000)}}, {VT_exponent,22,0x3a9094,{DOUBLEWITHTWODWORDINTREE(0x57d00000,0x00000000)}}, {VT_exponent,22,0x3a9095,{DOUBLEWITHTWODWORDINTREE(0x57e00000,0x00000000)}}, {VT_exponent,22,0x3a9096,{DOUBLEWITHTWODWORDINTREE(0x57f00000,0x00000000)}}, {VT_exponent,22,0x3a9097,{DOUBLEWITHTWODWORDINTREE(0x58000000,0x00000000)}}, {VT_exponent,22,0x3a9098,{DOUBLEWITHTWODWORDINTREE(0x58100000,0x00000000)}}, {VT_exponent,22,0x3a9099,{DOUBLEWITHTWODWORDINTREE(0x58200000,0x00000000)}}, {VT_exponent,22,0x3a909a,{DOUBLEWITHTWODWORDINTREE(0x58300000,0x00000000)}}, {VT_exponent,22,0x3a909b,{DOUBLEWITHTWODWORDINTREE(0x58400000,0x00000000)}}, {VT_exponent,22,0x3a909c,{DOUBLEWITHTWODWORDINTREE(0x58500000,0x00000000)}}, {VT_exponent,22,0x3a909d,{DOUBLEWITHTWODWORDINTREE(0x58600000,0x00000000)}}, {VT_exponent,22,0x3a909e,{DOUBLEWITHTWODWORDINTREE(0x58700000,0x00000000)}}, {VT_exponent,22,0x3a909f,{DOUBLEWITHTWODWORDINTREE(0x58800000,0x00000000)}}, {VT_exponent,22,0x3a90a0,{DOUBLEWITHTWODWORDINTREE(0x58900000,0x00000000)}}, {VT_exponent,22,0x3a90a1,{DOUBLEWITHTWODWORDINTREE(0x58a00000,0x00000000)}}, {VT_exponent,22,0x3a90a2,{DOUBLEWITHTWODWORDINTREE(0x58b00000,0x00000000)}}, {VT_exponent,22,0x3a90a3,{DOUBLEWITHTWODWORDINTREE(0x58c00000,0x00000000)}}, {VT_exponent,22,0x3a90a4,{DOUBLEWITHTWODWORDINTREE(0x58d00000,0x00000000)}}, {VT_exponent,22,0x3a90a5,{DOUBLEWITHTWODWORDINTREE(0x58e00000,0x00000000)}}, {VT_exponent,22,0x3a90a6,{DOUBLEWITHTWODWORDINTREE(0x58f00000,0x00000000)}}, {VT_exponent,22,0x3a90a7,{DOUBLEWITHTWODWORDINTREE(0x59000000,0x00000000)}}, {VT_exponent,22,0x3a90a8,{DOUBLEWITHTWODWORDINTREE(0x59100000,0x00000000)}}, {VT_exponent,22,0x3a90a9,{DOUBLEWITHTWODWORDINTREE(0x59200000,0x00000000)}}, {VT_exponent,22,0x3a90aa,{DOUBLEWITHTWODWORDINTREE(0x59300000,0x00000000)}}, {VT_exponent,22,0x3a90ab,{DOUBLEWITHTWODWORDINTREE(0x59400000,0x00000000)}}, {VT_exponent,22,0x3a90ac,{DOUBLEWITHTWODWORDINTREE(0x59500000,0x00000000)}}, {VT_exponent,22,0x3a90ad,{DOUBLEWITHTWODWORDINTREE(0x59600000,0x00000000)}}, {VT_exponent,22,0x3a90ae,{DOUBLEWITHTWODWORDINTREE(0x59700000,0x00000000)}}, {VT_exponent,22,0x3a90af,{DOUBLEWITHTWODWORDINTREE(0x59800000,0x00000000)}}, {VT_exponent,22,0x3a90b0,{DOUBLEWITHTWODWORDINTREE(0x59900000,0x00000000)}}, {VT_exponent,22,0x3a90b1,{DOUBLEWITHTWODWORDINTREE(0x59a00000,0x00000000)}}, {VT_exponent,22,0x3a90b2,{DOUBLEWITHTWODWORDINTREE(0x59b00000,0x00000000)}}, {VT_exponent,22,0x3a90b3,{DOUBLEWITHTWODWORDINTREE(0x59c00000,0x00000000)}}, {VT_exponent,22,0x3a90b4,{DOUBLEWITHTWODWORDINTREE(0x59d00000,0x00000000)}}, {VT_exponent,22,0x3a90b5,{DOUBLEWITHTWODWORDINTREE(0x59e00000,0x00000000)}}, {VT_exponent,22,0x3a90b6,{DOUBLEWITHTWODWORDINTREE(0x59f00000,0x00000000)}}, {VT_exponent,22,0x3a90b7,{DOUBLEWITHTWODWORDINTREE(0x5a000000,0x00000000)}}, {VT_exponent,22,0x3a90b8,{DOUBLEWITHTWODWORDINTREE(0x5a100000,0x00000000)}}, {VT_exponent,22,0x3a90b9,{DOUBLEWITHTWODWORDINTREE(0x5a200000,0x00000000)}}, {VT_exponent,22,0x3a90ba,{DOUBLEWITHTWODWORDINTREE(0x5a300000,0x00000000)}}, {VT_exponent,22,0x3a90bb,{DOUBLEWITHTWODWORDINTREE(0x5a400000,0x00000000)}}, {VT_exponent,22,0x3a90bc,{DOUBLEWITHTWODWORDINTREE(0x5a500000,0x00000000)}}, {VT_exponent,22,0x3a90bd,{DOUBLEWITHTWODWORDINTREE(0x5a600000,0x00000000)}}, {VT_exponent,22,0x3a90be,{DOUBLEWITHTWODWORDINTREE(0x5a700000,0x00000000)}}, {VT_exponent,22,0x3a90bf,{DOUBLEWITHTWODWORDINTREE(0x5a800000,0x00000000)}}, {VT_exponent,22,0x3a90c0,{DOUBLEWITHTWODWORDINTREE(0x5a900000,0x00000000)}}, {VT_exponent,22,0x3a90c1,{DOUBLEWITHTWODWORDINTREE(0x5aa00000,0x00000000)}}, {VT_exponent,22,0x3a90c2,{DOUBLEWITHTWODWORDINTREE(0x5ab00000,0x00000000)}}, {VT_exponent,22,0x3a90c3,{DOUBLEWITHTWODWORDINTREE(0x5ac00000,0x00000000)}}, {VT_exponent,22,0x3a90c4,{DOUBLEWITHTWODWORDINTREE(0x5ad00000,0x00000000)}}, {VT_exponent,22,0x3a90c5,{DOUBLEWITHTWODWORDINTREE(0x5ae00000,0x00000000)}}, {VT_exponent,22,0x3a90c6,{DOUBLEWITHTWODWORDINTREE(0x5af00000,0x00000000)}}, {VT_exponent,22,0x3a90c7,{DOUBLEWITHTWODWORDINTREE(0x5b000000,0x00000000)}}, {VT_exponent,22,0x3a90c8,{DOUBLEWITHTWODWORDINTREE(0x5b100000,0x00000000)}}, {VT_exponent,22,0x3a90c9,{DOUBLEWITHTWODWORDINTREE(0x5b200000,0x00000000)}}, {VT_exponent,22,0x3a90ca,{DOUBLEWITHTWODWORDINTREE(0x5b300000,0x00000000)}}, {VT_exponent,22,0x3a90cb,{DOUBLEWITHTWODWORDINTREE(0x5b400000,0x00000000)}}, {VT_exponent,22,0x3a90cc,{DOUBLEWITHTWODWORDINTREE(0x5b500000,0x00000000)}}, {VT_exponent,22,0x3a90cd,{DOUBLEWITHTWODWORDINTREE(0x5b600000,0x00000000)}}, {VT_exponent,22,0x3a90ce,{DOUBLEWITHTWODWORDINTREE(0x5b700000,0x00000000)}}, {VT_exponent,22,0x3a90cf,{DOUBLEWITHTWODWORDINTREE(0x5b800000,0x00000000)}}, {VT_exponent,22,0x3a90d0,{DOUBLEWITHTWODWORDINTREE(0x5b900000,0x00000000)}}, {VT_exponent,22,0x3a90d1,{DOUBLEWITHTWODWORDINTREE(0x5ba00000,0x00000000)}}, {VT_exponent,22,0x3a90d2,{DOUBLEWITHTWODWORDINTREE(0x5bb00000,0x00000000)}}, {VT_exponent,22,0x3a90d3,{DOUBLEWITHTWODWORDINTREE(0x5bc00000,0x00000000)}}, {VT_exponent,22,0x3a90d4,{DOUBLEWITHTWODWORDINTREE(0x5bd00000,0x00000000)}}, {VT_exponent,22,0x3a90d5,{DOUBLEWITHTWODWORDINTREE(0x5be00000,0x00000000)}}, {VT_exponent,22,0x3a90d6,{DOUBLEWITHTWODWORDINTREE(0x5bf00000,0x00000000)}}, {VT_exponent,22,0x3a90d7,{DOUBLEWITHTWODWORDINTREE(0x5c000000,0x00000000)}}, {VT_exponent,22,0x3a90d8,{DOUBLEWITHTWODWORDINTREE(0x5c100000,0x00000000)}}, {VT_exponent,22,0x3a90d9,{DOUBLEWITHTWODWORDINTREE(0x5c200000,0x00000000)}}, {VT_exponent,22,0x3a90da,{DOUBLEWITHTWODWORDINTREE(0x5c300000,0x00000000)}}, {VT_exponent,22,0x3a90db,{DOUBLEWITHTWODWORDINTREE(0x5c400000,0x00000000)}}, {VT_exponent,22,0x3a90dc,{DOUBLEWITHTWODWORDINTREE(0x5c500000,0x00000000)}}, {VT_exponent,22,0x3a90dd,{DOUBLEWITHTWODWORDINTREE(0x5c600000,0x00000000)}}, {VT_exponent,22,0x3a90de,{DOUBLEWITHTWODWORDINTREE(0x5c700000,0x00000000)}}, {VT_exponent,22,0x3a90df,{DOUBLEWITHTWODWORDINTREE(0x5c800000,0x00000000)}}, {VT_exponent,22,0x3a90e0,{DOUBLEWITHTWODWORDINTREE(0x5c900000,0x00000000)}}, {VT_exponent,22,0x3a90e1,{DOUBLEWITHTWODWORDINTREE(0x5ca00000,0x00000000)}}, {VT_exponent,22,0x3a90e2,{DOUBLEWITHTWODWORDINTREE(0x5cb00000,0x00000000)}}, {VT_exponent,22,0x3a90e3,{DOUBLEWITHTWODWORDINTREE(0x5cc00000,0x00000000)}}, {VT_exponent,22,0x3a90e4,{DOUBLEWITHTWODWORDINTREE(0x5cd00000,0x00000000)}}, {VT_exponent,22,0x3a90e5,{DOUBLEWITHTWODWORDINTREE(0x5ce00000,0x00000000)}}, {VT_exponent,22,0x3a90e6,{DOUBLEWITHTWODWORDINTREE(0x5cf00000,0x00000000)}}, {VT_exponent,22,0x3a90e7,{DOUBLEWITHTWODWORDINTREE(0x5d000000,0x00000000)}}, {VT_exponent,22,0x3a90e8,{DOUBLEWITHTWODWORDINTREE(0x5d100000,0x00000000)}}, {VT_exponent,22,0x3a90e9,{DOUBLEWITHTWODWORDINTREE(0x5d200000,0x00000000)}}, {VT_exponent,22,0x3a90ea,{DOUBLEWITHTWODWORDINTREE(0x5d300000,0x00000000)}}, {VT_exponent,22,0x3a90eb,{DOUBLEWITHTWODWORDINTREE(0x5d400000,0x00000000)}}, {VT_exponent,22,0x3a90ec,{DOUBLEWITHTWODWORDINTREE(0x5d500000,0x00000000)}}, {VT_exponent,22,0x3a90ed,{DOUBLEWITHTWODWORDINTREE(0x5d600000,0x00000000)}}, {VT_exponent,22,0x3a90ee,{DOUBLEWITHTWODWORDINTREE(0x5d700000,0x00000000)}}, {VT_exponent,22,0x3a90ef,{DOUBLEWITHTWODWORDINTREE(0x5d800000,0x00000000)}}, {VT_exponent,22,0x3a90f0,{DOUBLEWITHTWODWORDINTREE(0x5d900000,0x00000000)}}, {VT_exponent,22,0x3a90f1,{DOUBLEWITHTWODWORDINTREE(0x5da00000,0x00000000)}}, {VT_exponent,22,0x3a90f2,{DOUBLEWITHTWODWORDINTREE(0x5db00000,0x00000000)}}, {VT_exponent,22,0x3a90f3,{DOUBLEWITHTWODWORDINTREE(0x5dc00000,0x00000000)}}, {VT_exponent,22,0x3a90f4,{DOUBLEWITHTWODWORDINTREE(0x5dd00000,0x00000000)}}, {VT_exponent,22,0x3a90f5,{DOUBLEWITHTWODWORDINTREE(0x5de00000,0x00000000)}}, {VT_exponent,22,0x3a90f6,{DOUBLEWITHTWODWORDINTREE(0x5df00000,0x00000000)}}, {VT_exponent,22,0x3a90f7,{DOUBLEWITHTWODWORDINTREE(0x5e000000,0x00000000)}}, {VT_exponent,22,0x3a90f8,{DOUBLEWITHTWODWORDINTREE(0x5e100000,0x00000000)}}, {VT_exponent,22,0x3a90f9,{DOUBLEWITHTWODWORDINTREE(0x5e200000,0x00000000)}}, {VT_exponent,22,0x3a90fa,{DOUBLEWITHTWODWORDINTREE(0x5e300000,0x00000000)}}, {VT_exponent,22,0x3a90fb,{DOUBLEWITHTWODWORDINTREE(0x5e400000,0x00000000)}}, {VT_exponent,22,0x3a90fc,{DOUBLEWITHTWODWORDINTREE(0x5e500000,0x00000000)}}, {VT_exponent,22,0x3a90fd,{DOUBLEWITHTWODWORDINTREE(0x5e600000,0x00000000)}}, {VT_exponent,22,0x3a90fe,{DOUBLEWITHTWODWORDINTREE(0x5e700000,0x00000000)}}, {VT_exponent,22,0x3a90ff,{DOUBLEWITHTWODWORDINTREE(0x5e800000,0x00000000)}}, {VT_exponent,22,0x3a9100,{DOUBLEWITHTWODWORDINTREE(0x5e900000,0x00000000)}}, {VT_exponent,22,0x3a9101,{DOUBLEWITHTWODWORDINTREE(0x5ea00000,0x00000000)}}, {VT_exponent,22,0x3a9102,{DOUBLEWITHTWODWORDINTREE(0x5eb00000,0x00000000)}}, {VT_exponent,22,0x3a9103,{DOUBLEWITHTWODWORDINTREE(0x5ec00000,0x00000000)}}, {VT_exponent,22,0x3a9104,{DOUBLEWITHTWODWORDINTREE(0x5ed00000,0x00000000)}}, {VT_exponent,22,0x3a9105,{DOUBLEWITHTWODWORDINTREE(0x5ee00000,0x00000000)}}, {VT_exponent,22,0x3a9106,{DOUBLEWITHTWODWORDINTREE(0x5ef00000,0x00000000)}}, {VT_exponent,22,0x3a9107,{DOUBLEWITHTWODWORDINTREE(0x5f000000,0x00000000)}}, {VT_exponent,22,0x3a9108,{DOUBLEWITHTWODWORDINTREE(0x5f100000,0x00000000)}}, {VT_exponent,22,0x3a9109,{DOUBLEWITHTWODWORDINTREE(0x5f200000,0x00000000)}}, {VT_exponent,22,0x3a910a,{DOUBLEWITHTWODWORDINTREE(0x5f300000,0x00000000)}}, {VT_exponent,22,0x3a910b,{DOUBLEWITHTWODWORDINTREE(0x5f400000,0x00000000)}}, {VT_exponent,22,0x3a910c,{DOUBLEWITHTWODWORDINTREE(0x5f500000,0x00000000)}}, {VT_exponent,22,0x3a910d,{DOUBLEWITHTWODWORDINTREE(0x5f600000,0x00000000)}}, {VT_exponent,22,0x3a910e,{DOUBLEWITHTWODWORDINTREE(0x5f700000,0x00000000)}}, {VT_exponent,22,0x3a910f,{DOUBLEWITHTWODWORDINTREE(0x5f800000,0x00000000)}}, {VT_exponent,22,0x3a9110,{DOUBLEWITHTWODWORDINTREE(0x5f900000,0x00000000)}}, {VT_exponent,22,0x3a9111,{DOUBLEWITHTWODWORDINTREE(0x5fa00000,0x00000000)}}, {VT_exponent,22,0x3a9112,{DOUBLEWITHTWODWORDINTREE(0x5fb00000,0x00000000)}}, {VT_exponent,22,0x3a9113,{DOUBLEWITHTWODWORDINTREE(0x5fc00000,0x00000000)}}, {VT_exponent,22,0x3a9114,{DOUBLEWITHTWODWORDINTREE(0x5fd00000,0x00000000)}}, {VT_exponent,22,0x3a9115,{DOUBLEWITHTWODWORDINTREE(0x5fe00000,0x00000000)}}, {VT_exponent,22,0x3a9116,{DOUBLEWITHTWODWORDINTREE(0x5ff00000,0x00000000)}}, {VT_exponent,22,0x3a9117,{DOUBLEWITHTWODWORDINTREE(0x60000000,0x00000000)}}, {VT_exponent,22,0x3a9118,{DOUBLEWITHTWODWORDINTREE(0x60100000,0x00000000)}}, {VT_exponent,22,0x3a9119,{DOUBLEWITHTWODWORDINTREE(0x60200000,0x00000000)}}, {VT_exponent,22,0x3a911a,{DOUBLEWITHTWODWORDINTREE(0x60300000,0x00000000)}}, {VT_exponent,22,0x3a911b,{DOUBLEWITHTWODWORDINTREE(0x60400000,0x00000000)}}, {VT_exponent,22,0x3a911c,{DOUBLEWITHTWODWORDINTREE(0x60500000,0x00000000)}}, {VT_exponent,22,0x3a911d,{DOUBLEWITHTWODWORDINTREE(0x60600000,0x00000000)}}, {VT_exponent,22,0x3a911e,{DOUBLEWITHTWODWORDINTREE(0x60700000,0x00000000)}}, {VT_exponent,22,0x3a911f,{DOUBLEWITHTWODWORDINTREE(0x60800000,0x00000000)}}, {VT_exponent,22,0x3a9120,{DOUBLEWITHTWODWORDINTREE(0x60900000,0x00000000)}}, {VT_exponent,22,0x3a9121,{DOUBLEWITHTWODWORDINTREE(0x60a00000,0x00000000)}}, {VT_exponent,22,0x3a9122,{DOUBLEWITHTWODWORDINTREE(0x60b00000,0x00000000)}}, {VT_exponent,22,0x3a9123,{DOUBLEWITHTWODWORDINTREE(0x60c00000,0x00000000)}}, {VT_exponent,22,0x3a9124,{DOUBLEWITHTWODWORDINTREE(0x60d00000,0x00000000)}}, {VT_exponent,22,0x3a9125,{DOUBLEWITHTWODWORDINTREE(0x60e00000,0x00000000)}}, {VT_exponent,22,0x3a9126,{DOUBLEWITHTWODWORDINTREE(0x60f00000,0x00000000)}}, {VT_exponent,22,0x3a9127,{DOUBLEWITHTWODWORDINTREE(0x61000000,0x00000000)}}, {VT_exponent,22,0x3a9128,{DOUBLEWITHTWODWORDINTREE(0x61100000,0x00000000)}}, {VT_exponent,22,0x3a9129,{DOUBLEWITHTWODWORDINTREE(0x61200000,0x00000000)}}, {VT_exponent,22,0x3a912a,{DOUBLEWITHTWODWORDINTREE(0x61300000,0x00000000)}}, {VT_exponent,22,0x3a912b,{DOUBLEWITHTWODWORDINTREE(0x61400000,0x00000000)}}, {VT_exponent,22,0x3a912c,{DOUBLEWITHTWODWORDINTREE(0x61500000,0x00000000)}}, {VT_exponent,22,0x3a912d,{DOUBLEWITHTWODWORDINTREE(0x61600000,0x00000000)}}, {VT_exponent,22,0x3a912e,{DOUBLEWITHTWODWORDINTREE(0x61700000,0x00000000)}}, {VT_exponent,22,0x3a912f,{DOUBLEWITHTWODWORDINTREE(0x61800000,0x00000000)}}, {VT_exponent,22,0x3a9130,{DOUBLEWITHTWODWORDINTREE(0x61900000,0x00000000)}}, {VT_exponent,22,0x3a9131,{DOUBLEWITHTWODWORDINTREE(0x61a00000,0x00000000)}}, {VT_exponent,22,0x3a9132,{DOUBLEWITHTWODWORDINTREE(0x61b00000,0x00000000)}}, {VT_exponent,22,0x3a9133,{DOUBLEWITHTWODWORDINTREE(0x61c00000,0x00000000)}}, {VT_exponent,22,0x3a9134,{DOUBLEWITHTWODWORDINTREE(0x61d00000,0x00000000)}}, {VT_exponent,22,0x3a9135,{DOUBLEWITHTWODWORDINTREE(0x61e00000,0x00000000)}}, {VT_exponent,22,0x3a9136,{DOUBLEWITHTWODWORDINTREE(0x61f00000,0x00000000)}}, {VT_exponent,22,0x3a9137,{DOUBLEWITHTWODWORDINTREE(0x62000000,0x00000000)}}, {VT_exponent,22,0x3a9138,{DOUBLEWITHTWODWORDINTREE(0x62100000,0x00000000)}}, {VT_exponent,22,0x3a9139,{DOUBLEWITHTWODWORDINTREE(0x62200000,0x00000000)}}, {VT_exponent,22,0x3a913a,{DOUBLEWITHTWODWORDINTREE(0x62300000,0x00000000)}}, {VT_exponent,22,0x3a913b,{DOUBLEWITHTWODWORDINTREE(0x62400000,0x00000000)}}, {VT_exponent,22,0x3a913c,{DOUBLEWITHTWODWORDINTREE(0x62500000,0x00000000)}}, {VT_exponent,22,0x3a913d,{DOUBLEWITHTWODWORDINTREE(0x62600000,0x00000000)}}, {VT_exponent,22,0x3a913e,{DOUBLEWITHTWODWORDINTREE(0x62700000,0x00000000)}}, {VT_exponent,22,0x3a913f,{DOUBLEWITHTWODWORDINTREE(0x62800000,0x00000000)}}, {VT_exponent,22,0x3a9140,{DOUBLEWITHTWODWORDINTREE(0x62900000,0x00000000)}}, {VT_exponent,22,0x3a9141,{DOUBLEWITHTWODWORDINTREE(0x62a00000,0x00000000)}}, {VT_exponent,22,0x3a9142,{DOUBLEWITHTWODWORDINTREE(0x62b00000,0x00000000)}}, {VT_exponent,22,0x3a9143,{DOUBLEWITHTWODWORDINTREE(0x62c00000,0x00000000)}}, {VT_exponent,22,0x3a9144,{DOUBLEWITHTWODWORDINTREE(0x62d00000,0x00000000)}}, {VT_exponent,22,0x3a9145,{DOUBLEWITHTWODWORDINTREE(0x62e00000,0x00000000)}}, {VT_exponent,22,0x3a9146,{DOUBLEWITHTWODWORDINTREE(0x62f00000,0x00000000)}}, {VT_exponent,22,0x3a9147,{DOUBLEWITHTWODWORDINTREE(0x63000000,0x00000000)}}, {VT_exponent,22,0x3a9148,{DOUBLEWITHTWODWORDINTREE(0x63100000,0x00000000)}}, {VT_exponent,22,0x3a9149,{DOUBLEWITHTWODWORDINTREE(0x63200000,0x00000000)}}, {VT_exponent,22,0x3a914a,{DOUBLEWITHTWODWORDINTREE(0x63300000,0x00000000)}}, {VT_exponent,22,0x3a914b,{DOUBLEWITHTWODWORDINTREE(0x63400000,0x00000000)}}, {VT_exponent,22,0x3a914c,{DOUBLEWITHTWODWORDINTREE(0x63500000,0x00000000)}}, {VT_exponent,22,0x3a914d,{DOUBLEWITHTWODWORDINTREE(0x63600000,0x00000000)}}, {VT_exponent,22,0x3a914e,{DOUBLEWITHTWODWORDINTREE(0x63700000,0x00000000)}}, {VT_exponent,22,0x3a914f,{DOUBLEWITHTWODWORDINTREE(0x63800000,0x00000000)}}, {VT_exponent,22,0x3a9150,{DOUBLEWITHTWODWORDINTREE(0x63900000,0x00000000)}}, {VT_exponent,22,0x3a9151,{DOUBLEWITHTWODWORDINTREE(0x63a00000,0x00000000)}}, {VT_exponent,22,0x3a9152,{DOUBLEWITHTWODWORDINTREE(0x63b00000,0x00000000)}}, {VT_exponent,22,0x3a9153,{DOUBLEWITHTWODWORDINTREE(0x63c00000,0x00000000)}}, {VT_exponent,22,0x3a9154,{DOUBLEWITHTWODWORDINTREE(0x63d00000,0x00000000)}}, {VT_exponent,22,0x3a9155,{DOUBLEWITHTWODWORDINTREE(0x63e00000,0x00000000)}}, {VT_exponent,22,0x3a9156,{DOUBLEWITHTWODWORDINTREE(0x63f00000,0x00000000)}}, {VT_exponent,22,0x3a9157,{DOUBLEWITHTWODWORDINTREE(0x64000000,0x00000000)}}, {VT_exponent,22,0x3a9158,{DOUBLEWITHTWODWORDINTREE(0x64100000,0x00000000)}}, {VT_exponent,22,0x3a9159,{DOUBLEWITHTWODWORDINTREE(0x64200000,0x00000000)}}, {VT_exponent,22,0x3a915a,{DOUBLEWITHTWODWORDINTREE(0x64300000,0x00000000)}}, {VT_exponent,22,0x3a915b,{DOUBLEWITHTWODWORDINTREE(0x64400000,0x00000000)}}, {VT_exponent,22,0x3a915c,{DOUBLEWITHTWODWORDINTREE(0x64500000,0x00000000)}}, {VT_exponent,22,0x3a915d,{DOUBLEWITHTWODWORDINTREE(0x64600000,0x00000000)}}, {VT_exponent,22,0x3a915e,{DOUBLEWITHTWODWORDINTREE(0x64700000,0x00000000)}}, {VT_exponent,22,0x3a915f,{DOUBLEWITHTWODWORDINTREE(0x64800000,0x00000000)}}, {VT_exponent,22,0x3a9160,{DOUBLEWITHTWODWORDINTREE(0x64900000,0x00000000)}}, {VT_exponent,22,0x3a9161,{DOUBLEWITHTWODWORDINTREE(0x64a00000,0x00000000)}}, {VT_exponent,22,0x3a9162,{DOUBLEWITHTWODWORDINTREE(0x64b00000,0x00000000)}}, {VT_exponent,22,0x3a9163,{DOUBLEWITHTWODWORDINTREE(0x64c00000,0x00000000)}}, {VT_exponent,22,0x3a9164,{DOUBLEWITHTWODWORDINTREE(0x64d00000,0x00000000)}}, {VT_exponent,22,0x3a9165,{DOUBLEWITHTWODWORDINTREE(0x64e00000,0x00000000)}}, {VT_exponent,22,0x3a9166,{DOUBLEWITHTWODWORDINTREE(0x64f00000,0x00000000)}}, {VT_exponent,22,0x3a9167,{DOUBLEWITHTWODWORDINTREE(0x65000000,0x00000000)}}, {VT_exponent,22,0x3a9168,{DOUBLEWITHTWODWORDINTREE(0x65100000,0x00000000)}}, {VT_exponent,22,0x3a9169,{DOUBLEWITHTWODWORDINTREE(0x65200000,0x00000000)}}, {VT_exponent,22,0x3a916a,{DOUBLEWITHTWODWORDINTREE(0x65300000,0x00000000)}}, {VT_exponent,22,0x3a916b,{DOUBLEWITHTWODWORDINTREE(0x65400000,0x00000000)}}, {VT_exponent,22,0x3a916c,{DOUBLEWITHTWODWORDINTREE(0x65500000,0x00000000)}}, {VT_exponent,22,0x3a916d,{DOUBLEWITHTWODWORDINTREE(0x65600000,0x00000000)}}, {VT_exponent,22,0x3a916e,{DOUBLEWITHTWODWORDINTREE(0x65700000,0x00000000)}}, {VT_exponent,22,0x3a916f,{DOUBLEWITHTWODWORDINTREE(0x65800000,0x00000000)}}, {VT_exponent,22,0x3a9170,{DOUBLEWITHTWODWORDINTREE(0x65900000,0x00000000)}}, {VT_exponent,22,0x3a9171,{DOUBLEWITHTWODWORDINTREE(0x65a00000,0x00000000)}}, {VT_exponent,22,0x3a9172,{DOUBLEWITHTWODWORDINTREE(0x65b00000,0x00000000)}}, {VT_exponent,22,0x3a9173,{DOUBLEWITHTWODWORDINTREE(0x65c00000,0x00000000)}}, {VT_exponent,22,0x3a9174,{DOUBLEWITHTWODWORDINTREE(0x65d00000,0x00000000)}}, {VT_exponent,22,0x3a9175,{DOUBLEWITHTWODWORDINTREE(0x65e00000,0x00000000)}}, {VT_exponent,22,0x3a9176,{DOUBLEWITHTWODWORDINTREE(0x65f00000,0x00000000)}}, {VT_exponent,22,0x3a9177,{DOUBLEWITHTWODWORDINTREE(0x66000000,0x00000000)}}, {VT_exponent,22,0x3a9178,{DOUBLEWITHTWODWORDINTREE(0x66100000,0x00000000)}}, {VT_exponent,22,0x3a9179,{DOUBLEWITHTWODWORDINTREE(0x66200000,0x00000000)}}, {VT_exponent,22,0x3a917a,{DOUBLEWITHTWODWORDINTREE(0x66300000,0x00000000)}}, {VT_exponent,22,0x3a917b,{DOUBLEWITHTWODWORDINTREE(0x66400000,0x00000000)}}, {VT_exponent,22,0x3a917c,{DOUBLEWITHTWODWORDINTREE(0x66500000,0x00000000)}}, {VT_exponent,22,0x3a917d,{DOUBLEWITHTWODWORDINTREE(0x66600000,0x00000000)}}, {VT_exponent,22,0x3a917e,{DOUBLEWITHTWODWORDINTREE(0x66700000,0x00000000)}}, {VT_exponent,22,0x3a917f,{DOUBLEWITHTWODWORDINTREE(0x66800000,0x00000000)}}, {VT_exponent,22,0x3a9180,{DOUBLEWITHTWODWORDINTREE(0x66900000,0x00000000)}}, {VT_exponent,22,0x3a9181,{DOUBLEWITHTWODWORDINTREE(0x66a00000,0x00000000)}}, {VT_exponent,22,0x3a9182,{DOUBLEWITHTWODWORDINTREE(0x66b00000,0x00000000)}}, {VT_exponent,22,0x3a9183,{DOUBLEWITHTWODWORDINTREE(0x66c00000,0x00000000)}}, {VT_exponent,22,0x3a9184,{DOUBLEWITHTWODWORDINTREE(0x66d00000,0x00000000)}}, {VT_exponent,22,0x3a9185,{DOUBLEWITHTWODWORDINTREE(0x66e00000,0x00000000)}}, {VT_exponent,22,0x3a9186,{DOUBLEWITHTWODWORDINTREE(0x66f00000,0x00000000)}}, {VT_exponent,22,0x3a9187,{DOUBLEWITHTWODWORDINTREE(0x67000000,0x00000000)}}, {VT_exponent,22,0x3a9188,{DOUBLEWITHTWODWORDINTREE(0x67100000,0x00000000)}}, {VT_exponent,22,0x3a9189,{DOUBLEWITHTWODWORDINTREE(0x67200000,0x00000000)}}, {VT_exponent,22,0x3a918a,{DOUBLEWITHTWODWORDINTREE(0x67300000,0x00000000)}}, {VT_exponent,22,0x3a918b,{DOUBLEWITHTWODWORDINTREE(0x67400000,0x00000000)}}, {VT_exponent,22,0x3a918c,{DOUBLEWITHTWODWORDINTREE(0x67500000,0x00000000)}}, {VT_exponent,22,0x3a918d,{DOUBLEWITHTWODWORDINTREE(0x67600000,0x00000000)}}, {VT_exponent,22,0x3a918e,{DOUBLEWITHTWODWORDINTREE(0x67700000,0x00000000)}}, {VT_exponent,22,0x3a918f,{DOUBLEWITHTWODWORDINTREE(0x67800000,0x00000000)}}, {VT_exponent,22,0x3a9190,{DOUBLEWITHTWODWORDINTREE(0x67900000,0x00000000)}}, {VT_exponent,22,0x3a9191,{DOUBLEWITHTWODWORDINTREE(0x67a00000,0x00000000)}}, {VT_exponent,22,0x3a9192,{DOUBLEWITHTWODWORDINTREE(0x67b00000,0x00000000)}}, {VT_exponent,22,0x3a9193,{DOUBLEWITHTWODWORDINTREE(0x67c00000,0x00000000)}}, {VT_exponent,22,0x3a9194,{DOUBLEWITHTWODWORDINTREE(0x67d00000,0x00000000)}}, {VT_exponent,22,0x3a9195,{DOUBLEWITHTWODWORDINTREE(0x67e00000,0x00000000)}}, {VT_exponent,22,0x3a9196,{DOUBLEWITHTWODWORDINTREE(0x67f00000,0x00000000)}}, {VT_exponent,22,0x3a9197,{DOUBLEWITHTWODWORDINTREE(0x68000000,0x00000000)}}, {VT_exponent,22,0x3a9198,{DOUBLEWITHTWODWORDINTREE(0x68100000,0x00000000)}}, {VT_exponent,22,0x3a9199,{DOUBLEWITHTWODWORDINTREE(0x68200000,0x00000000)}}, {VT_exponent,22,0x3a919a,{DOUBLEWITHTWODWORDINTREE(0x68300000,0x00000000)}}, {VT_exponent,22,0x3a919b,{DOUBLEWITHTWODWORDINTREE(0x68400000,0x00000000)}}, {VT_exponent,22,0x3a919c,{DOUBLEWITHTWODWORDINTREE(0x68500000,0x00000000)}}, {VT_exponent,22,0x3a919d,{DOUBLEWITHTWODWORDINTREE(0x68600000,0x00000000)}}, {VT_exponent,22,0x3a919e,{DOUBLEWITHTWODWORDINTREE(0x68700000,0x00000000)}}, {VT_exponent,22,0x3a919f,{DOUBLEWITHTWODWORDINTREE(0x68800000,0x00000000)}}, {VT_exponent,22,0x3a91a0,{DOUBLEWITHTWODWORDINTREE(0x68900000,0x00000000)}}, {VT_exponent,22,0x3a91a1,{DOUBLEWITHTWODWORDINTREE(0x68a00000,0x00000000)}}, {VT_exponent,22,0x3a91a2,{DOUBLEWITHTWODWORDINTREE(0x68b00000,0x00000000)}}, {VT_exponent,22,0x3a91a3,{DOUBLEWITHTWODWORDINTREE(0x68c00000,0x00000000)}}, {VT_exponent,22,0x3a91a4,{DOUBLEWITHTWODWORDINTREE(0x68d00000,0x00000000)}}, {VT_exponent,22,0x3a91a5,{DOUBLEWITHTWODWORDINTREE(0x68e00000,0x00000000)}}, {VT_exponent,22,0x3a91a6,{DOUBLEWITHTWODWORDINTREE(0x68f00000,0x00000000)}}, {VT_exponent,22,0x3a91a7,{DOUBLEWITHTWODWORDINTREE(0x69000000,0x00000000)}}, {VT_exponent,22,0x3a91a8,{DOUBLEWITHTWODWORDINTREE(0x69100000,0x00000000)}}, {VT_exponent,22,0x3a91a9,{DOUBLEWITHTWODWORDINTREE(0x69200000,0x00000000)}}, {VT_exponent,22,0x3a91aa,{DOUBLEWITHTWODWORDINTREE(0x69300000,0x00000000)}}, {VT_exponent,22,0x3a91ab,{DOUBLEWITHTWODWORDINTREE(0x69400000,0x00000000)}}, {VT_exponent,22,0x3a91ac,{DOUBLEWITHTWODWORDINTREE(0x69500000,0x00000000)}}, {VT_exponent,22,0x3a91ad,{DOUBLEWITHTWODWORDINTREE(0x69600000,0x00000000)}}, {VT_exponent,22,0x3a91ae,{DOUBLEWITHTWODWORDINTREE(0x69700000,0x00000000)}}, {VT_exponent,22,0x3a91af,{DOUBLEWITHTWODWORDINTREE(0x69800000,0x00000000)}}, {VT_exponent,22,0x3a91b0,{DOUBLEWITHTWODWORDINTREE(0x69900000,0x00000000)}}, {VT_exponent,22,0x3a91b1,{DOUBLEWITHTWODWORDINTREE(0x69a00000,0x00000000)}}, {VT_exponent,22,0x3a91b2,{DOUBLEWITHTWODWORDINTREE(0x69b00000,0x00000000)}}, {VT_exponent,22,0x3a91b3,{DOUBLEWITHTWODWORDINTREE(0x69c00000,0x00000000)}}, {VT_exponent,22,0x3a91b4,{DOUBLEWITHTWODWORDINTREE(0x69d00000,0x00000000)}}, {VT_exponent,22,0x3a91b5,{DOUBLEWITHTWODWORDINTREE(0x69e00000,0x00000000)}}, {VT_exponent,22,0x3a91b6,{DOUBLEWITHTWODWORDINTREE(0x69f00000,0x00000000)}}, {VT_exponent,22,0x3a91b7,{DOUBLEWITHTWODWORDINTREE(0x6a000000,0x00000000)}}, {VT_exponent,22,0x3a91b8,{DOUBLEWITHTWODWORDINTREE(0x6a100000,0x00000000)}}, {VT_exponent,22,0x3a91b9,{DOUBLEWITHTWODWORDINTREE(0x6a200000,0x00000000)}}, {VT_exponent,22,0x3a91ba,{DOUBLEWITHTWODWORDINTREE(0x6a300000,0x00000000)}}, {VT_exponent,22,0x3a91bb,{DOUBLEWITHTWODWORDINTREE(0x6a400000,0x00000000)}}, {VT_exponent,22,0x3a91bc,{DOUBLEWITHTWODWORDINTREE(0x6a500000,0x00000000)}}, {VT_exponent,22,0x3a91bd,{DOUBLEWITHTWODWORDINTREE(0x6a600000,0x00000000)}}, {VT_exponent,22,0x3a91be,{DOUBLEWITHTWODWORDINTREE(0x6a700000,0x00000000)}}, {VT_exponent,22,0x3a91bf,{DOUBLEWITHTWODWORDINTREE(0x6a800000,0x00000000)}}, {VT_exponent,22,0x3a91c0,{DOUBLEWITHTWODWORDINTREE(0x6a900000,0x00000000)}}, {VT_exponent,22,0x3a91c1,{DOUBLEWITHTWODWORDINTREE(0x6aa00000,0x00000000)}}, {VT_exponent,22,0x3a91c2,{DOUBLEWITHTWODWORDINTREE(0x6ab00000,0x00000000)}}, {VT_exponent,22,0x3a91c3,{DOUBLEWITHTWODWORDINTREE(0x6ac00000,0x00000000)}}, {VT_exponent,22,0x3a91c4,{DOUBLEWITHTWODWORDINTREE(0x6ad00000,0x00000000)}}, {VT_exponent,22,0x3a91c5,{DOUBLEWITHTWODWORDINTREE(0x6ae00000,0x00000000)}}, {VT_exponent,22,0x3a91c6,{DOUBLEWITHTWODWORDINTREE(0x6af00000,0x00000000)}}, {VT_exponent,22,0x3a91c7,{DOUBLEWITHTWODWORDINTREE(0x6b000000,0x00000000)}}, {VT_exponent,22,0x3a91c8,{DOUBLEWITHTWODWORDINTREE(0x6b100000,0x00000000)}}, {VT_exponent,22,0x3a91c9,{DOUBLEWITHTWODWORDINTREE(0x6b200000,0x00000000)}}, {VT_exponent,22,0x3a91ca,{DOUBLEWITHTWODWORDINTREE(0x6b300000,0x00000000)}}, {VT_exponent,22,0x3a91cb,{DOUBLEWITHTWODWORDINTREE(0x6b400000,0x00000000)}}, {VT_exponent,22,0x3a91cc,{DOUBLEWITHTWODWORDINTREE(0x6b500000,0x00000000)}}, {VT_exponent,22,0x3a91cd,{DOUBLEWITHTWODWORDINTREE(0x6b600000,0x00000000)}}, {VT_exponent,22,0x3a91ce,{DOUBLEWITHTWODWORDINTREE(0x6b700000,0x00000000)}}, {VT_exponent,22,0x3a91cf,{DOUBLEWITHTWODWORDINTREE(0x6b800000,0x00000000)}}, {VT_exponent,22,0x3a91d0,{DOUBLEWITHTWODWORDINTREE(0x6b900000,0x00000000)}}, {VT_exponent,22,0x3a91d1,{DOUBLEWITHTWODWORDINTREE(0x6ba00000,0x00000000)}}, {VT_exponent,22,0x3a91d2,{DOUBLEWITHTWODWORDINTREE(0x6bb00000,0x00000000)}}, {VT_exponent,22,0x3a91d3,{DOUBLEWITHTWODWORDINTREE(0x6bc00000,0x00000000)}}, {VT_exponent,22,0x3a91d4,{DOUBLEWITHTWODWORDINTREE(0x6bd00000,0x00000000)}}, {VT_exponent,22,0x3a91d5,{DOUBLEWITHTWODWORDINTREE(0x6be00000,0x00000000)}}, {VT_exponent,22,0x3a91d6,{DOUBLEWITHTWODWORDINTREE(0x6bf00000,0x00000000)}}, {VT_exponent,22,0x3a91d7,{DOUBLEWITHTWODWORDINTREE(0x6c000000,0x00000000)}}, {VT_exponent,22,0x3a91d8,{DOUBLEWITHTWODWORDINTREE(0x6c100000,0x00000000)}}, {VT_exponent,22,0x3a91d9,{DOUBLEWITHTWODWORDINTREE(0x6c200000,0x00000000)}}, {VT_exponent,22,0x3a91da,{DOUBLEWITHTWODWORDINTREE(0x6c300000,0x00000000)}}, {VT_exponent,22,0x3a91db,{DOUBLEWITHTWODWORDINTREE(0x6c400000,0x00000000)}}, {VT_exponent,22,0x3a91dc,{DOUBLEWITHTWODWORDINTREE(0x6c500000,0x00000000)}}, {VT_exponent,22,0x3a91dd,{DOUBLEWITHTWODWORDINTREE(0x6c600000,0x00000000)}}, {VT_exponent,22,0x3a91de,{DOUBLEWITHTWODWORDINTREE(0x6c700000,0x00000000)}}, {VT_exponent,22,0x3a91df,{DOUBLEWITHTWODWORDINTREE(0x6c800000,0x00000000)}}, {VT_exponent,22,0x3a91e0,{DOUBLEWITHTWODWORDINTREE(0x6c900000,0x00000000)}}, {VT_exponent,22,0x3a91e1,{DOUBLEWITHTWODWORDINTREE(0x6ca00000,0x00000000)}}, {VT_exponent,22,0x3a91e2,{DOUBLEWITHTWODWORDINTREE(0x6cb00000,0x00000000)}}, {VT_exponent,22,0x3a91e3,{DOUBLEWITHTWODWORDINTREE(0x6cc00000,0x00000000)}}, {VT_exponent,22,0x3a91e4,{DOUBLEWITHTWODWORDINTREE(0x6cd00000,0x00000000)}}, {VT_exponent,22,0x3a91e5,{DOUBLEWITHTWODWORDINTREE(0x6ce00000,0x00000000)}}, {VT_exponent,22,0x3a91e6,{DOUBLEWITHTWODWORDINTREE(0x6cf00000,0x00000000)}}, {VT_exponent,22,0x3a91e7,{DOUBLEWITHTWODWORDINTREE(0x6d000000,0x00000000)}}, {VT_exponent,22,0x3a91e8,{DOUBLEWITHTWODWORDINTREE(0x6d100000,0x00000000)}}, {VT_exponent,22,0x3a91e9,{DOUBLEWITHTWODWORDINTREE(0x6d200000,0x00000000)}}, {VT_exponent,22,0x3a91ea,{DOUBLEWITHTWODWORDINTREE(0x6d300000,0x00000000)}}, {VT_exponent,22,0x3a91eb,{DOUBLEWITHTWODWORDINTREE(0x6d400000,0x00000000)}}, {VT_exponent,22,0x3a91ec,{DOUBLEWITHTWODWORDINTREE(0x6d500000,0x00000000)}}, {VT_exponent,22,0x3a91ed,{DOUBLEWITHTWODWORDINTREE(0x6d600000,0x00000000)}}, {VT_exponent,22,0x3a91ee,{DOUBLEWITHTWODWORDINTREE(0x6d700000,0x00000000)}}, {VT_exponent,22,0x3a91ef,{DOUBLEWITHTWODWORDINTREE(0x6d800000,0x00000000)}}, {VT_exponent,22,0x3a91f0,{DOUBLEWITHTWODWORDINTREE(0x6d900000,0x00000000)}}, {VT_exponent,22,0x3a91f1,{DOUBLEWITHTWODWORDINTREE(0x6da00000,0x00000000)}}, {VT_exponent,22,0x3a91f2,{DOUBLEWITHTWODWORDINTREE(0x6db00000,0x00000000)}}, {VT_exponent,22,0x3a91f3,{DOUBLEWITHTWODWORDINTREE(0x6dc00000,0x00000000)}}, {VT_exponent,22,0x3a91f4,{DOUBLEWITHTWODWORDINTREE(0x6dd00000,0x00000000)}}, {VT_exponent,22,0x3a91f5,{DOUBLEWITHTWODWORDINTREE(0x6de00000,0x00000000)}}, {VT_exponent,22,0x3a91f6,{DOUBLEWITHTWODWORDINTREE(0x6df00000,0x00000000)}}, {VT_exponent,22,0x3a91f7,{DOUBLEWITHTWODWORDINTREE(0x6e000000,0x00000000)}}, {VT_exponent,22,0x3a91f8,{DOUBLEWITHTWODWORDINTREE(0x6e100000,0x00000000)}}, {VT_exponent,22,0x3a91f9,{DOUBLEWITHTWODWORDINTREE(0x6e200000,0x00000000)}}, {VT_exponent,22,0x3a91fa,{DOUBLEWITHTWODWORDINTREE(0x6e300000,0x00000000)}}, {VT_exponent,22,0x3a91fb,{DOUBLEWITHTWODWORDINTREE(0x6e400000,0x00000000)}}, {VT_exponent,22,0x3a91fc,{DOUBLEWITHTWODWORDINTREE(0x6e500000,0x00000000)}}, {VT_exponent,22,0x3a91fd,{DOUBLEWITHTWODWORDINTREE(0x6e600000,0x00000000)}}, {VT_exponent,22,0x3a91fe,{DOUBLEWITHTWODWORDINTREE(0x6e700000,0x00000000)}}, {VT_exponent,22,0x3a91ff,{DOUBLEWITHTWODWORDINTREE(0x6e800000,0x00000000)}}, {VT_exponent,22,0x3a9200,{DOUBLEWITHTWODWORDINTREE(0x6e900000,0x00000000)}}, {VT_exponent,22,0x3a9201,{DOUBLEWITHTWODWORDINTREE(0x6ea00000,0x00000000)}}, {VT_exponent,22,0x3a9202,{DOUBLEWITHTWODWORDINTREE(0x6eb00000,0x00000000)}}, {VT_exponent,22,0x3a9203,{DOUBLEWITHTWODWORDINTREE(0x6ec00000,0x00000000)}}, {VT_exponent,22,0x3a9204,{DOUBLEWITHTWODWORDINTREE(0x6ed00000,0x00000000)}}, {VT_exponent,22,0x3a9205,{DOUBLEWITHTWODWORDINTREE(0x6ee00000,0x00000000)}}, {VT_exponent,22,0x3a9206,{DOUBLEWITHTWODWORDINTREE(0x6ef00000,0x00000000)}}, {VT_exponent,22,0x3a9207,{DOUBLEWITHTWODWORDINTREE(0x6f000000,0x00000000)}}, {VT_exponent,22,0x3a9208,{DOUBLEWITHTWODWORDINTREE(0x6f100000,0x00000000)}}, {VT_exponent,22,0x3a9209,{DOUBLEWITHTWODWORDINTREE(0x6f200000,0x00000000)}}, {VT_exponent,22,0x3a920a,{DOUBLEWITHTWODWORDINTREE(0x6f300000,0x00000000)}}, {VT_exponent,22,0x3a920b,{DOUBLEWITHTWODWORDINTREE(0x6f400000,0x00000000)}}, {VT_exponent,22,0x3a920c,{DOUBLEWITHTWODWORDINTREE(0x6f500000,0x00000000)}}, {VT_exponent,22,0x3a920d,{DOUBLEWITHTWODWORDINTREE(0x6f600000,0x00000000)}}, {VT_exponent,22,0x3a920e,{DOUBLEWITHTWODWORDINTREE(0x6f700000,0x00000000)}}, {VT_exponent,22,0x3a920f,{DOUBLEWITHTWODWORDINTREE(0x6f800000,0x00000000)}}, {VT_exponent,22,0x3a9210,{DOUBLEWITHTWODWORDINTREE(0x6f900000,0x00000000)}}, {VT_exponent,22,0x3a9211,{DOUBLEWITHTWODWORDINTREE(0x6fa00000,0x00000000)}}, {VT_exponent,22,0x3a9212,{DOUBLEWITHTWODWORDINTREE(0x6fb00000,0x00000000)}}, {VT_exponent,22,0x3a9213,{DOUBLEWITHTWODWORDINTREE(0x6fc00000,0x00000000)}}, {VT_exponent,22,0x3a9214,{DOUBLEWITHTWODWORDINTREE(0x6fd00000,0x00000000)}}, {VT_exponent,22,0x3a9215,{DOUBLEWITHTWODWORDINTREE(0x6fe00000,0x00000000)}}, {VT_exponent,22,0x3a9216,{DOUBLEWITHTWODWORDINTREE(0x6ff00000,0x00000000)}}, {VT_exponent,22,0x3a9217,{DOUBLEWITHTWODWORDINTREE(0x70000000,0x00000000)}}, {VT_exponent,22,0x3a9218,{DOUBLEWITHTWODWORDINTREE(0x70100000,0x00000000)}}, {VT_exponent,22,0x3a9219,{DOUBLEWITHTWODWORDINTREE(0x70200000,0x00000000)}}, {VT_exponent,22,0x3a921a,{DOUBLEWITHTWODWORDINTREE(0x70300000,0x00000000)}}, {VT_exponent,22,0x3a921b,{DOUBLEWITHTWODWORDINTREE(0x70400000,0x00000000)}}, {VT_exponent,22,0x3a921c,{DOUBLEWITHTWODWORDINTREE(0x70500000,0x00000000)}}, {VT_exponent,22,0x3a921d,{DOUBLEWITHTWODWORDINTREE(0x70600000,0x00000000)}}, {VT_exponent,22,0x3a921e,{DOUBLEWITHTWODWORDINTREE(0x70700000,0x00000000)}}, {VT_exponent,22,0x3a921f,{DOUBLEWITHTWODWORDINTREE(0x70800000,0x00000000)}}, {VT_exponent,22,0x3a9220,{DOUBLEWITHTWODWORDINTREE(0x70900000,0x00000000)}}, {VT_exponent,22,0x3a9221,{DOUBLEWITHTWODWORDINTREE(0x70a00000,0x00000000)}}, {VT_exponent,22,0x3a9222,{DOUBLEWITHTWODWORDINTREE(0x70b00000,0x00000000)}}, {VT_exponent,22,0x3a9223,{DOUBLEWITHTWODWORDINTREE(0x70c00000,0x00000000)}}, {VT_exponent,22,0x3a9224,{DOUBLEWITHTWODWORDINTREE(0x70d00000,0x00000000)}}, {VT_exponent,22,0x3a9225,{DOUBLEWITHTWODWORDINTREE(0x70e00000,0x00000000)}}, {VT_exponent,22,0x3a9226,{DOUBLEWITHTWODWORDINTREE(0x70f00000,0x00000000)}}, {VT_exponent,22,0x3a9227,{DOUBLEWITHTWODWORDINTREE(0x71000000,0x00000000)}}, {VT_exponent,22,0x3a9228,{DOUBLEWITHTWODWORDINTREE(0x71100000,0x00000000)}}, {VT_exponent,22,0x3a9229,{DOUBLEWITHTWODWORDINTREE(0x71200000,0x00000000)}}, {VT_exponent,22,0x3a922a,{DOUBLEWITHTWODWORDINTREE(0x71300000,0x00000000)}}, {VT_exponent,22,0x3a922b,{DOUBLEWITHTWODWORDINTREE(0x71400000,0x00000000)}}, {VT_exponent,22,0x3a922c,{DOUBLEWITHTWODWORDINTREE(0x71500000,0x00000000)}}, {VT_exponent,22,0x3a922d,{DOUBLEWITHTWODWORDINTREE(0x71600000,0x00000000)}}, {VT_exponent,22,0x3a922e,{DOUBLEWITHTWODWORDINTREE(0x71700000,0x00000000)}}, {VT_exponent,22,0x3a922f,{DOUBLEWITHTWODWORDINTREE(0x71800000,0x00000000)}}, {VT_exponent,22,0x3a9230,{DOUBLEWITHTWODWORDINTREE(0x71900000,0x00000000)}}, {VT_exponent,22,0x3a9231,{DOUBLEWITHTWODWORDINTREE(0x71a00000,0x00000000)}}, {VT_exponent,22,0x3a9232,{DOUBLEWITHTWODWORDINTREE(0x71b00000,0x00000000)}}, {VT_exponent,22,0x3a9233,{DOUBLEWITHTWODWORDINTREE(0x71c00000,0x00000000)}}, {VT_exponent,22,0x3a9234,{DOUBLEWITHTWODWORDINTREE(0x71d00000,0x00000000)}}, {VT_exponent,22,0x3a9235,{DOUBLEWITHTWODWORDINTREE(0x71e00000,0x00000000)}}, {VT_exponent,22,0x3a9236,{DOUBLEWITHTWODWORDINTREE(0x71f00000,0x00000000)}}, {VT_exponent,22,0x3a9237,{DOUBLEWITHTWODWORDINTREE(0x72000000,0x00000000)}}, {VT_exponent,22,0x3a9238,{DOUBLEWITHTWODWORDINTREE(0x72100000,0x00000000)}}, {VT_exponent,22,0x3a9239,{DOUBLEWITHTWODWORDINTREE(0x72200000,0x00000000)}}, {VT_exponent,22,0x3a923a,{DOUBLEWITHTWODWORDINTREE(0x72300000,0x00000000)}}, {VT_exponent,22,0x3a923b,{DOUBLEWITHTWODWORDINTREE(0x72400000,0x00000000)}}, {VT_exponent,22,0x3a923c,{DOUBLEWITHTWODWORDINTREE(0x72500000,0x00000000)}}, {VT_exponent,22,0x3a923d,{DOUBLEWITHTWODWORDINTREE(0x72600000,0x00000000)}}, {VT_exponent,22,0x3a923e,{DOUBLEWITHTWODWORDINTREE(0x72700000,0x00000000)}}, {VT_exponent,22,0x3a923f,{DOUBLEWITHTWODWORDINTREE(0x72800000,0x00000000)}}, {VT_exponent,22,0x3a9240,{DOUBLEWITHTWODWORDINTREE(0x72900000,0x00000000)}}, {VT_exponent,22,0x3a9241,{DOUBLEWITHTWODWORDINTREE(0x72a00000,0x00000000)}}, {VT_exponent,22,0x3a9242,{DOUBLEWITHTWODWORDINTREE(0x72b00000,0x00000000)}}, {VT_exponent,22,0x3a9243,{DOUBLEWITHTWODWORDINTREE(0x72c00000,0x00000000)}}, {VT_exponent,22,0x3a9244,{DOUBLEWITHTWODWORDINTREE(0x72d00000,0x00000000)}}, {VT_exponent,22,0x3a9245,{DOUBLEWITHTWODWORDINTREE(0x72e00000,0x00000000)}}, {VT_exponent,22,0x3a9246,{DOUBLEWITHTWODWORDINTREE(0x72f00000,0x00000000)}}, {VT_exponent,22,0x3a9247,{DOUBLEWITHTWODWORDINTREE(0x73000000,0x00000000)}}, {VT_exponent,22,0x3a9248,{DOUBLEWITHTWODWORDINTREE(0x73100000,0x00000000)}}, {VT_exponent,22,0x3a9249,{DOUBLEWITHTWODWORDINTREE(0x73200000,0x00000000)}}, {VT_exponent,22,0x3a924a,{DOUBLEWITHTWODWORDINTREE(0x73300000,0x00000000)}}, {VT_exponent,22,0x3a924b,{DOUBLEWITHTWODWORDINTREE(0x73400000,0x00000000)}}, {VT_exponent,22,0x3a924c,{DOUBLEWITHTWODWORDINTREE(0x73500000,0x00000000)}}, {VT_exponent,22,0x3a924d,{DOUBLEWITHTWODWORDINTREE(0x73600000,0x00000000)}}, {VT_exponent,22,0x3a924e,{DOUBLEWITHTWODWORDINTREE(0x73700000,0x00000000)}}, {VT_exponent,22,0x3a924f,{DOUBLEWITHTWODWORDINTREE(0x73800000,0x00000000)}}, {VT_exponent,22,0x3a9250,{DOUBLEWITHTWODWORDINTREE(0x73900000,0x00000000)}}, {VT_exponent,22,0x3a9251,{DOUBLEWITHTWODWORDINTREE(0x73a00000,0x00000000)}}, {VT_exponent,22,0x3a9252,{DOUBLEWITHTWODWORDINTREE(0x73b00000,0x00000000)}}, {VT_exponent,22,0x3a9253,{DOUBLEWITHTWODWORDINTREE(0x73c00000,0x00000000)}}, {VT_exponent,22,0x3a9254,{DOUBLEWITHTWODWORDINTREE(0x73d00000,0x00000000)}}, {VT_exponent,22,0x3a9255,{DOUBLEWITHTWODWORDINTREE(0x73e00000,0x00000000)}}, {VT_exponent,22,0x3a9256,{DOUBLEWITHTWODWORDINTREE(0x73f00000,0x00000000)}}, {VT_exponent,22,0x3a9257,{DOUBLEWITHTWODWORDINTREE(0x74000000,0x00000000)}}, {VT_exponent,22,0x3a9258,{DOUBLEWITHTWODWORDINTREE(0x74100000,0x00000000)}}, {VT_exponent,22,0x3a9259,{DOUBLEWITHTWODWORDINTREE(0x74200000,0x00000000)}}, {VT_exponent,22,0x3a925a,{DOUBLEWITHTWODWORDINTREE(0x74300000,0x00000000)}}, {VT_exponent,22,0x3a925b,{DOUBLEWITHTWODWORDINTREE(0x74400000,0x00000000)}}, {VT_exponent,22,0x3a925c,{DOUBLEWITHTWODWORDINTREE(0x74500000,0x00000000)}}, {VT_exponent,22,0x3a925d,{DOUBLEWITHTWODWORDINTREE(0x74600000,0x00000000)}}, {VT_exponent,22,0x3a925e,{DOUBLEWITHTWODWORDINTREE(0x74700000,0x00000000)}}, {VT_exponent,22,0x3a925f,{DOUBLEWITHTWODWORDINTREE(0x74800000,0x00000000)}}, {VT_exponent,22,0x3a9260,{DOUBLEWITHTWODWORDINTREE(0x74900000,0x00000000)}}, {VT_exponent,22,0x3a9261,{DOUBLEWITHTWODWORDINTREE(0x74a00000,0x00000000)}}, {VT_exponent,22,0x3a9262,{DOUBLEWITHTWODWORDINTREE(0x74b00000,0x00000000)}}, {VT_exponent,22,0x3a9263,{DOUBLEWITHTWODWORDINTREE(0x74c00000,0x00000000)}}, {VT_exponent,22,0x3a9264,{DOUBLEWITHTWODWORDINTREE(0x74d00000,0x00000000)}}, {VT_exponent,22,0x3a9265,{DOUBLEWITHTWODWORDINTREE(0x74e00000,0x00000000)}}, {VT_exponent,22,0x3a9266,{DOUBLEWITHTWODWORDINTREE(0x74f00000,0x00000000)}}, {VT_exponent,22,0x3a9267,{DOUBLEWITHTWODWORDINTREE(0x75000000,0x00000000)}}, {VT_exponent,22,0x3a9268,{DOUBLEWITHTWODWORDINTREE(0x75100000,0x00000000)}}, {VT_exponent,22,0x3a9269,{DOUBLEWITHTWODWORDINTREE(0x75200000,0x00000000)}}, {VT_exponent,22,0x3a926a,{DOUBLEWITHTWODWORDINTREE(0x75300000,0x00000000)}}, {VT_exponent,22,0x3a926b,{DOUBLEWITHTWODWORDINTREE(0x75400000,0x00000000)}}, {VT_exponent,22,0x3a926c,{DOUBLEWITHTWODWORDINTREE(0x75500000,0x00000000)}}, {VT_exponent,22,0x3a926d,{DOUBLEWITHTWODWORDINTREE(0x75600000,0x00000000)}}, {VT_exponent,22,0x3a926e,{DOUBLEWITHTWODWORDINTREE(0x75700000,0x00000000)}}, {VT_exponent,22,0x3a926f,{DOUBLEWITHTWODWORDINTREE(0x75800000,0x00000000)}}, {VT_exponent,22,0x3a9270,{DOUBLEWITHTWODWORDINTREE(0x75900000,0x00000000)}}, {VT_exponent,22,0x3a9271,{DOUBLEWITHTWODWORDINTREE(0x75a00000,0x00000000)}}, {VT_exponent,22,0x3a9272,{DOUBLEWITHTWODWORDINTREE(0x75b00000,0x00000000)}}, {VT_exponent,22,0x3a9273,{DOUBLEWITHTWODWORDINTREE(0x75c00000,0x00000000)}}, {VT_exponent,22,0x3a9274,{DOUBLEWITHTWODWORDINTREE(0x75d00000,0x00000000)}}, {VT_exponent,22,0x3a9275,{DOUBLEWITHTWODWORDINTREE(0x75e00000,0x00000000)}}, {VT_exponent,22,0x3a9276,{DOUBLEWITHTWODWORDINTREE(0x75f00000,0x00000000)}}, {VT_exponent,22,0x3a9277,{DOUBLEWITHTWODWORDINTREE(0x76000000,0x00000000)}}, {VT_exponent,22,0x3a9278,{DOUBLEWITHTWODWORDINTREE(0x76100000,0x00000000)}}, {VT_exponent,22,0x3a9279,{DOUBLEWITHTWODWORDINTREE(0x76200000,0x00000000)}}, {VT_exponent,22,0x3a927a,{DOUBLEWITHTWODWORDINTREE(0x76300000,0x00000000)}}, {VT_exponent,22,0x3a927b,{DOUBLEWITHTWODWORDINTREE(0x76400000,0x00000000)}}, {VT_exponent,22,0x3a927c,{DOUBLEWITHTWODWORDINTREE(0x76500000,0x00000000)}}, {VT_exponent,22,0x3a927d,{DOUBLEWITHTWODWORDINTREE(0x76600000,0x00000000)}}, {VT_exponent,22,0x3a927e,{DOUBLEWITHTWODWORDINTREE(0x76700000,0x00000000)}}, {VT_exponent,22,0x3a927f,{DOUBLEWITHTWODWORDINTREE(0x76800000,0x00000000)}}, {VT_exponent,22,0x3a9280,{DOUBLEWITHTWODWORDINTREE(0x76900000,0x00000000)}}, {VT_exponent,22,0x3a9281,{DOUBLEWITHTWODWORDINTREE(0x76a00000,0x00000000)}}, {VT_exponent,22,0x3a9282,{DOUBLEWITHTWODWORDINTREE(0x76b00000,0x00000000)}}, {VT_exponent,22,0x3a9283,{DOUBLEWITHTWODWORDINTREE(0x76c00000,0x00000000)}}, {VT_exponent,22,0x3a9284,{DOUBLEWITHTWODWORDINTREE(0x76d00000,0x00000000)}}, {VT_exponent,22,0x3a9285,{DOUBLEWITHTWODWORDINTREE(0x76e00000,0x00000000)}}, {VT_exponent,22,0x3a9286,{DOUBLEWITHTWODWORDINTREE(0x76f00000,0x00000000)}}, {VT_exponent,22,0x3a9287,{DOUBLEWITHTWODWORDINTREE(0x77000000,0x00000000)}}, {VT_exponent,22,0x3a9288,{DOUBLEWITHTWODWORDINTREE(0x77100000,0x00000000)}}, {VT_exponent,22,0x3a9289,{DOUBLEWITHTWODWORDINTREE(0x77200000,0x00000000)}}, {VT_exponent,22,0x3a928a,{DOUBLEWITHTWODWORDINTREE(0x77300000,0x00000000)}}, {VT_exponent,22,0x3a928b,{DOUBLEWITHTWODWORDINTREE(0x77400000,0x00000000)}}, {VT_exponent,22,0x3a928c,{DOUBLEWITHTWODWORDINTREE(0x77500000,0x00000000)}}, {VT_exponent,22,0x3a928d,{DOUBLEWITHTWODWORDINTREE(0x77600000,0x00000000)}}, {VT_exponent,22,0x3a928e,{DOUBLEWITHTWODWORDINTREE(0x77700000,0x00000000)}}, {VT_exponent,22,0x3a928f,{DOUBLEWITHTWODWORDINTREE(0x77800000,0x00000000)}}, {VT_exponent,22,0x3a9290,{DOUBLEWITHTWODWORDINTREE(0x77900000,0x00000000)}}, {VT_exponent,22,0x3a9291,{DOUBLEWITHTWODWORDINTREE(0x77a00000,0x00000000)}}, {VT_exponent,22,0x3a9292,{DOUBLEWITHTWODWORDINTREE(0x77b00000,0x00000000)}}, {VT_exponent,22,0x3a9293,{DOUBLEWITHTWODWORDINTREE(0x77c00000,0x00000000)}}, {VT_exponent,22,0x3a9294,{DOUBLEWITHTWODWORDINTREE(0x77d00000,0x00000000)}}, {VT_exponent,22,0x3a9295,{DOUBLEWITHTWODWORDINTREE(0x77e00000,0x00000000)}}, {VT_exponent,22,0x3a9296,{DOUBLEWITHTWODWORDINTREE(0x77f00000,0x00000000)}}, {VT_exponent,22,0x3a9297,{DOUBLEWITHTWODWORDINTREE(0x78000000,0x00000000)}}, {VT_exponent,22,0x3a9298,{DOUBLEWITHTWODWORDINTREE(0x78100000,0x00000000)}}, {VT_exponent,22,0x3a9299,{DOUBLEWITHTWODWORDINTREE(0x78200000,0x00000000)}}, {VT_exponent,22,0x3a929a,{DOUBLEWITHTWODWORDINTREE(0x78300000,0x00000000)}}, {VT_exponent,22,0x3a929b,{DOUBLEWITHTWODWORDINTREE(0x78400000,0x00000000)}}, {VT_exponent,22,0x3a929c,{DOUBLEWITHTWODWORDINTREE(0x78500000,0x00000000)}}, {VT_exponent,22,0x3a929d,{DOUBLEWITHTWODWORDINTREE(0x78600000,0x00000000)}}, {VT_exponent,22,0x3a929e,{DOUBLEWITHTWODWORDINTREE(0x78700000,0x00000000)}}, {VT_exponent,22,0x3a929f,{DOUBLEWITHTWODWORDINTREE(0x78800000,0x00000000)}}, {VT_exponent,22,0x3a92a0,{DOUBLEWITHTWODWORDINTREE(0x78900000,0x00000000)}}, {VT_exponent,22,0x3a92a1,{DOUBLEWITHTWODWORDINTREE(0x78a00000,0x00000000)}}, {VT_exponent,22,0x3a92a2,{DOUBLEWITHTWODWORDINTREE(0x78b00000,0x00000000)}}, {VT_exponent,22,0x3a92a3,{DOUBLEWITHTWODWORDINTREE(0x78c00000,0x00000000)}}, {VT_exponent,22,0x3a92a4,{DOUBLEWITHTWODWORDINTREE(0x78d00000,0x00000000)}}, {VT_exponent,22,0x3a92a5,{DOUBLEWITHTWODWORDINTREE(0x78e00000,0x00000000)}}, {VT_exponent,22,0x3a92a6,{DOUBLEWITHTWODWORDINTREE(0x78f00000,0x00000000)}}, {VT_exponent,22,0x3a92a7,{DOUBLEWITHTWODWORDINTREE(0x79000000,0x00000000)}}, {VT_exponent,22,0x3a92a8,{DOUBLEWITHTWODWORDINTREE(0x79100000,0x00000000)}}, {VT_exponent,22,0x3a92a9,{DOUBLEWITHTWODWORDINTREE(0x79200000,0x00000000)}}, {VT_exponent,22,0x3a92aa,{DOUBLEWITHTWODWORDINTREE(0x79300000,0x00000000)}}, {VT_exponent,22,0x3a92ab,{DOUBLEWITHTWODWORDINTREE(0x79400000,0x00000000)}}, {VT_exponent,22,0x3a92ac,{DOUBLEWITHTWODWORDINTREE(0x79500000,0x00000000)}}, {VT_exponent,22,0x3a92ad,{DOUBLEWITHTWODWORDINTREE(0x79600000,0x00000000)}}, {VT_exponent,22,0x3a92ae,{DOUBLEWITHTWODWORDINTREE(0x79700000,0x00000000)}}, {VT_exponent,22,0x3a92af,{DOUBLEWITHTWODWORDINTREE(0x79800000,0x00000000)}}, {VT_exponent,22,0x3a92b0,{DOUBLEWITHTWODWORDINTREE(0x79900000,0x00000000)}}, {VT_exponent,22,0x3a92b1,{DOUBLEWITHTWODWORDINTREE(0x79a00000,0x00000000)}}, {VT_exponent,22,0x3a92b2,{DOUBLEWITHTWODWORDINTREE(0x79b00000,0x00000000)}}, {VT_exponent,22,0x3a92b3,{DOUBLEWITHTWODWORDINTREE(0x79c00000,0x00000000)}}, {VT_exponent,22,0x3a92b4,{DOUBLEWITHTWODWORDINTREE(0x79d00000,0x00000000)}}, {VT_exponent,22,0x3a92b5,{DOUBLEWITHTWODWORDINTREE(0x79e00000,0x00000000)}}, {VT_exponent,22,0x3a92b6,{DOUBLEWITHTWODWORDINTREE(0x79f00000,0x00000000)}}, {VT_exponent,22,0x3a92b7,{DOUBLEWITHTWODWORDINTREE(0x7a000000,0x00000000)}}, {VT_exponent,22,0x3a92b8,{DOUBLEWITHTWODWORDINTREE(0x7a100000,0x00000000)}}, {VT_exponent,22,0x3a92b9,{DOUBLEWITHTWODWORDINTREE(0x7a200000,0x00000000)}}, {VT_exponent,22,0x3a92ba,{DOUBLEWITHTWODWORDINTREE(0x7a300000,0x00000000)}}, {VT_exponent,22,0x3a92bb,{DOUBLEWITHTWODWORDINTREE(0x7a400000,0x00000000)}}, {VT_exponent,22,0x3a92bc,{DOUBLEWITHTWODWORDINTREE(0x7a500000,0x00000000)}}, {VT_exponent,22,0x3a92bd,{DOUBLEWITHTWODWORDINTREE(0x7a600000,0x00000000)}}, {VT_exponent,22,0x3a92be,{DOUBLEWITHTWODWORDINTREE(0x7a700000,0x00000000)}}, {VT_exponent,22,0x3a92bf,{DOUBLEWITHTWODWORDINTREE(0x7a800000,0x00000000)}}, {VT_exponent,22,0x3a92c0,{DOUBLEWITHTWODWORDINTREE(0x7a900000,0x00000000)}}, {VT_exponent,22,0x3a92c1,{DOUBLEWITHTWODWORDINTREE(0x7aa00000,0x00000000)}}, {VT_exponent,22,0x3a92c2,{DOUBLEWITHTWODWORDINTREE(0x7ab00000,0x00000000)}}, {VT_exponent,22,0x3a92c3,{DOUBLEWITHTWODWORDINTREE(0x7ac00000,0x00000000)}}, {VT_exponent,22,0x3a92c4,{DOUBLEWITHTWODWORDINTREE(0x7ad00000,0x00000000)}}, {VT_exponent,22,0x3a92c5,{DOUBLEWITHTWODWORDINTREE(0x7ae00000,0x00000000)}}, {VT_exponent,22,0x3a92c6,{DOUBLEWITHTWODWORDINTREE(0x7af00000,0x00000000)}}, {VT_exponent,22,0x3a92c7,{DOUBLEWITHTWODWORDINTREE(0x7b000000,0x00000000)}}, {VT_exponent,22,0x3a92c8,{DOUBLEWITHTWODWORDINTREE(0x7b100000,0x00000000)}}, {VT_exponent,22,0x3a92c9,{DOUBLEWITHTWODWORDINTREE(0x7b200000,0x00000000)}}, {VT_exponent,22,0x3a92ca,{DOUBLEWITHTWODWORDINTREE(0x7b300000,0x00000000)}}, {VT_exponent,22,0x3a92cb,{DOUBLEWITHTWODWORDINTREE(0x7b400000,0x00000000)}}, {VT_exponent,22,0x3a92cc,{DOUBLEWITHTWODWORDINTREE(0x7b500000,0x00000000)}}, {VT_exponent,22,0x3a92cd,{DOUBLEWITHTWODWORDINTREE(0x7b600000,0x00000000)}}, {VT_exponent,22,0x3a92ce,{DOUBLEWITHTWODWORDINTREE(0x7b700000,0x00000000)}}, {VT_exponent,22,0x3a92cf,{DOUBLEWITHTWODWORDINTREE(0x7b800000,0x00000000)}}, {VT_exponent,22,0x3a92d0,{DOUBLEWITHTWODWORDINTREE(0x7b900000,0x00000000)}}, {VT_exponent,22,0x3a92d1,{DOUBLEWITHTWODWORDINTREE(0x7ba00000,0x00000000)}}, {VT_exponent,22,0x3a92d2,{DOUBLEWITHTWODWORDINTREE(0x7bb00000,0x00000000)}}, {VT_exponent,22,0x3a92d3,{DOUBLEWITHTWODWORDINTREE(0x7bc00000,0x00000000)}}, {VT_exponent,22,0x3a92d4,{DOUBLEWITHTWODWORDINTREE(0x7bd00000,0x00000000)}}, {VT_exponent,22,0x3a92d5,{DOUBLEWITHTWODWORDINTREE(0x7be00000,0x00000000)}}, {VT_exponent,22,0x3a92d6,{DOUBLEWITHTWODWORDINTREE(0x7bf00000,0x00000000)}}, {VT_exponent,22,0x3a92d7,{DOUBLEWITHTWODWORDINTREE(0x7c000000,0x00000000)}}, {VT_exponent,22,0x3a92d8,{DOUBLEWITHTWODWORDINTREE(0x7c100000,0x00000000)}}, {VT_exponent,22,0x3a92d9,{DOUBLEWITHTWODWORDINTREE(0x7c200000,0x00000000)}}, {VT_exponent,22,0x3a92da,{DOUBLEWITHTWODWORDINTREE(0x7c300000,0x00000000)}}, {VT_exponent,22,0x3a92db,{DOUBLEWITHTWODWORDINTREE(0x7c400000,0x00000000)}}, {VT_exponent,22,0x3a92dc,{DOUBLEWITHTWODWORDINTREE(0x7c500000,0x00000000)}}, {VT_exponent,22,0x3a92dd,{DOUBLEWITHTWODWORDINTREE(0x7c600000,0x00000000)}}, {VT_exponent,22,0x3a92de,{DOUBLEWITHTWODWORDINTREE(0x7c700000,0x00000000)}}, {VT_exponent,22,0x3a92df,{DOUBLEWITHTWODWORDINTREE(0x7c800000,0x00000000)}}, {VT_exponent,22,0x3a92e0,{DOUBLEWITHTWODWORDINTREE(0x7c900000,0x00000000)}}, {VT_exponent,22,0x3a92e1,{DOUBLEWITHTWODWORDINTREE(0x7ca00000,0x00000000)}}, {VT_exponent,22,0x3a92e2,{DOUBLEWITHTWODWORDINTREE(0x7cb00000,0x00000000)}}, {VT_exponent,22,0x3a92e3,{DOUBLEWITHTWODWORDINTREE(0x7cc00000,0x00000000)}}, {VT_exponent,22,0x3a92e4,{DOUBLEWITHTWODWORDINTREE(0x7cd00000,0x00000000)}}, {VT_exponent,22,0x3a92e5,{DOUBLEWITHTWODWORDINTREE(0x7ce00000,0x00000000)}}, {VT_exponent,22,0x3a92e6,{DOUBLEWITHTWODWORDINTREE(0x7cf00000,0x00000000)}}, {VT_exponent,22,0x3a92e7,{DOUBLEWITHTWODWORDINTREE(0x7d000000,0x00000000)}}, {VT_exponent,22,0x3a92e8,{DOUBLEWITHTWODWORDINTREE(0x7d100000,0x00000000)}}, {VT_exponent,22,0x3a92e9,{DOUBLEWITHTWODWORDINTREE(0x7d200000,0x00000000)}}, {VT_exponent,22,0x3a92ea,{DOUBLEWITHTWODWORDINTREE(0x7d300000,0x00000000)}}, {VT_exponent,22,0x3a92eb,{DOUBLEWITHTWODWORDINTREE(0x7d400000,0x00000000)}}, {VT_exponent,22,0x3a92ec,{DOUBLEWITHTWODWORDINTREE(0x7d500000,0x00000000)}}, {VT_exponent,22,0x3a92ed,{DOUBLEWITHTWODWORDINTREE(0x7d600000,0x00000000)}}, {VT_exponent,22,0x3a92ee,{DOUBLEWITHTWODWORDINTREE(0x7d700000,0x00000000)}}, {VT_exponent,22,0x3a92ef,{DOUBLEWITHTWODWORDINTREE(0x7d800000,0x00000000)}}, {VT_exponent,22,0x3a92f0,{DOUBLEWITHTWODWORDINTREE(0x7d900000,0x00000000)}}, {VT_exponent,22,0x3a92f1,{DOUBLEWITHTWODWORDINTREE(0x7da00000,0x00000000)}}, {VT_exponent,22,0x3a92f2,{DOUBLEWITHTWODWORDINTREE(0x7db00000,0x00000000)}}, {VT_exponent,22,0x3a92f3,{DOUBLEWITHTWODWORDINTREE(0x7dc00000,0x00000000)}}, {VT_exponent,22,0x3a92f4,{DOUBLEWITHTWODWORDINTREE(0x7dd00000,0x00000000)}}, {VT_exponent,22,0x3a92f5,{DOUBLEWITHTWODWORDINTREE(0x7de00000,0x00000000)}}, {VT_exponent,22,0x3a92f6,{DOUBLEWITHTWODWORDINTREE(0x7df00000,0x00000000)}}, {VT_exponent,22,0x3a92f7,{DOUBLEWITHTWODWORDINTREE(0x7e000000,0x00000000)}}, {VT_exponent,22,0x3a92f8,{DOUBLEWITHTWODWORDINTREE(0x7e100000,0x00000000)}}, {VT_exponent,22,0x3a92f9,{DOUBLEWITHTWODWORDINTREE(0x7e200000,0x00000000)}}, {VT_exponent,22,0x3a92fa,{DOUBLEWITHTWODWORDINTREE(0x7e300000,0x00000000)}}, {VT_exponent,22,0x3a92fb,{DOUBLEWITHTWODWORDINTREE(0x7e400000,0x00000000)}}, {VT_exponent,22,0x3a92fc,{DOUBLEWITHTWODWORDINTREE(0x7e500000,0x00000000)}}, {VT_exponent,22,0x3a92fd,{DOUBLEWITHTWODWORDINTREE(0x7e600000,0x00000000)}}, {VT_exponent,22,0x3a92fe,{DOUBLEWITHTWODWORDINTREE(0x7e700000,0x00000000)}}, {VT_exponent,22,0x3a92ff,{DOUBLEWITHTWODWORDINTREE(0x7e800000,0x00000000)}}, {VT_exponent,22,0x3a95a0,{DOUBLEWITHTWODWORDINTREE(0x7e900000,0x00000000)}}, {VT_exponent,22,0x3a95a1,{DOUBLEWITHTWODWORDINTREE(0x7ea00000,0x00000000)}}, {VT_exponent,22,0x3a95a2,{DOUBLEWITHTWODWORDINTREE(0x7eb00000,0x00000000)}}, {VT_exponent,22,0x3a95a3,{DOUBLEWITHTWODWORDINTREE(0x7ec00000,0x00000000)}}, {VT_exponent,22,0x3a95a4,{DOUBLEWITHTWODWORDINTREE(0x7ed00000,0x00000000)}}, {VT_exponent,22,0x3a95a5,{DOUBLEWITHTWODWORDINTREE(0x7ee00000,0x00000000)}}, {VT_exponent,22,0x3a95a6,{DOUBLEWITHTWODWORDINTREE(0x7ef00000,0x00000000)}}, {VT_exponent,22,0x3a95a7,{DOUBLEWITHTWODWORDINTREE(0x7f000000,0x00000000)}}, {VT_exponent,22,0x3a95a8,{DOUBLEWITHTWODWORDINTREE(0x7f100000,0x00000000)}}, {VT_exponent,22,0x3a95a9,{DOUBLEWITHTWODWORDINTREE(0x7f200000,0x00000000)}}, {VT_exponent,22,0x3a95aa,{DOUBLEWITHTWODWORDINTREE(0x7f300000,0x00000000)}}, {VT_exponent,22,0x3a95ab,{DOUBLEWITHTWODWORDINTREE(0x7f400000,0x00000000)}}, {VT_exponent,22,0x3a95ac,{DOUBLEWITHTWODWORDINTREE(0x7f500000,0x00000000)}}, {VT_exponent,22,0x3a95ad,{DOUBLEWITHTWODWORDINTREE(0x7f600000,0x00000000)}}, {VT_exponent,22,0x3a95ae,{DOUBLEWITHTWODWORDINTREE(0x7f700000,0x00000000)}}, {VT_exponent,22,0x3a95af,{DOUBLEWITHTWODWORDINTREE(0x7f800000,0x00000000)}}, {VT_exponent,22,0x3b8fe0,{DOUBLEWITHTWODWORDINTREE(0x7f900000,0x00000000)}}, {VT_exponent,22,0x3b8fe1,{DOUBLEWITHTWODWORDINTREE(0x7fa00000,0x00000000)}}, {VT_exponent,22,0x3b8fe2,{DOUBLEWITHTWODWORDINTREE(0x7fb00000,0x00000000)}}, {VT_exponent,22,0x3b8fe3,{DOUBLEWITHTWODWORDINTREE(0x7fc00000,0x00000000)}}, {VT_exponent,21,0x68e90,{DOUBLEWITHTWODWORDINTREE(0x7fd00000,0x00000000)}}, {VT_exponent,21,0x68e91,{DOUBLEWITHTWODWORDINTREE(0x7fe00000,0x00000000)}}, {VT_exponent,21,0x68e98,{DOUBLEWITHTWODWORDINTREE(0x7ff80000,0x00000000)}}, }; // End of acofdoe array mathgl-2.4.4/src/canvas_cf.cpp0000644000175000017500000010261413513030041016367 0ustar alastairalastair/*************************************************************************** * canvas_cf.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/canvas.h" #include "mgl2/canvas_cf.h" #include "mgl2/eval.h" #include "mgl2/evalc.h" //----------------------------------------------------------------------------- #undef _GR_ #define _GR_ ((mglCanvas *)(*gr)) //----------------------------------------------------------------------------- MGL_EXPORT const unsigned char *mgl_get_rgb(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetBits():0; } MGL_EXPORT const unsigned char *mgl_get_rgba(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetRGBA():0; } MGL_EXPORT_PURE const unsigned char* mgl_get_background(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetBackground():0; } int MGL_EXPORT mgl_get_width(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetWidth():0; } int MGL_EXPORT mgl_get_height(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetHeight():0; } void MGL_EXPORT mgl_calc_xyz(HMGL gr, int xs, int ys, mreal *x, mreal *y, mreal *z) { mglCanvas *g = dynamic_cast(gr); mglPoint p = g?g->CalcXYZ(xs,ys):mglPoint(NAN,NAN,NAN); *x = p.x; *y = p.y; *z = p.z; } void MGL_EXPORT mgl_calc_scr(HMGL gr, double x, double y, double z, int *xs, int *ys) { mglCanvas *g = dynamic_cast(gr); if(g) g->CalcScr(mglPoint(x,y,z),xs,ys); } void MGL_EXPORT mgl_set_obj_id(HMGL gr, int id) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetObjId(id); } int MGL_EXPORT_PURE mgl_get_obj_id(HMGL gr, int x, int y) { mglCanvas *g = dynamic_cast(gr); return g?g->GetObjId(x,y):-1; } int MGL_EXPORT_PURE mgl_get_spl_id(HMGL gr, int x, int y) { mglCanvas *g = dynamic_cast(gr); return g?g->GetSplId(x,y):-1; } //----------------------------------------------------------------------------- long MGL_EXPORT_PURE mgl_is_active(HMGL gr, int xs, int ys, int d) { if(d<=0) d=1; for(size_t i=0;iAct.size();i++) { const mglActivePos &p = gr->Act[i]; if(abs(xs-p.x)(gr); return g?g->NewFrame():-1; } void MGL_EXPORT mgl_end_frame(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->EndFrame(); } int MGL_EXPORT_PURE mgl_get_num_frame(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetNumFrame():0; } void MGL_EXPORT mgl_reset_frames(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->ResetFrames(); } void MGL_EXPORT mgl_get_frame(HMGL gr, int i) { mglCanvas *g = dynamic_cast(gr); if(g) g->GetFrame(i); } void MGL_EXPORT mgl_set_frame(HMGL gr, int i) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetFrame(i); } void MGL_EXPORT mgl_show_frame(HMGL gr, int i) { mglCanvas *g = dynamic_cast(gr); if(g) g->ShowFrame(i); } void MGL_EXPORT mgl_del_frame(HMGL gr, int i) { mglCanvas *g = dynamic_cast(gr); if(g) g->DelFrame(i); } void MGL_EXPORT mgl_clear_frame(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->ClearFrame(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_transp_type(HMGL gr, int type) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTranspType(type); } void MGL_EXPORT mgl_set_alpha(HMGL gr, int enable) { gr->Alpha(enable); } void MGL_EXPORT mgl_set_gray(HMGL gr, int enable) { gr->set(enable, MGL_GRAY_MODE); } void MGL_EXPORT mgl_set_fog(HMGL gr, double d, double dz) { mglCanvas *g = dynamic_cast(gr); if(g) g->Fog(d,dz); } void MGL_EXPORT mgl_set_light(HMGL gr, int enable) { gr->Light(enable); } void MGL_EXPORT mgl_set_attach_light(HMGL gr, int enable) { gr->AttachLight(enable); } void MGL_EXPORT mgl_set_light_n(HMGL gr, int n, int enable) { mglCanvas *g = dynamic_cast(gr); if(g) g->Light(n, enable); } void MGL_EXPORT mgl_add_light_ext(HMGL gr, int n, double x, double y, double z, char c, double br, double ap) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddLight(n,mglPoint(x,y,z),c,br,ap); } void MGL_EXPORT mgl_add_light_loc(HMGL gr, int n, double x, double y, double z, double dx, double dy, double dz, char c, double br, double ap) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddLight(n,mglPoint(x,y,z),mglPoint(dx,dy,dz),c,br,ap); } void MGL_EXPORT mgl_add_light(HMGL gr, int n, double x, double y, double z) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddLight(n,mglPoint(x,y,z)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mat_push(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->Push(); } void MGL_EXPORT mgl_mat_pop(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->Pop(); } void MGL_EXPORT mgl_clf(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->Clf(); } void MGL_EXPORT mgl_clf_chr(HMGL gr, char ch) { mglCanvas *g = dynamic_cast(gr); if(g) g->Clf(mglColor(ch)); } void MGL_EXPORT mgl_clf_rgb(HMGL gr, double r, double g, double b) { mglCanvas *gg = dynamic_cast(gr); if(gg) gg->Clf(mglColor(r,g,b)); } void MGL_EXPORT mgl_clf_str(HMGL gr, const char *col) { mglCanvas *g = dynamic_cast(gr); if(g) g->Clf(col); } void MGL_EXPORT mgl_load_background(HMGL gr, const char *fn, double alpha) { mglCanvas *g = dynamic_cast(gr); if(g) g->LoadBackground(fn,alpha); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_subplot_d(HMGL gr, int nx,int ny,int m,const char *style,double dx,double dy) { double x1,x2,y1,y2; int mx = m%nx, my = m/nx; if(gr->get(MGL_AUTO_FACTOR)) { dx /= 1.55; dy /= 1.55; } else { dx /= 2; dy /= 2; } x1 = (mx+dx)/nx; x2 = (mx+1+dx)/nx; y2 = 1.f-(my+dy)/ny; y1 = 1.f-(my+1+dy)/ny; mglCanvas *g = dynamic_cast(gr); if(g) g->InPlot(x1,x2,y1,y2,style); } void MGL_EXPORT mgl_subplot(HMGL gr, int nx,int ny,int m,const char *style) { mgl_subplot_d(gr,nx,ny,m,style,0,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_multiplot_d(HMGL gr, int nx,int ny,int m,int dx,int dy,const char *style,double sx,double sy) { double x1,x2,y1,y2; int mx = m%nx, my = m/nx; if(gr->get(MGL_AUTO_FACTOR)) { sx /= 1.55; sy /= 1.55; } else { sx /= 2; sy /= 2; } dx = (dx<1 || dx+mx>nx) ? 1 : dx; dy = (dy<1 || dy+my>ny) ? 1 : dy; x1 = double(mx+sx)/nx; x2 = double(mx+dx+sx)/nx; y2 = 1-double(my+sy)/ny; y1 = 1-double(my+dy+sy)/ny; mglCanvas *g = dynamic_cast(gr); if(g) g->InPlot(x1,x2,y1,y2,style); } void MGL_EXPORT mgl_multiplot(HMGL gr, int nx,int ny,int m,int dx,int dy,const char *style) { mgl_multiplot_d(gr,nx,ny,m,dx,dy,style,0,0); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MGL_EXPORT mgl_inplot(HMGL gr, double x1,double x2,double y1,double y2) { mglCanvas *g = dynamic_cast(gr); if(g) g->InPlot(x1,x2,y1,y2,false); } void MGL_EXPORT mgl_relplot(HMGL gr, double x1,double x2,double y1,double y2) { mglCanvas *g = dynamic_cast(gr); if(g) g->InPlot(x1,x2,y1,y2,true); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_columnplot(HMGL gr, int num, int i, double dd) { double w = 1./num; mglCanvas *g = dynamic_cast(gr); if(g) g->InPlot(0,1,1-w*(i+1-dd/2),1-(i+dd/2)*w,true); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_gridplot(HMGL gr, int nx, int ny, int i, double dd) { int ix=i%nx, iy=i/nx; double wx = 1./nx, wy = 1./ny; mglCanvas *g = dynamic_cast(gr); if(g) g->InPlot((ix+dd/2)*wx,wx*(ix+1-dd/2),1-wy*(iy+1-dd/2),1-(iy+dd/2)*wy,true); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stickplot(HMGL gr, int num, int i, double tet, double phi) { mglCanvas *g = dynamic_cast(gr); if(g) g->StickPlot(num, i, tet, phi); } void MGL_EXPORT mgl_shearplot(HMGL gr, int num, int i, double sx, double sy, double xd, double yd) { mglCanvas *g = dynamic_cast(gr); if(g) g->ShearPlot(num, i, sx, sy, xd, yd); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_aspect(HMGL gr, double Ax,double Ay,double Az) { mglCanvas *g = dynamic_cast(gr); if(g) g->Aspect(Ax,Ay,Az); } void MGL_EXPORT mgl_shear(HMGL gr, double Sx,double Sy) { mglCanvas *g = dynamic_cast(gr); if(g) g->Shear(Sx,Sy); } void MGL_EXPORT mgl_rotate(HMGL gr, double TetX,double TetZ,double TetY) { mglCanvas *g = dynamic_cast(gr); if(g) g->Rotate(TetX,TetZ,TetY); } void MGL_EXPORT mgl_view(HMGL gr, double TetX,double TetZ,double TetY) { mglCanvas *g = dynamic_cast(gr); if(g) g->View(TetX,TetZ,TetY); } void MGL_EXPORT mgl_zoom(HMGL gr, double x1, double y1, double x2, double y2) { mglCanvas *g = dynamic_cast(gr); if(g) g->Zoom(x1,y1,x2,y2); } void MGL_EXPORT mgl_rotate_vector(HMGL gr, double Tet,double x,double y,double z) { mglCanvas *g = dynamic_cast(gr); if(g) g->RotateN(Tet,x,y,z); } void MGL_EXPORT mgl_perspective(HMGL gr, double val) { mglCanvas *g = dynamic_cast(gr); if(g) g->Perspective(val); } void MGL_EXPORT mgl_ask_perspective(HMGL gr, double val) { mglCanvas *g = dynamic_cast(gr); if(g) g->Perspective(val,false); } void MGL_EXPORT mgl_title(HMGL gr, const char *title, const char *stl, double size) { mglCanvas *g = dynamic_cast(gr); if(g) g->Title(title,stl,size); } void MGL_EXPORT mgl_titlew(HMGL gr, const wchar_t *title, const char *stl, double size) { mglCanvas *g = dynamic_cast(gr); if(g) g->Title(title,stl,size); } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_new_frame_(uintptr_t *gr) { return _GR_->NewFrame(); } void MGL_EXPORT mgl_end_frame_(uintptr_t *gr) { _GR_->EndFrame(); } int MGL_EXPORT_PURE mgl_get_num_frame_(uintptr_t *gr) { return _GR_->GetNumFrame(); } void MGL_EXPORT mgl_reset_frames_(uintptr_t *gr) { _GR_->ResetFrames(); } void MGL_EXPORT mgl_get_frame_(uintptr_t *gr, int *i) { _GR_->GetFrame(*i); } void MGL_EXPORT mgl_set_frame_(uintptr_t *gr, int *i) { _GR_->SetFrame(*i); } void MGL_EXPORT mgl_show_frame_(uintptr_t *gr, int *i) { _GR_->ShowFrame(*i);} void MGL_EXPORT mgl_del_frame_(uintptr_t *gr, int *i) { _GR_->DelFrame(*i); } void MGL_EXPORT mgl_clear_frame_(uintptr_t *gr) { _GR_->ClearFrame(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_transp_type_(uintptr_t *gr, int *type) { _GR_->SetTranspType(*type); } void MGL_EXPORT mgl_set_alpha_(uintptr_t *gr, int *enable) { _GR_->Alpha(*enable); } void MGL_EXPORT mgl_set_gray_(uintptr_t *gr, int *enable) { _GR_->set(*enable, MGL_GRAY_MODE); } void MGL_EXPORT mgl_set_fog_(uintptr_t *gr, mreal *d, mreal *dz) { _GR_->Fog(*d, *dz); } void MGL_EXPORT mgl_set_light_(uintptr_t *gr, int *enable) { _GR_->Light(*enable); } void MGL_EXPORT mgl_set_attach_light_(uintptr_t *gr, int *enable) { _GR_->AttachLight(*enable); } void MGL_EXPORT mgl_set_light_n_(uintptr_t *gr, int *n, int *enable) { _GR_->Light(*n, *enable); } void MGL_EXPORT mgl_add_light_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z) { _GR_->AddLight(*n,mglPoint(*x,*y,*z)); } void MGL_EXPORT mgl_add_light_ext_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z, char *c, mreal *br, mreal *ap, int) { _GR_->AddLight(*n,mglPoint(*x,*y,*z),*c,*br,*ap); } void MGL_EXPORT mgl_add_light_loc_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z, mreal *dx, mreal *dy, mreal *dz, char *c, mreal *br, mreal *ap, int) { _GR_->AddLight(*n,mglPoint(*x,*y,*z),mglPoint(*dx,*dy,*dz),*c,*br,*ap); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mat_push_(uintptr_t *gr) { _GR_->Push(); } void MGL_EXPORT mgl_mat_pop_(uintptr_t *gr) { _GR_->Pop(); } void MGL_EXPORT mgl_clf_(uintptr_t *gr) { _GR_->Clf(); } void MGL_EXPORT mgl_clf_chr_(uintptr_t *gr, const char *ch, int) { _GR_->Clf(mglColor(*ch)); } void MGL_EXPORT mgl_clf_rgb_(uintptr_t *gr, mreal *r, mreal *g, mreal *b) { _GR_->Clf(mglColor(*r,*g,*b)); } void MGL_EXPORT mgl_clf_str_(uintptr_t *gr, const char *col, int l) { char *s=new char[l+1]; memcpy(s,col,l); s[l]=0; mgl_clf_str(_GR_,s); delete []s; } void MGL_EXPORT mgl_load_background_(uintptr_t *gr, const char *fn, mreal *a, int l) { char *s=new char[l+1]; memcpy(s,fn,l); s[l]=0; mgl_load_background(_GR_,s,*a); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_subplot_d_(uintptr_t *gr, int *nx,int *ny,int *m,const char *st, mreal *dx, mreal *dy,int l) { char *s=new char[l+1]; memcpy(s,st,l); s[l]=0; mgl_subplot_d(_GR_,*nx,*ny,*m,s,*dx,*dy); delete []s; } void MGL_EXPORT mgl_subplot_(uintptr_t *gr, int *nx,int *ny,int *m,const char *st,int l) { char *s=new char[l+1]; memcpy(s,st,l); s[l]=0; mgl_subplot(_GR_,*nx,*ny,*m,s); delete []s; } void MGL_EXPORT mgl_multiplot_(uintptr_t *gr, int *nx,int *ny,int *m,int *dx,int *dy,const char *st,int l) { char *s=new char[l+1]; memcpy(s,st,l); s[l]=0; mgl_multiplot(_GR_,*nx,*ny,*m,*dx,*dy,s); delete []s; } void MGL_EXPORT mgl_multiplot_d_(uintptr_t *gr, int *nx,int *ny,int *m,int *dx,int *dy,const char *st, mreal *sx, mreal *sy,int l) { char *s=new char[l+1]; memcpy(s,st,l); s[l]=0; mgl_multiplot_d(_GR_,*nx,*ny,*m,*dx,*dy,s, *sx, *sy); delete []s; } void MGL_EXPORT mgl_inplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2) { _GR_->InPlot(*x1,*x2,*y1,*y2,false); } void MGL_EXPORT mgl_relplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2) { _GR_->InPlot(*x1,*x2,*y1,*y2,true); } void MGL_EXPORT mgl_columnplot_(uintptr_t *gr, int *num, int *i, mreal *d) { mgl_columnplot(_GR_,*num,*i,*d); } void MGL_EXPORT mgl_gridplot_(uintptr_t *gr, int *nx, int *ny, int *i, mreal *d) { mgl_gridplot(_GR_,*nx,*ny,*i,*d); } void MGL_EXPORT mgl_stickplot_(uintptr_t *gr, int *num, int *i, mreal *tet, mreal *phi) { _GR_->StickPlot(*num, *i, *tet, *phi); } void MGL_EXPORT mgl_shearplot_(uintptr_t *gr, int *num, int *i, mreal *sy, mreal *sx, mreal *xd, mreal *yd) { _GR_->ShearPlot(*num,*i,*sx,*sy,*xd,*yd); } void MGL_EXPORT mgl_title_(uintptr_t *gr, const char *title, const char *stl, mreal *size, int l,int m) { char *t=new char[l+1]; memcpy(t,title,l); t[l]=0; char *s=new char[m+1]; memcpy(s,stl,m); s[m]=0; _GR_->Title(t,s,*size); delete []s; delete []t; } void MGL_EXPORT mgl_aspect_(uintptr_t *gr, mreal *Ax, mreal *Ay, mreal *Az) { _GR_->Aspect(*Ax,*Ay,*Az); } void MGL_EXPORT mgl_shear_(uintptr_t *gr, mreal *Sx, mreal *Sy) { _GR_->Shear(*Sx,*Sy); } void MGL_EXPORT mgl_rotate_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY) { _GR_->Rotate(*TetX,*TetZ,*TetY); } void MGL_EXPORT mgl_view_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY) { _GR_->View(*TetX,*TetZ,*TetY); } void MGL_EXPORT mgl_zoom_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *x2, mreal *y2) { _GR_->Zoom(*x1,*y1,*x2,*y2); } void MGL_EXPORT mgl_rotate_vector_(uintptr_t *gr, mreal *Tet, mreal *x, mreal *y, mreal *z) { _GR_->RotateN(*Tet,*x,*y,*z); } void MGL_EXPORT mgl_perspective_(uintptr_t *gr, mreal *val) { _GR_->Perspective(*val); } void MGL_EXPORT mgl_ask_perspective_(uintptr_t *gr, mreal *val) { mgl_ask_perspective(_GR_,*val); } //----------------------------------------------------------------------------- MGL_EXPORT const unsigned char *mgl_get_rgb_(uintptr_t *gr) { return gr ? _GR_->GetBits():0; } MGL_EXPORT const unsigned char *mgl_get_rgba_(uintptr_t *gr){ return gr ? _GR_->GetRGBA():0; } MGL_EXPORT_PURE const unsigned char* mgl_get_background_(uintptr_t* gr) { return gr ? _GR_->GetBackground():0; } int MGL_EXPORT mgl_get_width_(uintptr_t *gr) { return gr ? _GR_->GetWidth():0; } int MGL_EXPORT mgl_get_height_(uintptr_t *gr) { return gr ? _GR_->GetHeight():0;} void MGL_EXPORT mgl_calc_xyz_(uintptr_t *gr, int *xs, int *ys, mreal *x, mreal *y, mreal *z) { mglPoint p = _GR_->CalcXYZ(*xs,*ys); *x = p.x; *y = p.y; *z = p.z; } void MGL_EXPORT mgl_calc_scr_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, int *xs, int *ys) { _GR_->CalcScr(mglPoint(*x,*y,*z),xs,ys); } void MGL_EXPORT mgl_set_obj_id_(uintptr_t *gr, int *id) { _GR_->SetObjId(*id); } int MGL_EXPORT_PURE mgl_get_obj_id_(uintptr_t *gr, int *x, int *y) { return _GR_->GetObjId(*x,*y); } int MGL_EXPORT_PURE mgl_get_spl_id_(uintptr_t *gr, int *x, int *y) { return _GR_->GetSplId(*x,*y); } //----------------------------------------------------------------------------- double mgl_size_scl = 1; HMGL MGL_EXPORT mgl_create_graph(int width, int height) { return new mglCanvas(width,height); } void MGL_EXPORT mgl_delete_graph(HMGL gr) { if(gr) delete gr; } void MGL_EXPORT mgl_set_size_scl(double scl){ if(scl>0) mgl_size_scl = scl; } void MGL_EXPORT mgl_set_size(HMGL gr, int width, int height) { mglCanvas *g = dynamic_cast(gr); width = int(mgl_size_scl*width); height = int(mgl_size_scl*height); if(g) g->SetSize(width, height); } void MGL_EXPORT mgl_scale_size(HMGL gr, int width, int height) { mglCanvas *g = dynamic_cast(gr); width = int(mgl_size_scl*width); height = int(mgl_size_scl*height); if(g) g->SetSize(width, height, false); } void MGL_EXPORT mgl_set_def_param(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->DefaultPlotParam(); } void MGL_EXPORT mgl_combine_gr(HMGL gr, HMGL in) { const mglCanvas *gg = dynamic_cast(in); mglCanvas *g = dynamic_cast(gr); if(g && gg) g->Combine(gg); } void MGL_EXPORT mgl_set_bbox(HMGL gr, int x1, int y1, int x2, int y2) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetBBox(x1,y1,x2,y2); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_tick_len(HMGL gr, double len, double stt) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTickLen(len,stt); } void MGL_EXPORT mgl_set_axis_stl(HMGL gr, const char *stl, const char *tck, const char *sub) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetAxisStl(stl,tck,sub); } void MGL_EXPORT mgl_tune_ticks(HMGL gr, int tune, double pos) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTuneTicks(tune,pos); } void MGL_EXPORT mgl_adjust_ticks(HMGL gr, const char *dir) { mgl_adjust_ticks_ext(gr,dir,""); } void MGL_EXPORT mgl_adjust_ticks_ext(HMGL gr, const char *dir, const char *stl) { mglCanvas *g = dynamic_cast(gr); if(g) g->AdjustTicks(dir,true,stl); } void MGL_EXPORT mgl_set_ticks(HMGL gr, char dir, double d, int ns, double org) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTicks(dir,d,ns,org); } void MGL_EXPORT mgl_set_ticks_factw(HMGL gr, char dir, double d, int ns, double org, const wchar_t *fact) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTicks(dir,d,ns,org,fact); } void MGL_EXPORT mgl_set_ticks_fact(HMGL gr, char dir, double d, int ns, double org, const char *fact) { MGL_TO_WCS(fact,mgl_set_ticks_factw(gr,dir,d,ns,org,wcs)); } void MGL_EXPORT mgl_set_ticks_str(HMGL gr, char dir, const char *lbl, int add) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTicksVal(dir,lbl,add); } void MGL_EXPORT mgl_set_ticks_wcs(HMGL gr, char dir, const wchar_t *lbl, int add) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTicksVal(dir,lbl,add); } void MGL_EXPORT mgl_set_ticks_val(HMGL gr, char dir, HCDT val, const char *lbl, int add) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTicksVal(dir,val,lbl,add); } void MGL_EXPORT mgl_set_ticks_valw(HMGL gr, char dir, HCDT val, const wchar_t *lbl, int add) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTicksVal(dir,val,lbl,add); } void MGL_EXPORT mgl_add_tick(HMGL gr, char dir, double val, const char *lbl) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddTick(dir,val,lbl); } void MGL_EXPORT mgl_add_tickw(HMGL gr, char dir, double val, const wchar_t *lbl) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddTick(dir,val,lbl); } void MGL_EXPORT mgl_set_tick_templ(HMGL gr, char dir, const char *templ) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTickTempl(dir,templ); } void MGL_EXPORT mgl_set_tick_templw(HMGL gr, char dir, const wchar_t *templ) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTickTempl(dir,templ); } void MGL_EXPORT mgl_set_ticks_time(HMGL gr, char dir, double d, const char *t) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTickTime(dir,d,t); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_box(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->Box(); } void MGL_EXPORT mgl_box_str(HMGL gr, const char *col, int ticks) { mglCanvas *g = dynamic_cast(gr); if(g) g->Box(col,ticks); } void MGL_EXPORT mgl_axis(HMGL gr, const char *dir, const char *stl, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Axis(dir,stl,opt); } void MGL_EXPORT mgl_axis_grid(HMGL gr, const char *dir,const char *pen, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Grid(dir,pen,opt); } void MGL_EXPORT mgl_label(HMGL gr, char dir, const char *text, double pos, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Label(dir,text,pos,opt); } void MGL_EXPORT mgl_labelw(HMGL gr, char dir, const wchar_t *text, double pos, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Labelw(dir,text,pos,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_colorbar(HMGL gr, const char *sch) { mglCanvas *g = dynamic_cast(gr); if(g) g->Colorbar(sch); } void MGL_EXPORT mgl_colorbar_ext(HMGL gr, const char *sch, double x, double y, double w, double h) { mglCanvas *g = dynamic_cast(gr); if(g) g->Colorbar(sch,x,y,w,h); } void MGL_EXPORT mgl_colorbar_val(HMGL gr, HCDT dat, const char *sch) { mglCanvas *g = dynamic_cast(gr); if(g) g->Colorbar(dat,sch); } void MGL_EXPORT mgl_colorbar_val_ext(HMGL gr, HCDT dat, const char *sch,double x, double y, double w, double h) { mglCanvas *g = dynamic_cast(gr); if(g) g->Colorbar(dat,sch,x,y,w,h); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_add_legend(HMGL gr, const char *text,const char *style) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddLegend(text,style); } void MGL_EXPORT mgl_add_legendw(HMGL gr, const wchar_t *text,const char *style) { mglCanvas *g = dynamic_cast(gr); if(g) g->AddLegend(text,style); } void MGL_EXPORT mgl_clear_legend(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->ClearLegend(); } void MGL_EXPORT mgl_legend_pos(HMGL gr, double x, double y, const char *font, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Legend(x,y,font,opt); } void MGL_EXPORT mgl_legend(HMGL gr, int where, const char *font, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Legend(where,font,opt); } void MGL_EXPORT mgl_set_legend_marks(HMGL gr, int num) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetLegendMarks(num); } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_create_graph_(int *width, int *height) { return uintptr_t(new mglCanvas(*width,*height)); } void MGL_EXPORT mgl_delete_graph_(uintptr_t *gr) { delete _GR_; } void MGL_EXPORT mgl_set_size_scl_(double *scl) { mgl_set_size_scl(*scl); } void MGL_EXPORT mgl_set_size_(uintptr_t *gr, int *width, int *height) { mgl_set_size(_GR_,*width,*height); } void MGL_EXPORT mgl_scale_size_(uintptr_t *gr, int *width, int *height) { mgl_scale_size(_GR_,*width,*height); } void MGL_EXPORT mgl_set_def_param_(uintptr_t *gr) { _GR_->DefaultPlotParam(); } void MGL_EXPORT mgl_combine_gr_(uintptr_t *gr, uintptr_t *in) { _GR_->Combine((mglCanvas *)in); } void MGL_EXPORT mgl_set_bbox_(uintptr_t *gr, int *x1, int *y1, int *x2, int *y2) { _GR_->SetBBox(*x1,*y1,*x2,*y2); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_ticks_fact_(uintptr_t *gr, char *dir, double *d, int *ns, double *org, const char *fact,int,int l) { char *s=new char[l+1]; memcpy(s,fact,l); s[l]=0; mgl_set_ticks_fact(_GR_,*dir,*d,*ns,*org,s); delete []s; } void MGL_EXPORT mgl_set_tick_len_(uintptr_t *gr, mreal *len, mreal *stt) { _GR_->SetTickLen(*len, *stt); } void MGL_EXPORT mgl_set_axis_stl_(uintptr_t *gr, const char *stl, const char *tck, const char *sub, int l,int m,int n) { char *a=new char[l+1]; memcpy(a,stl,l); a[l]=0; char *t=new char[m+1]; memcpy(t,tck,m); t[m]=0; char *s=new char[n+1]; memcpy(s,sub,n); s[n]=0; _GR_->SetAxisStl(a,t,s); delete []a; delete []s; delete []t; } void MGL_EXPORT mgl_adjust_ticks_(uintptr_t *gr, const char *dir, int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; _GR_->AdjustTicks(s,true); delete []s; } void MGL_EXPORT mgl_adjust_ticks_ext_(uintptr_t *gr, const char *dir, const char *stl, int l, int m) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; char *f=new char[m+1]; memcpy(f,stl,m); f[m]=0; _GR_->AdjustTicks(s,true,f); delete []s; delete []f; } void MGL_EXPORT mgl_set_ticks_(uintptr_t *gr, char *dir, mreal *d, int *ns, mreal *org, int) { _GR_->SetTicks(*dir, *d, *ns, *org); } void MGL_EXPORT mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *lbl, int *add,int,int l) { char *s=new char[l+1]; memcpy(s,lbl,l); s[l]=0; _GR_->SetTicksVal(*dir,s,*add); delete []s; } void MGL_EXPORT mgl_set_ticks_val_(uintptr_t *gr, const char *dir, uintptr_t *val, const char *lbl, int *add,int,int l) { char *s=new char[l+1]; memcpy(s,lbl,l); s[l]=0; _GR_->SetTicksVal(*dir,_DA_(val),s,*add); delete []s; } void MGL_EXPORT mgl_add_tick_(uintptr_t *gr, const char *dir, mreal *val, const char *lbl, int,int l) { char *s=new char[l+1]; memcpy(s,lbl,l); s[l]=0; mgl_add_tick(_GR_,*dir,*val,s); delete []s; } void MGL_EXPORT mgl_tune_ticks_(uintptr_t *gr, int *tune, mreal *fact_pos) { _GR_->SetTuneTicks(*tune, *fact_pos); } void MGL_EXPORT mgl_set_tick_templ_(uintptr_t *gr, const char *dir, const char *templ,int,int l) { char *s=new char[l+1]; memcpy(s,templ,l); s[l]=0; _GR_->SetTickTempl(*dir,s); delete []s; } void MGL_EXPORT mgl_set_ticks_time_(uintptr_t *gr, const char *dir, mreal *d, const char *t,int,int l) { char *s=new char[l+1]; memcpy(s,t,l); s[l]=0; _GR_->SetTickTime(*dir,*d,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_box_(uintptr_t *gr) { _GR_->Box(); } void MGL_EXPORT mgl_box_str_(uintptr_t *gr, const char *col, int *ticks, int l) { char *s=new char[l+1]; memcpy(s,col,l); s[l]=0; _GR_->Box(s,*ticks); delete []s; } void MGL_EXPORT mgl_axis_(uintptr_t *gr, const char *dir, const char *stl, const char *opt,int l,int n,int m) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; char *p=new char[n+1]; memcpy(p,stl,l); p[n]=0; char *o=new char[m+1]; memcpy(o,opt,m); o[m]=0; _GR_->Axis(s,p,o); delete []s; delete []p; delete []o; } void MGL_EXPORT mgl_axis_grid_(uintptr_t *gr, const char *dir,const char *pen, const char *opt,int l,int n,int m) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; char *p=new char[n+1]; memcpy(p,pen,n); p[n]=0; char *o=new char[m+1]; memcpy(o,opt,m); o[m]=0; _GR_->Grid(s,p,o); delete []s; delete []p; delete []o; } void MGL_EXPORT mgl_label_(uintptr_t *gr, const char *dir, const char *text, mreal *pos, const char *opt,int,int l,int m) { char *s=new char[l+1]; memcpy(s,text,l); s[l]=0; char *o=new char[m+1]; memcpy(o,opt,m); o[m]=0; _GR_->Label(*dir, s, *pos, o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_colorbar_(uintptr_t *gr, const char *sch,int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; _GR_->Colorbar(s); delete []s; } void MGL_EXPORT mgl_colorbar_ext_(uintptr_t *gr, const char *sch, mreal *x, mreal *y, mreal *w, mreal *h, int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; _GR_->Colorbar(s,*x,*y,*w,*h); delete []s; } void MGL_EXPORT mgl_colorbar_val_(uintptr_t *gr, uintptr_t *dat, const char *sch,int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; _GR_->Colorbar(_DA_(dat), s); delete []s; } void MGL_EXPORT mgl_colorbar_val_ext_(uintptr_t *gr, uintptr_t *dat, const char *sch, mreal *x, mreal *y, mreal *w, mreal *h, int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; _GR_->Colorbar(_DA_(dat),s,*x,*y,*w,*h); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_add_legend_(uintptr_t *gr, const char *text,const char *style,int l,int n) { char *s=new char[l+1]; memcpy(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,style,n); f[n]=0; _GR_->AddLegend(s,f); delete []s; delete []f; } void MGL_EXPORT mgl_clear_legend_(uintptr_t *gr) { if(gr) _GR_->ClearLegend(); } void MGL_EXPORT mgl_legend_pos_(uintptr_t *gr, mreal *x, mreal *y, const char *font, const char *opt,int l,int m) { char *s=new char[l+1]; memcpy(s,font,l); s[l]=0; char *o=new char[m+1]; memcpy(o,opt,m); o[m]=0; _GR_->Legend(*x, *y, s, o); delete []s; delete []o; } void MGL_EXPORT mgl_legend_(uintptr_t *gr, int *where, const char *font, const char *opt,int l,int m) { char *s=new char[l+1]; memcpy(s,font,l); s[l]=0; char *o=new char[m+1]; memcpy(o,opt,m); o[m]=0; _GR_->Legend(*where, s, o); delete []s; delete []o; } void MGL_EXPORT mgl_set_legend_marks_(uintptr_t *gr, int *num) { _GR_->SetLegendMarks(*num); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_plotfactor(HMGL gr, double val) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetPlotFactor(val); } void MGL_EXPORT mgl_set_plotfactor_(uintptr_t *gr, mreal *val) { _GR_->SetPlotFactor(*val); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_tick_shift(HMGL gr, double sx, double sy, double sz, double sc) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetTickShift(mglPoint(sx,sy,sz,sc)); } void MGL_EXPORT mgl_set_tick_shift_(uintptr_t *gr, mreal *sx, mreal *sy, mreal *sz, mreal *sc) { _GR_->SetTickShift(mglPoint(*sx,*sy,*sz,*sc)); } //----------------------------------------------------------------------------- #if !MGL_HAVE_PNG void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char *descr, int make_pdf) { mgl_set_global_warn(_("PNG support was disabled. Please, enable it and rebuild MathGL.")); } void MGL_EXPORT mgl_write_prc_(uintptr_t *graph, const char *fname,const char *descr, int *make_pdf,int lf,int ld) { mgl_set_global_warn(_("PNG support was disabled. Please, enable it and rebuild MathGL.")); } #endif //----------------------------------------------------------------------------- void MGL_EXPORT mgl_finish(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->Finish(); } void MGL_EXPORT mgl_finish_(uintptr_t *gr) { _GR_->Finish(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_rasterize(HMGL gr) { mglCanvas *g = dynamic_cast(gr); if(g) g->Rasterize(); } void MGL_EXPORT mgl_rasterize_(uintptr_t *gr) { _GR_->Rasterize(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pen_delta(HMGL gr, double d) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetPenDelta(d); } void MGL_EXPORT mgl_pen_delta_(uintptr_t *gr, double *d) { _GR_->SetPenDelta(*d); } //----------------------------------------------------------------------------- mathgl-2.4.4/src/prc.cpp0000644000175000017500000007646113513030041015242 0ustar alastairalastair/*************************************************************************** * prc.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "mgl2/canvas.h" #include "mgl2/canvas_cf.h" #include "prc/oPRCFile.h" #include #include #include #include #include #include #if MGL_HAVE_PDF #include #include #include #include #endif // MGL_HAVE_PDF #undef _GR_ #define _GR_ ((mglCanvas *)(*gr)) #define _Gr_ ((mglCanvas *)(gr)) //----------------------------------------------------------------------------- void mglTexture::GetRGBAPRC(unsigned char *f) const { for(size_t i=0;i<256;i++) { mglColor c1 = col[2*i], c2 = col[2*i+1], c; for(size_t j=0;j<256;j++) { size_t i0 = 4*(j+256*(255-i)); c = c1 + (c2-c1)*(j/255.); f[i0] = int(255*c.r); f[i0+1] = int(255*c.g); f[i0+2] = int(255*c.b); f[i0+3] = int(255*c.a); } } } //----------------------------------------------------------------------------- int MGL_NO_EXPORT mgl_tga_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_pnga_save(const char *fname, int w, int h, unsigned char **p); void MGL_NO_EXPORT mgl_printf(void *fp, bool gz, const char *str, ...); //----------------------------------------------------------------------------- struct prctriangle { uint32_t pi[3]; uint32_t ti[3]; }; //----------------------------------------------------------------------------- struct prctriangles { prctriangles(const HMGL g) : samecolour(true), samealpha(true), gr(g), ntxt(g->GetTxtNum()), vertexcolor(g->get(MGL_PREFERVC)) {} std::map points; std::map texturecoords; std::map colours; std::vector triangles; RGBAColour commoncolour; bool samecolour; float commonalpha; bool samealpha; const HMGL gr; const size_t ntxt; bool vertexcolor; uint32_t addPoint(const mglPnt& p) { const PRCVector3d point(p.x,p.y,p.z); std::map::iterator pPoint = points.find(point); if(pPoint!=points.end()) return pPoint->second; else { const uint32_t point_index = (uint32_t)points.size(); points.insert(std::make_pair(point,point_index)); return point_index; } } uint32_t addPoint(float x, float y, float z) { const PRCVector3d point(x,y,z); std::map::iterator pPoint = points.find(point); if(pPoint!=points.end()) return pPoint->second; else { const uint32_t point_index = (uint32_t)points.size(); points.insert(std::make_pair(point,point_index)); return point_index; } } void writePoints(double (*P)[3]) { for(std::map::const_iterator pPoint = points.begin(); pPoint != points.end(); pPoint++) { P[pPoint->second][0] = pPoint->first.x; P[pPoint->second][1] = pPoint->first.y; P[pPoint->second][2] = pPoint->first.z; } } void addTriangle(uint32_t ti, uint32_t pi1, uint32_t pi2, uint32_t pi3) { prctriangle triangle; triangle.pi[0] = pi1; triangle.pi[1] = pi2; triangle.pi[2] = pi3; triangle.ti[0] = ti; triangle.ti[1] = ti; triangle.ti[2] = ti; triangles.push_back(triangle); } void addTriangle(uint32_t pi1, uint32_t ti1, uint32_t pi2, uint32_t ti2, uint32_t pi3, uint32_t ti3) { prctriangle triangle; triangle.pi[0] = pi1; triangle.pi[1] = pi2; triangle.pi[2] = pi3; triangle.ti[0] = ti1; triangle.ti[1] = ti2; triangle.ti[2] = ti3; triangles.push_back(triangle); } uint32_t addColourInfo(const mglPnt& p) { const RGBAColour colour(p.r,p.g,p.b,p.a); if (colours.empty() && texturecoords.empty()) { commoncolour = colour; commonalpha = p.a; } if (samecolour) { if (commoncolour != colour) samecolour = false; } if (samealpha) { if (commonalpha != p.a) samealpha = false; } if (vertexcolor) { std::map::iterator pColour = colours.find(colour); if(pColour!=colours.end()) return pColour->second; else { const uint32_t colour_index = (uint32_t)colours.size(); colours.insert(std::make_pair(colour,colour_index)); return colour_index; } } else { const mreal gap = 1./512; const double u = p.ta*(1-2*gap)+gap; const double v = ((p.c-floor(p.c))*(1-2*gap) + gap + floor(p.c))/ntxt; const PRCVector2d point(u, v); std::map::iterator pPoint = texturecoords.find(point); if(pPoint!=texturecoords.end()) return pPoint->second; else { const uint32_t point_index = (uint32_t)texturecoords.size(); texturecoords.insert(std::make_pair(point,point_index)); return point_index; } } } void writeTextureCoords(double (*T)[2]) { for(std::map::const_iterator pPoint = texturecoords.begin(); pPoint != texturecoords.end(); pPoint++) { T[pPoint->second][0] = pPoint->first.x; T[pPoint->second][1] = pPoint->first.y; } } void writeColours(RGBAColour *C) { for(std::map::const_iterator pColour = colours.begin(); pColour != colours.end(); pColour++) { C[pColour->second] = pColour->first; } } }; //----------------------------------------------------------------------------- /* structure to store PNG image bytes */ struct png_buf { uint8_t *data; size_t size; }; //----------------------------------------------------------------------------- void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { struct png_buf* p=(struct png_buf*)png_get_io_ptr(png_ptr); size_t nsize = p->size + length; /* allocate or grow buffer */ if(p->data) p->data = (uint8_t*)realloc(p->data, nsize); else p->data = (uint8_t*)malloc(nsize); if(!p->data) png_error(png_ptr, "Write Error - no mem"); /* copy new bytes to end of buffer */ memcpy(p->data + p->size, data, length); p->size += length; } //----------------------------------------------------------------------------- void my_png_flush(png_structp /*png_ptr*/) { } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char* /*descr*/, int make_pdf) { mglCanvas *gg = dynamic_cast(gr); if(!gg || gr->GetPrmNum()==0) return; // nothing to do { long mmin=0,mmax=0,m; for(size_t i=0;iGrp.size();i++) // prepare array of indirect indexing { m = gr->Grp[i].Id; if(mmmax) mmax=m; } long *ng = new long[mmax-mmin+1]; for(size_t i=0;iGrp.size();i++) ng[gr->Grp[i].Id-mmin] = i; for(size_t i=0;iGetPrmNum());i++) // collect data for groups // it is rather expensive (extra 4b per primitive) but need for export to 3D { m = gr->GetPrm(i,false).id-mmin; if(m>=0 && mGrp[ng[m]].p.push_back(i); } delete []ng; } const size_t len=strlen(fname); char * const tname = new char[len+9]; strcpy(tname,fname); if (strncmp(tname+len-4, ".prc", 4)!=0) { tname[len]='.'; tname[len+1]='p'; tname[len+2]='r'; tname[len+3]='c'; tname[len+4]='\0'; } oPRCFile file(tname); PRCoptions grpopt; grpopt.tess = true; grpopt.closed = gr->get(MGL_ONESIDED); // set to true to make only front side visible // grpopt.no_break = true; // grpopt.do_break = false; grpopt.crease_angle = 80; uint32_t materialMathGLid = m1; if (gr->get(MGL_PREFERVC)) { const PRCmaterial materialMathGL( RGBAColour(0.1,0.1,0.1,1), // ambient RGBAColour(1.0,1.0,1.0,1), // diffuse RGBAColour(0.1,0.1,0.1,1), // emissive RGBAColour(0.0,0.0,0.0,1), // spectral 1.0,0.1 // alpha, shininess ); materialMathGLid = file.addMaterial(materialMathGL); } else { png_buf buffer; buffer.data = (uint8_t*)malloc(1024);; buffer.size = 0; const size_t ntxt = gr->GetTxtNum(); // prepare texture file (PNG) const png_uint_32 width=256, height=256*png_uint_32(ntxt); png_bytep buf = new png_byte[4*width*height]; png_bytepp pbuf= new png_bytep[height]; for(size_t i=0;iGetTxt(i).GetRGBAPRC(buf+(ntxt-1-i)*256*width*4); png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); png_infop info_ptr = png_create_info_struct(png_ptr); png_set_write_fn(png_ptr, &buffer, my_png_write_data, my_png_flush); png_set_filter(png_ptr, 0, PNG_ALL_FILTERS); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(png_ptr, info_ptr, pbuf); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); delete []pbuf; delete []buf; PRCtexture* t = new PRCtexture(); t->mapping = PRC_TEXTURE_MAPPING_DIFFUSE; t->components = PRC_TEXTURE_MAPPING_COMPONENTS_RGBA; // Modulate for OBJ compatibilty, Replace is a better setting t->function = KEPRCTextureFunction_Replace; // Repeat for OBJ compatibilty, ClampToEdge is a better setting t->wrapping_mode_S = KEPRCTextureWrappingMode_ClampToEdge; t->wrapping_mode_T = KEPRCTextureWrappingMode_ClampToEdge; t->data = buffer.data; t->size = buffer.size; t->format = KEPRCPicture_PNG; PRCmaterial m( RGBAColour(0.0,0.0,0.0,1), // ambient RGBAColour(1.0,1.0,1.0,1), // diffuse RGBAColour(0.0,0.0,0.0,1), // emissive RGBAColour(0.0,0.0,0.0,1), // spectral 1.0,0.1); // alpha, shininess materialMathGLid = file.addTexturedMaterial(m,1,&t); delete t; // char * const pngname = new char[len+100]; // strcpy(pngname, "test_texture_"); // strcat(pngname,tname); // const size_t tlen=strlen(pngname)-4; // pngname[tlen+1]='p'; pngname[tlen+2]='n'; pngname[tlen+3]='g'; // FILE *fp = fopen(pngname, "wb"); // fwrite(buffer.data, 1, buffer.size, fp); // fclose(fp); // delete[] pngname; free(buffer.data); buffer.data = NULL; } // primitive definition in groups mglPnt p0; const double width = gg->GetWidth(); const double height = gg->GetHeight(); const double depth = sqrt(width*height); p0.x = width/2.; p0.y = height/2.; p0.z = (1.f-sqrt(width*height)/(2*depth))*depth; for(size_t i=0;iGrp.size();i++) { mglGroup& grp = gr->Grp[i]; std::vector& prm = grp.p; prctriangles group(gr); file.begingroup(grp.Lbl.c_str(),&grpopt); for(size_t j=0;jGetPrm(prm[j],false); const double w = (q.w>1)?(q.w*sqrt(gr->FontFactor()/400.)):1; const mglPnt p = gr->GetPnt(q.n1) - p0; const mreal size = q.s; { switch(q.type) { case 0: if (gr->GetPnt(q.n1).a > mgl_min_a) { const char type = q.n4; float ss=size; const RGBAColour c(p.r, p.g, p.b, p.a); if(!strchr("xsSoO",type)) ss *= 1.1; if(type=='.' || ss==0) { const double P[3] = {p.x, p.y, p.z}; file.addPoint(P, c, w); } else switch(type) { case 'P': { const double P[5][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z }, { p.x-ss,p.y+ss,p.z }, { p.x-ss,p.y-ss,p.z } }; file.addLine(5, P, c, w); } case '+': { const double P1[2][3] = { { p.x-ss,p.y,p.z }, { p.x+ss,p.y,p.z } }; file.addLine(2, P1, c, w); const double P2[2][3] = { { p.x,p.y-ss,p.z }, { p.x,p.y+ss,p.z } }; file.addLine(2, P2, c, w); } break; case 'X': { const double P[5][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z }, { p.x-ss,p.y+ss,p.z }, { p.x-ss,p.y-ss,p.z } }; file.addLine(5, P, c, w); const double P1[2][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z } }; file.addLine(2, P1, c, w); const double P2[2][3] = { { p.x+ss,p.y-ss,p.z }, { p.x-ss,p.y+ss,p.z } }; file.addLine(2, P2, c, w); } break; case 'x': { const double P1[2][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z } }; file.addLine(2, P1, c, w); const double P2[2][3] = { { p.x+ss,p.y-ss,p.z }, { p.x-ss,p.y+ss,p.z } }; file.addLine(2, P2, c, w); } break; case 'S': { const uint32_t ti = group.addColourInfo(p); const uint32_t pi1 = group.addPoint(p.x-ss,p.y-ss,p.z); const uint32_t pi2 = group.addPoint(p.x+ss,p.y-ss,p.z); const uint32_t pi3 = group.addPoint(p.x-ss,p.y+ss,p.z); const uint32_t pi4 = group.addPoint(p.x+ss,p.y+ss,p.z); group.addTriangle(ti, pi1, pi2, pi3); group.addTriangle(ti, pi4, pi3, pi2); } break; case 's': { const double P[5][3] = { { p.x-ss,p.y-ss,p.z }, { p.x+ss,p.y-ss,p.z }, { p.x+ss,p.y+ss,p.z }, { p.x-ss,p.y+ss,p.z }, { p.x-ss,p.y-ss,p.z } }; file.addLine(5, P, c, w); } break; case 'D': { const uint32_t ti = group.addColourInfo(p); const uint32_t pi1 = group.addPoint(p.x,p.y-ss,p.z); const uint32_t pi2 = group.addPoint(p.x+ss,p.y,p.z); const uint32_t pi3 = group.addPoint(p.x-ss,p.y,p.z); const uint32_t pi4 = group.addPoint(p.x,p.y+ss,p.z); group.addTriangle(ti, pi1, pi2, pi3); group.addTriangle(ti, pi4, pi3, pi2); } break; case 'd': { const double P[5][3] = { { p.x,p.y-ss,p.z }, { p.x+ss,p.y,p.z }, { p.x,p.y+ss,p.z }, { p.x-ss,p.y,p.z }, { p.x,p.y-ss,p.z } }; file.addLine(5, P, c, w); } break; case 'Y': { const double P1[3][3] = { { p.x, p.y-ss, p.z }, { p.x, p.y, p.z }, { p.x+0.8*ss,p.y+0.6*ss,p.z } }; file.addLine(3, P1, c, w); const double P2[2][3] = { { p.x, p.y, p.z }, { p.x-0.8*ss,p.y+0.6*ss,p.z } }; file.addLine(2, P2, c, w); } break; case '*': { const double P1[2][3] = { { p.x-ss,p.y,p.z }, { p.x+ss,p.y,p.z } }; file.addLine(2, P1, c, w); const double P2[2][3] = { { p.x-0.6*ss,p.y-0.8*ss,p.z }, { p.x+0.6*ss,p.y+0.8*ss,p.z } }; file.addLine(2, P2, c, w); const double P3[2][3] = { { p.x-0.6*ss,p.y+0.8*ss,p.z }, { p.x+0.6*ss,p.y-0.8*ss,p.z } }; file.addLine(2, P3, c, w); } break; case 'T': { const uint32_t ti = group.addColourInfo(p); const uint32_t pi1 = group.addPoint(p.x-ss,p.y-ss/2,p.z); const uint32_t pi2 = group.addPoint(p.x+ss,p.y-ss/2,p.z); const uint32_t pi3 = group.addPoint(p.x,p.y+ss,p.z); group.addTriangle(ti, pi1, pi2, pi3); } break; case '^': { const double P[4][3] = { { p.x-ss,p.y-ss/2,p.z }, { p.x+ss,p.y-ss/2,p.z }, { p.x, p.y+ss, p.z }, { p.x-ss,p.y-ss/2,p.z } }; file.addLine(4, P, c, w); } break; case 'V': { const uint32_t ti = group.addColourInfo(p); const uint32_t pi1 = group.addPoint(p.x-ss,p.y+ss/2,p.z); const uint32_t pi2 = group.addPoint(p.x,p.y-ss,p.z); const uint32_t pi3 = group.addPoint(p.x+ss,p.y+ss/2,p.z); group.addTriangle(ti, pi1, pi2, pi3); } break; case 'v': { const double P[4][3] = { { p.x-ss,p.y+ss/2,p.z }, { p.x+ss,p.y+ss/2,p.z }, { p.x, p.y-ss, p.z }, { p.x-ss,p.y+ss/2,p.z } }; file.addLine(4, P, c, w); } break; case 'L': { const uint32_t ti = group.addColourInfo(p); const uint32_t pi1 = group.addPoint(p.x+ss/2,p.y+ss,p.z); const uint32_t pi2 = group.addPoint(p.x-ss, p.y, p.z); const uint32_t pi3 = group.addPoint(p.x+ss/2,p.y-ss,p.z); group.addTriangle(ti, pi1, pi2, pi3); } break; case '<': { const double P[4][3] = { { p.x+ss/2,p.y+ss,p.z }, { p.x+ss/2,p.y-ss,p.z }, { p.x-ss, p.y, p.z }, { p.x+ss/2,p.y+ss,p.z } }; file.addLine(4, P, c, w); } break; case 'R': { const uint32_t ti = group.addColourInfo(p); const uint32_t pi1 = group.addPoint(p.x-ss/2,p.y+ss,p.z); const uint32_t pi2 = group.addPoint(p.x-ss/2,p.y-ss,p.z); const uint32_t pi3 = group.addPoint(p.x+ss, p.y, p.z); group.addTriangle(ti, pi1, pi2, pi3); } break; case '>': { const double P[4][3] = { { p.x-ss/2,p.y+ss,p.z }, { p.x-ss/2,p.y-ss,p.z }, { p.x+ss, p.y, p.z }, { p.x-ss/2,p.y+ss,p.z } }; file.addLine(4, P, c, w); } break; case 'O': { const uint32_t ti = group.addColourInfo(p); const uint32_t cpi=group.addPoint(p); uint32_t pnti[21]; for(size_t k=0;k<=20;k++) pnti[k]=group.addPoint(p.x+ss*cos(k*M_PI/10),p.y+ss*sin(k*M_PI/10),p.z); for(size_t k=0;k<20;k++) { group.addTriangle(ti, pnti[k], pnti[k+1], cpi); } } break; case 'C': { const double P[3] = {p.x, p.y, p.z}; file.addPoint(P, c, w); } case 'o': { double P[21][3]; for(size_t k=0;k<=20;k++) { P[k][0] = p.x+ss*cos(k*M_PI/10); P[k][1] = p.y+ss*sin(k*M_PI/10); P[k][2] = p.z; } file.addLine(21, P, c, w); } break; } } break; case 1: if (gr->GetPnt(q.n1).a > mgl_min_a || gr->GetPnt(q.n2).a > mgl_min_a) { const mglPnt p1 = gr->GetPnt(q.n1) - p0, p2 = gr->GetPnt(q.n2) - p0; const uint32_t n = 2; double P[2][3]; P[0][0] = p1.x; P[0][1] = p1.y; P[0][2] = p1.z; P[1][0] = p2.x; P[1][1] = p2.y; P[1][2] = p2.z; const RGBAColour colour((p1.r+p2.r)/2, (p1.g+p2.g)/2, (p1.b+p2.b)/2, (p1.a+p2.a)/2); file.addLine(n, P, colour, w); } break; case 2: if (gr->GetPnt(q.n1).a > mgl_min_a || gr->GetPnt(q.n2).a > mgl_min_a || gr->GetPnt(q.n3).a > mgl_min_a) { const mglPnt p1 = gr->GetPnt(q.n1) - p0, p2 = gr->GetPnt(q.n2) - p0, p3 = gr->GetPnt(q.n3) - p0; prctriangle triangle; triangle.pi[0] = group.addPoint(p1); triangle.pi[1] = group.addPoint(p2); triangle.pi[2] = group.addPoint(p3); triangle.ti[0] = group.addColourInfo(p1); triangle.ti[1] = group.addColourInfo(p2); triangle.ti[2] = group.addColourInfo(p3); group.triangles.push_back(triangle); } break; case 3: if (gr->GetPnt(q.n1).a > mgl_min_a || gr->GetPnt(q.n2).a > mgl_min_a || gr->GetPnt(q.n3).a > mgl_min_a || gr->GetPnt(q.n4).a > mgl_min_a) { const mglPnt p1 = gr->GetPnt(q.n1) - p0; const uint32_t pi1 = group.addPoint(p1); const uint32_t ti1 = group.addColourInfo(p1); const mglPnt p2 = gr->GetPnt(q.n2) - p0; const uint32_t pi2 = group.addPoint(p2); const uint32_t ti2 = group.addColourInfo(p2); const mglPnt p3 = gr->GetPnt(q.n3) - p0; const uint32_t pi3 = group.addPoint(p3); const uint32_t ti3 = group.addColourInfo(p3); const mglPnt p4 = gr->GetPnt(q.n4) - p0; const uint32_t pi4 = group.addPoint(p4); const uint32_t ti4 = group.addColourInfo(p4); prctriangle triangle1, triangle2; triangle1.pi[0] = pi1; triangle1.pi[1] = pi2; triangle1.pi[2] = pi3; triangle1.ti[0] = ti1; triangle1.ti[1] = ti2; triangle1.ti[2] = ti3; group.triangles.push_back(triangle1); triangle2.pi[0] = pi4; triangle2.pi[1] = pi3; triangle2.pi[2] = pi2; triangle2.ti[0] = ti4; triangle2.ti[1] = ti3; triangle2.ti[2] = ti2; group.triangles.push_back(triangle2); } break; case 4: if (gr->GetPnt(q.n1).a > mgl_min_a) { const mglPnt p = gr->GetPnt(q.n1) - p0; const mreal f = q.p/2, dx=p.u/2, dy=p.v/2; const mreal c=q.s*cos(q.w*M_PI/180), s=-q.s*sin(q.w*M_PI/180); const double b[4] = {c,-s, s,c}; long ik,il=0; const mglGlyph &g = gr->GetGlf(q.n4); const mreal dd = 0.004; if(q.n3&8) { if(!(q.n3&4)) // glyph_line(p,f,true, d); { const uint32_t ti = group.addColourInfo(p); const uint32_t p_4 = group.addPoint(p.x+b[0]*dx+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z); const uint32_t p_3 = group.addPoint(p.x+b[0]*dx+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z); const uint32_t p_2 = group.addPoint(p.x+b[0]*(dx+f)+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z); const uint32_t p_1 = group.addPoint(p.x+b[0]*(dx+f)+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z); group.addTriangle(ti, p_1, p_3, p_2); group.addTriangle(ti, p_4, p_2, p_3); } else // glyph_line(p,f,false, d); { const RGBAColour c(p.r, p.g, p.b, p.a); const double p_4[3] = {p.x+b[0]*dx+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z}; const double p_3[3] = {p.x+b[0]*dx+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z}; const double p_2[3] = {p.x+b[0]*(dx+f)+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z}; const double p_1[3] = {p.x+b[0]*(dx+f)+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z}; file.addSegment(p_1, p_2, c, w); file.addSegment(p_3, p_4, c, w); file.addSegment(p_1, p_3, c, w); file.addSegment(p_2, p_4, c, w); } } else { if(!(q.n3&4)) // glyph_fill(p,f,g, d); { for(ik=0;ikget(MGL_PREFERVC)) { const uint32_t nC = (uint32_t)group.colours.size(); RGBAColour *C = new RGBAColour[nC]; group.writeColours(C); uint32_t (*CI)[3] = new uint32_t[nI][3]; for(uint32_t k = 0; k(gr)->GetWidth(); // const HPDF_REAL height = dynamic_cast(gr)->GetHeight(); // const HPDF_REAL depth = sqrt(width*height); const HPDF_Rect rect = {0, 0, HPDF_REAL(width), HPDF_REAL(height)}; HPDF_Doc pdf; HPDF_Page page; HPDF_Annotation annot; HPDF_U3D u3d; HPDF_Dict view; pdf = HPDF_New (NULL, NULL); pdf->pdf_version = HPDF_VER_17; page = HPDF_AddPage (pdf); HPDF_Page_SetWidth (page, width); HPDF_Page_SetHeight (page, height); u3d = HPDF_LoadU3DFromFile (pdf, tname); // Default view view = HPDF_Create3DView (u3d->mmgr, "DefaultView"); // Position camera HPDF_3DView_SetCamera (view, 0, 0, 0, 0, 0, 1, depth, 0); // Set ortho projection HPDF_3DView_SetOrthogonalProjection (view, 1); // Background color HPDF_3DView_SetBackgroundColor (view, 0.9, 0.9, 0.9); // Lighting HPDF_3DView_SetLighting (view, "CAD"); // Add views HPDF_U3D_Add3DView (u3d, view); HPDF_U3D_SetDefault3DView(u3d, "DefaultView"); // Create annotation annot = HPDF_Page_Create3DAnnot (page, rect, u3d ); // Enable toolbar HPDF_Dict action = (HPDF_Dict)HPDF_Dict_GetItem (annot, "3DA", HPDF_OCLASS_DICT); HPDF_Dict_AddBoolean (action, "TB", HPDF_TRUE); /* save the document to a file */ const size_t tlen = strlen(tname); tname[tlen-3]='p'; tname[tlen-2]='d'; tname[tlen-1]='f'; HPDF_SaveToFile (pdf, tname); /* clean up */ HPDF_Free (pdf); #else const size_t tlen = strlen(tname); tname[tlen-2]='p'; tname[tlen-2]='d'; tname[tlen-1]='f'; tname[tlen+0]='.'; tname[tlen+1]='t'; tname[tlen+2]='x'; tname[tlen+3]='t'; tname[tlen+4]='\0'; FILE *fp=fopen(tname,"wt"); fputs("Can not produce PDF file, MathGL compiled without PDF output support\n", fp); fclose(fp); mgl_set_global_warn(_("PDF support was disabled. Please, enable it and rebuild MathGL.")); #endif // MGL_HAVE_PDF } delete []tname; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_prc_(uintptr_t *gr, const char *fname,const char *descr, int *make_pdf,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_prc(_GR_,s,f,*make_pdf); delete []s; delete []f; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/evalc.cpp0000644000175000017500000003407713513030041015545 0ustar alastairalastair/*************************************************************************** * evalc.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/datac.h" #include "mgl2/evalc.h" #if MGL_HAVE_GSL #include #endif //----------------------------------------------------------------------------- // constants for expression parsing enum{ EQ_NUM=0, // a variable substitution EQ_RND, // random number EQ_A, // numeric constant // normal functions of 2 arguments EQ_LT, // comparison xy EQ_EQ, // comparison x=y EQ_ADD, // addition x+y EQ_SUB, // substraction x-y EQ_MUL, // multiplication x*y EQ_DIV, // division x/y EQ_IPOW, // power x^n for integer n EQ_POW, // power x^y EQ_LOG, // logarithm of x on base a, log_a(x) = ln(x)/ln(a) EQ_CMPLX, // return a+i*b EQ_HYPOT, // return sqrt(a*a+b*b) // normal functions of 1 argument EQ_SIN, // sine function \sin(x). !!! MUST BE FIRST 1-PLACE FUNCTION EQ_COS, // cosine function \cos(x). EQ_TAN, // tangent function \tan(x). EQ_ASIN, // inverse sine function \asin(x). EQ_ACOS, // inverse cosine function \acos(x). EQ_ATAN, // inverse tangent function \atan(x). EQ_SINH, // hyperbolic sine function \sinh(x). EQ_COSH, // hyperbolic cosine function \cosh(x). EQ_TANH, // hyperbolic tangent function \tanh(x). EQ_ASINH, // inverse hyperbolic sine function \asinh(x). EQ_ACOSH, // inverse hyperbolic cosine function \acosh(x). EQ_ATANH, // inverse hyperbolic tangent function \atanh(x). EQ_SQRT, // square root function \sqrt(x) EQ_EXP, // exponential function \exp(x) EQ_EXPI, // exponential function \exp(i*x) EQ_LN, // logarithm of x, ln(x) EQ_LG, // decimal logarithm of x, lg(x) = ln(x)/ln(10) EQ_ABS, // absolute value EQ_ARG, // argument (or phase) of complex number EQ_CONJ, // complex conjugate EQ_REAL, // real part EQ_IMAG, // imaginary part EQ_NORM, // square of absolute value |u|^2 EQ_LAST // id of last entry }; //----------------------------------------------------------------------------- int mglFormulaC::Error=0; bool MGL_LOCAL_PURE mglCheck(char *str,int n); int MGL_LOCAL_PURE mglFindInText(const char *str, const char *lst); //----------------------------------------------------------------------------- mglFormulaC::~mglFormulaC() { if(tmp) delete tmp; if(Left) delete Left; if(Right) delete Right; } //----------------------------------------------------------------------------- // Formula constructor (automatically parse and "compile" formula) mglFormulaC::mglFormulaC(const char *string) { dat = tmp = NULL; dx1=dy1=dz1=0; dx2=dy2=dz2=1; Error=0; Left=Right=0; Res=0; Kod=0; if(!string) { Kod = EQ_NUM; Res = 0; return; } char *str = new char[strlen(string)+1]; strcpy(str,string); long n,len; mgl_strtrim(str); mgl_strlwr(str); len=strlen(str); if(str[0]==0) { delete []str; return; } if(str[0]=='(' && mglCheck(&(str[1]),len-2)) // remove braces { memmove(str,str+1,len); len-=2; str[len]=0; } len=strlen(str); if(str[0]==':' && str[1]!=0) // this data file for interpolation { double sx1,sx2,sy1,sy2,sz1,sz2; char *buf = strchr(str+1,':'); if(buf && *buf) { *buf = 0; int r = sscanf(buf+1,"%lg:%lg:%lg:%lg:%lg:%lg",&sx1,&sx2,&sy1,&sy2,&sz1,&sz2); if(r>1 && sx1!=sx2) { dx1=sx1; dx2=sx2; } if(r>3 && sy1!=sy2) { dy1=sy1; dy2=sy2; } if(r>5 && sz1!=sz2) { dz1=sz1; dz2=sz2; } } dat = tmp = new mglDataC(str+1); delete []str; return; } n=mglFindInText(str,"<>="); // low priority -- conditions if(n>=0) { if(str[n]=='<') Kod=EQ_LT; else if(str[n]=='>') Kod=EQ_GT; else Kod=EQ_EQ; str[n]=0; Left=new mglFormulaC(str); Right=new mglFormulaC(str+n+1); delete []str; return; } n=mglFindInText(str,"+-"); // normal priority -- additions if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2])))) { if(str[n]=='+') Kod=EQ_ADD; else Kod=EQ_SUB; str[n]=0; Left=new mglFormulaC(str); Right=new mglFormulaC(str+n+1); delete []str; return; } n=mglFindInText(str,"*/"); // high priority -- multiplications if(n>=0) { if(str[n]=='*') Kod=EQ_MUL; else Kod=EQ_DIV; str[n]=0; Left=new mglFormulaC(str); Right=new mglFormulaC(str+n+1); delete []str; return; } n=mglFindInText(str,"^"); // highest priority -- power if(n>=0) { Kod=EQ_IPOW; str[n]=0; Left=new mglFormulaC(str); Right=new mglFormulaC(str+n+1); delete []str; return; } for(n=0;n=len) // this is number or variable { Kod = EQ_NUM; // Left = Right = 0; if(str[1]==0 && str[0]>='a' && str[0]<='z') // available variables { Kod=EQ_A; Res = str[0]-'a'; } else if(!strcmp(str,"rnd")) Kod=EQ_RND; else if(!strcmp(str,"pi")) Res=M_PI; else if(!strcmp(str,"inf")) Res=INFINITY; else if(str[0]=='i') Res = dual(0,atof(str+1)); else Res = (str[len-1]=='i') ? dual(0,atof(str)) : atof(str); } else { char name[128]; mgl_strncpy(name,str,128); name[127]=name[n]=0; memmove(str,str+n+1,len-n); len=strlen(str); str[--len]=0; if(!strcmp(name,"sin")) Kod=EQ_SIN; else if(!strcmp(name,"cos")) Kod=EQ_COS; else if(!strcmp(name,"tg")) Kod=EQ_TAN; else if(!strcmp(name,"tan")) Kod=EQ_TAN; else if(!strcmp(name,"asin")) Kod=EQ_ASIN; else if(!strcmp(name,"acos")) Kod=EQ_ACOS; else if(!strcmp(name,"atan")) Kod=EQ_ATAN; else if(!strcmp(name,"sinh")) Kod=EQ_SINH; else if(!strcmp(name,"cosh")) Kod=EQ_COSH; else if(!strcmp(name,"tanh")) Kod=EQ_TANH; else if(!strcmp(name,"sh")) Kod=EQ_SINH; else if(!strcmp(name,"ch")) Kod=EQ_COSH; else if(!strcmp(name,"th")) Kod=EQ_TANH; else if(!strcmp(name,"sqrt")) Kod=EQ_SQRT; else if(!strcmp(name,"log")) Kod=EQ_LOG; else if(!strcmp(name,"pow")) Kod=EQ_POW; else if(!strcmp(name,"exp")) Kod=EQ_EXP; else if(!strcmp(name,"lg")) Kod=EQ_LG; else if(!strcmp(name,"ln")) Kod=EQ_LN; else if(!strcmp(name,"abs")) Kod=EQ_ABS; else if(!strcmp(name,"arg")) Kod=EQ_ARG; else if(!strcmp(name,"conj")) Kod=EQ_CONJ; else if(!strcmp(name,"real")) Kod=EQ_REAL; else if(!strcmp(name,"imag")) Kod=EQ_IMAG; else if(!strcmp(name,"norm")) Kod=EQ_NORM; else if(!strcmp(name,"cmplx")) Kod=EQ_CMPLX; else if(!strcmp(name,"hypot")) Kod=EQ_HYPOT; else { delete []str; return; } // unknown function n=mglFindInText(str,","); if(n>=0) { str[n]=0; Left=new mglFormulaC(str); Right=new mglFormulaC(str+n+1); } else Left=new mglFormulaC(str); } delete []str; } //----------------------------------------------------------------------------- // evaluate formula for 'x'='r', 'y'='n'='v', 't'='z', 'u'='a' variables dual mglFormulaC::Calc(dual x,dual y,dual t,dual u) const { Error=0; dual a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(dual)); a1['a'-'a'] = a1['u'-'a'] = u; a1['x'-'a'] = a1['r'-'a'] = x; a1['y'-'a'] = a1['n'-'a'] = a1['v'-'a'] = y; a1['z'-'a'] = a1['t'-'a'] = t; a1['i'-'a'] = dual(0,1); dual b = CalcIn(a1); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate formula for 'x'='r', 'y'='n', 't'='z', 'u'='a', 'v'='b', 'w'='c' variables dual mglFormulaC::Calc(dual x,dual y,dual t,dual u,dual v,dual w) const { Error=0; dual a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(dual)); a1['c'-'a'] = a1['w'-'a'] = w; a1['b'-'a'] = a1['v'-'a'] = v; a1['a'-'a'] = a1['u'-'a'] = u; a1['x'-'a'] = a1['r'-'a'] = x; a1['y'-'a'] = a1['n'-'a'] = y; a1['z'-'a'] = a1['t'-'a'] = t; a1['i'-'a'] = dual(0,1); dual b = CalcIn(a1); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- // evaluate formula for arbitrary set of variables dual mglFormulaC::Calc(const dual var[MGL_VS]) const { Error=0; dual b = CalcIn(var); return mgl_isfin(b) ? b : NAN; } //----------------------------------------------------------------------------- dual MGL_LOCAL_CONST ceqc(dual a,dual b) {return a==b?1:0;} dual MGL_LOCAL_CONST cltc(dual a,dual b) {return real(a-b)<0?1:0;} dual MGL_LOCAL_CONST cgtc(dual a,dual b) {return real(a-b)>0?1:0;} dual MGL_LOCAL_CONST addc(dual a,dual b) {return a+b;} dual MGL_LOCAL_CONST subc(dual a,dual b) {return a-b;} dual MGL_LOCAL_CONST mulc(dual a,dual b) {return a*b;} dual MGL_LOCAL_CONST divc(dual a,dual b) {return a/b;} dual MGL_LOCAL_CONST ipwc(dual a,dual b) {return mgl_ipowc(a,int(b.real()));} dual MGL_LOCAL_CONST powc(dual a,dual b) {return exp(b*log(a)); } dual MGL_LOCAL_CONST llgc(dual a,dual b) {return log(a)/log(b); } dual MGL_LOCAL_CONST cmplxc(dual a,dual b) {return a+dual(0,1)*b; } dual MGL_LOCAL_CONST expi(dual a) { return exp(dual(0,1)*a); } dual MGL_LOCAL_CONST expi(double a) { return dual(cos(a),sin(a)); } //----------------------------------------------------------------------------- dual MGL_NO_EXPORT ic = dual(0,1); dual MGL_LOCAL_CONST hypotc(dual x, dual y) { return sqrt(x*x+y*y); } dual MGL_LOCAL_CONST asinhc(dual x) { return log(x+sqrt(x*x+mreal(1))); } dual MGL_LOCAL_CONST acoshc(dual x) { return log(x+sqrt(x*x-mreal(1))); } dual MGL_LOCAL_CONST atanhc(dual x) { return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); } dual MGL_LOCAL_CONST conjc(dual x) { return dual(real(x),-imag(x)); } dual MGL_LOCAL_CONST sinc(dual x) { return sin(x); } dual MGL_LOCAL_CONST cosc(dual x) { return cos(x); } dual MGL_LOCAL_CONST tanc(dual x) { return tan(x); } dual MGL_LOCAL_CONST sinhc(dual x) { return sinh(x); } dual MGL_LOCAL_CONST coshc(dual x) { return cosh(x); } dual MGL_LOCAL_CONST tanhc(dual x) { return tanh(x); } dual MGL_LOCAL_CONST asinc(dual x) { return log(ic*x+sqrt(mreal(1)-x*x))/ic; } dual MGL_LOCAL_CONST acosc(dual x) { return log(x+sqrt(x*x-mreal(1)))/ic; } dual MGL_LOCAL_CONST atanc(dual x) { return log((ic-x)/(ic+x))/(mreal(2)*ic); } dual MGL_LOCAL_CONST expc(dual x) { return exp(x); } dual MGL_LOCAL_CONST sqrtc(dual x) { return sqrt(x); } dual MGL_LOCAL_CONST logc(dual x) { return log(x); } dual MGL_LOCAL_CONST absc(dual x) { return abs(x); } dual MGL_LOCAL_CONST argc(dual x) { return arg(x); } dual MGL_LOCAL_CONST lgc(dual x) { return log10(x);} dual MGL_LOCAL_CONST realc(dual x) { return real(x); } dual MGL_LOCAL_CONST imagc(dual x) { return imag(x); } dual MGL_LOCAL_CONST normc(dual x) { return norm(x); } //----------------------------------------------------------------------------- typedef dual (*func_1)(dual); typedef dual (*func_2)(dual, dual); static const func_2 f2[EQ_SIN-EQ_LT] = {cltc,cgtc,ceqc,addc,subc,mulc,divc,ipwc,powc,llgc,cmplxc,hypotc}; static const func_1 f1[EQ_LAST-EQ_SIN] = {sinc,cosc,tanc,asinc,acosc,atanc,sinhc,coshc,tanhc, asinhc,acoshc,atanhc,sqrtc,expc,expi,logc,lgc,absc,argc,conjc,realc,imagc,normc}; // evaluation of embedded (included) expressions dual mglFormulaC::CalcIn(const dual *a1) const { if(dat) { mreal x = (real(a1['x'-'a'])-dx1)*(dat->GetNx()-1)/(dx2-dx1); mreal y = (real(a1['y'-'a'])-dy1)*(dat->GetNy()-1)/(dy2-dy1); mreal z = (real(a1['z'-'a'])-dz1)*(dat->GetNz()-1)/(dz2-dz1); return mgl_datac_spline(dat,x,y,z); } if(KodCalcIn(a1); if(mgl_isfin(a)) { if(KodCalcIn(a1)):NAN; else return f1[Kod-EQ_SIN](a); } return NAN; } //----------------------------------------------------------------------------- dual MGL_LOCAL_CONST mgl_ipowc_c(dual x,int n) { dual t; if(n==2) t = x*x; else if(n==1) t = x; else if(n<0) t = mreal(1)/mgl_ipowc_c(x,-n); else if(n==0) t = mreal(1); else { t = mgl_ipowc_c(x,n/2); t = t*t; if(n%2==1) t *= x; } return t; } cmdual MGL_EXPORT_CONST mgl_ipowc(mdual x,int n) { return mdual(mgl_ipowc_c(x,n)); } cmdual MGL_EXPORT_PURE mgl_ipowc_(mdual *x,int *n) { return mgl_ipowc(*x,*n); } //----------------------------------------------------------------------------- HAEX MGL_EXPORT mgl_create_cexpr(const char *expr) { return new mglFormulaC(expr); } uintptr_t MGL_EXPORT mgl_create_cexpr_(const char *expr, int l) { char *s=new char[l+1]; memcpy(s,expr,l); s[l]=0; uintptr_t res = uintptr_t(mgl_create_cexpr(s)); delete []s; return res; } void MGL_EXPORT mgl_delete_cexpr(HAEX ex) { if(ex) delete ex; } void MGL_EXPORT mgl_delete_cexpr_(uintptr_t *ex) { mgl_delete_cexpr((HAEX)ex); } cmdual MGL_EXPORT mgl_cexpr_eval(HAEX ex, mdual x, mdual y, mdual z) { return mdual(ex->Calc(x,y,z)); } cmdual MGL_EXPORT mgl_cexpr_eval_(uintptr_t *ex, mdual *x, mdual *y, mdual *z) { return mgl_cexpr_eval((HAEX) ex, *x,*y,*z); } cmdual MGL_EXPORT mgl_cexpr_eval_v(HAEX ex, mdual *var) { return mdual(ex->Calc(reinterpret_cast(var))); } //----------------------------------------------------------------------------- mathgl-2.4.4/src/base_cf.cpp0000644000175000017500000004501513513030041016027 0ustar alastairalastair/*************************************************************************** * base.cpp is part of Math gric Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/font.h" #include "mgl2/base_cf.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- // // C interfaces // //----------------------------------------------------------------------------- bool mglPrintWarn = true; void MGL_EXPORT mgl_suppress_warn(int on) { mglPrintWarn = !on; } void MGL_EXPORT mgl_suppress_warn_(int *on) { mgl_suppress_warn(*on); } void MGL_EXPORT mgl_set_quality(HMGL gr, int qual) { gr->SetQuality(qual); } void MGL_EXPORT mgl_set_quality_(uintptr_t *gr, int *qual) { _GR_->SetQuality(*qual); } int MGL_EXPORT_PURE mgl_get_quality(HMGL gr) { return gr->GetQuality(); } int MGL_EXPORT_PURE mgl_get_quality_(uintptr_t *gr) { return _GR_->GetQuality(); } int MGL_EXPORT_PURE mgl_is_frames(HMGL gr) { return gr->get(MGL_VECT_FRAME) && !(gr->GetQuality()&MGL_DRAW_LMEM); } void MGL_EXPORT mgl_set_draw_reg(HMGL gr, long nx, long ny, long m) { gr->SetDrawReg(nx,ny,m); } void MGL_EXPORT mgl_set_draw_reg_(uintptr_t *gr, int *nx, int *ny, int *m) { _GR_->SetDrawReg(*nx,*ny,*m); } //----------------------------------------------------------------------------- int MGL_EXPORT_PURE mgl_get_flag(HMGL gr, uint32_t flag) { return gr->get(flag); } int MGL_EXPORT_PURE mgl_get_flag_(uintptr_t *gr, unsigned long *flag) { return _GR_->get(*flag); } void MGL_EXPORT mgl_set_flag(HMGL gr, int val, uint32_t flag) { gr->set(val,flag); } void MGL_EXPORT mgl_set_flag_(uintptr_t *gr, int *val, unsigned long *flag) { _GR_->set(*val,*flag); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_color(char id, double r, double g, double b) { for(long i=0;mglColorIds[i].id;i++) if(mglColorIds[i].id==id) mglColorIds[i].col = mglColor(r,g,b); } void MGL_EXPORT mgl_set_color_(char *id, mreal *r, mreal *g, mreal *b, int) { mgl_set_color(*id,*r,*g,*b); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_def_sch(HMGL gr, const char *sch) { gr->SetDefScheme(sch); } void MGL_EXPORT mgl_set_def_sch_(uintptr_t *gr, const char *sch,int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; mgl_set_def_sch(_GR_, s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_plotid(HMGL gr, const char *id) { gr->PlotId = id; } void MGL_EXPORT mgl_set_plotid_(uintptr_t *gr, const char *id,int l) { char *s=new char[l+1]; memcpy(s,id,l); s[l]=0; _GR_->PlotId = s; delete []s; } MGL_EXPORT_PURE const char *mgl_get_plotid(HMGL gr) { return gr->PlotId.c_str(); } int MGL_EXPORT mgl_get_plotid_(uintptr_t *gr, char *out, int len) { const char *res = mgl_get_plotid(_GR_); if(out) mgl_strncpy(out,res,len); return strlen(res); } //----------------------------------------------------------------------------- MGL_EXPORT_PURE const char *mgl_get_mess(HMGL gr) { return gr->Mess.c_str(); } int MGL_EXPORT mgl_get_mess_(uintptr_t *gr, char *out, int len) { const char *res = mgl_get_mess(_GR_); if(out) mgl_strncpy(out,res,len); return strlen(res); } int MGL_EXPORT_PURE mgl_get_warn(HMGL gr) { return gr->GetWarn(); } void MGL_EXPORT mgl_set_warn(HMGL gr, int code, const char *txt) { gr->SetWarn(code,txt); } extern bool mglPrintWarn; void MGL_EXPORT mgl_set_global_warn(const char *txt) { if(txt && *txt) { mglGlobalMess += txt; mglGlobalMess += '\n'; if(mglPrintWarn) fprintf(stderr,_("Global message - %s\n"),txt); } } void MGL_EXPORT mgl_set_global_warn_(const char *txt, int l) { char *s=new char[l+1]; memcpy(s,txt,l); s[l]=0; mgl_set_global_warn(s); delete []s; } MGL_EXPORT_PURE const char *mgl_get_global_warn() { return mglGlobalMess.c_str(); } int MGL_EXPORT mgl_get_global_warn_(char *out, int len) { const char *res = mgl_get_global_warn(); if(out) mgl_strncpy(out,res,len); return strlen(res); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_origin(HMGL gr, double x0, double y0, double z0) { gr->SetOrigin(x0,y0,z0); } void MGL_EXPORT mgl_set_palette(HMGL gr, const char *colors) { gr->SetPalette(colors); } void MGL_EXPORT mgl_set_meshnum(HMGL gr, int num) { gr->SetMeshNum(num); } void MGL_EXPORT mgl_set_facenum(HMGL gr, int num) { gr->FaceNum=num; } void MGL_EXPORT mgl_set_alpha_default(HMGL gr, double alpha) { gr->SetAlphaDef(alpha); } void MGL_EXPORT mgl_set_light_dif(HMGL gr, int enable) { gr->SetDifLight(enable); } void MGL_EXPORT mgl_clear_unused(HMGL gr) { gr->ClearUnused(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_rdc_acc(HMGL gr, int reduce) { gr->SetReduceAcc(reduce); } void MGL_EXPORT mgl_highlight(HMGL gr, int id) { gr->Highlight(id); } void MGL_EXPORT mgl_set_cut(HMGL gr, int cut) { gr->SetCut(cut); } void MGL_EXPORT mgl_set_cut_box(HMGL gr, double x1,double y1,double z1,double x2,double y2,double z2) { gr->SetCutBox(x1,y1,z1,x2,y2,z2); } void MGL_EXPORT mgl_set_cutoff(HMGL gr, const char *EqC) { gr->CutOff(EqC); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_ternary(HMGL gr, int enable) { gr->Ternary(enable); } void MGL_EXPORT mgl_set_range_val(HMGL gr, char dir, double v1,double v2) { if(dir=='c' || dir=='a') gr->CRange(v1,v2); else if(dir=='x') gr->XRange(v1,v2); else if(dir=='y') gr->YRange(v1,v2); else if(dir=='z') gr->ZRange(v1,v2); } void MGL_EXPORT mgl_add_range_val(HMGL gr, char dir, double v1,double v2) { if(dir=='c' || dir=='a') gr->CRange(v1,v2,true); else if(dir=='x') gr->XRange(v1,v2,true); else if(dir=='y') gr->YRange(v1,v2,true); else if(dir=='z') gr->ZRange(v1,v2,true); } void MGL_EXPORT mgl_set_range_dat(HMGL gr, char dir, HCDT a, int add) { if(dir=='c' || dir=='a') gr->CRange(a,add); else if(dir=='x') gr->XRange(a,add); else if(dir=='y') gr->YRange(a,add); else if(dir=='z') gr->ZRange(a,add); } void MGL_EXPORT mgl_set_ranges(HMGL gr, double x1, double x2, double y1, double y2, double z1, double z2) { gr->SetRanges(x1,x2,y1,y2,z1,z2); } void MGL_EXPORT mgl_set_auto_ranges(HMGL gr, double x1, double x2, double y1, double y2, double z1, double z2, double c1, double c2) { gr->SetAutoRanges(x1,x2,y1,y2,z1,z2,c1,c2); } void MGL_EXPORT mgl_set_func(HMGL gr, const char *EqX,const char *EqY,const char *EqZ,const char *EqA) { gr->SetFunc(EqX,EqY,EqZ,EqA); } void MGL_EXPORT mgl_set_coor(HMGL gr, int how) { gr->SetCoor(how); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_bar_width(HMGL gr, double width) { gr->SetBarWidth(width); } //----------------------------------------------------------------------------- // // Fortran interfaces // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_rdc_acc_(uintptr_t *gr, int *reduce) { _GR_->SetReduceAcc(*reduce); } void MGL_EXPORT mgl_highlight_(uintptr_t *gr, int *id) { _GR_->Highlight(*id); } void MGL_EXPORT mgl_set_origin_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0) { _GR_->SetOrigin(*x0,*y0,*z0); } int MGL_EXPORT_PURE mgl_get_warn_(uintptr_t *gr) { return _GR_->GetWarn(); } void MGL_EXPORT mgl_set_warn_(uintptr_t *gr, int *code, const char *txt, int l) { char *s=new char[l+1]; memcpy(s,txt,l); s[l]=0; _GR_->SetWarn(*code, s); delete []s; } void MGL_EXPORT mgl_set_palette_(uintptr_t *gr, const char *colors, int l) { char *s=new char[l+1]; memcpy(s,colors,l); s[l]=0; _GR_->SetPalette(s); delete []s; } void MGL_EXPORT mgl_set_meshnum_(uintptr_t *gr, int *num) { _GR_->SetMeshNum(*num); } void MGL_EXPORT mgl_set_facenum_(uintptr_t *gr, int *num) { _GR_->FaceNum=*num; } void MGL_EXPORT mgl_set_alpha_default_(uintptr_t *gr, mreal *alpha) { _GR_->SetAlphaDef(*alpha); } void MGL_EXPORT mgl_set_light_dif_(uintptr_t *gr, int *enable) { _GR_->SetDifLight(*enable); } void MGL_EXPORT mgl_clear_unused_(uintptr_t *gr) { _GR_->ClearUnused(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_cut_box_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2) { _GR_->SetCutBox(*x1,*y1,*z1,*x2,*y2,*z2); } void MGL_EXPORT mgl_set_cut_(uintptr_t *gr, int *cut) { _GR_->SetCut(*cut); } void MGL_EXPORT mgl_set_cutoff_(uintptr_t *gr, const char *EqC, int l) { char *s=new char[l+1]; memcpy(s,EqC,l); s[l]=0; _GR_->CutOff(s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_ternary_(uintptr_t *gr, int *enable) { _GR_->Ternary(*enable); } void MGL_EXPORT mgl_set_range_val_(uintptr_t *gr, const char *dir, mreal *v1, mreal *v2,int) { mgl_set_range_val(_GR_,*dir,*v1,*v2); } void MGL_EXPORT mgl_add_range_val_(uintptr_t *gr, const char *dir, mreal *v1, mreal *v2,int) { mgl_add_range_val(_GR_,*dir,*v1,*v2); } void MGL_EXPORT mgl_set_range_dat_(uintptr_t *gr, const char *dir, uintptr_t *a, int *add,int) { mgl_set_range_dat(_GR_,*dir,_DA_(a),*add); } void MGL_EXPORT mgl_set_ranges_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2) { _GR_->SetRanges(*x1,*x2,*y1,*y2,*z1,*z2); } void MGL_EXPORT mgl_set_auto_ranges_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2, mreal *c1, mreal *c2) { _GR_->SetAutoRanges(*x1,*x2,*y1,*y2,*z1,*z2,*c1,*c2); } void MGL_EXPORT mgl_set_func_(uintptr_t *gr, const char *EqX,const char *EqY,const char *EqZ,const char *EqA,int lx,int ly,int lz,int la) { char *sx=new char[lx+1]; memcpy(sx,EqX,lx); sx[lx]=0; char *sy=new char[ly+1]; memcpy(sy,EqY,ly); sy[ly]=0; char *sz=new char[lz+1]; memcpy(sz,EqZ,lz); sz[lz]=0; char *sa=new char[la+1]; memcpy(sa,EqA,la); sa[la]=0; _GR_->SetFunc(sx,sy,sz,sa); delete []sx; delete []sy; delete []sz; delete []sa; } void MGL_EXPORT mgl_set_coor_(uintptr_t *gr, int *how) { _GR_->SetCoor(*how); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_tick_rotate(HMGL gr, int enable){ gr->SetTickRotate(enable); } void MGL_EXPORT mgl_set_tick_skip(HMGL gr, int enable) { gr->SetTickSkip(enable); } void MGL_EXPORT mgl_set_tick_rotate_(uintptr_t *gr,int *enable){ _GR_->SetTickRotate(*enable); } void MGL_EXPORT mgl_set_tick_skip_(uintptr_t *gr, int *enable) { _GR_->SetTickSkip(*enable); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_rotated_text(HMGL gr, int enable) { gr->SetRotatedText(enable); } void MGL_EXPORT mgl_set_scale_text(HMGL gr, int enable) { gr->set(!enable, MGL_NO_SCALE_REL); } void MGL_EXPORT mgl_set_mark_size(HMGL gr, double size) { gr->SetMarkSize(size); } void MGL_EXPORT mgl_set_arrow_size(HMGL gr, double size) { gr->SetArrowSize(size); } void MGL_EXPORT mgl_set_font_size(HMGL gr, double size) { gr->SetFontSize(size); } void MGL_EXPORT mgl_set_font_def(HMGL gr, const char *fnt) { gr->SetFontDef(fnt); } void MGL_EXPORT mgl_load_font(HMGL gr, const char *name, const char *path) { gr->LoadFont(name,path); } void MGL_EXPORT mgl_copy_font(HMGL gr, HMGL gr_from) { gr->CopyFont(gr_from); } void MGL_EXPORT mgl_restore_font(HMGL gr) { gr->RestoreFont(); } void MGL_EXPORT mgl_define_symbol(HMGL gr, char id, HCDT x, HCDT y) { gr->DefineGlyph(x,y,id); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_set_bar_width_(uintptr_t *gr, mreal *width) { _GR_->SetBarWidth(*width); } void MGL_EXPORT mgl_set_rotated_text_(uintptr_t *gr, int *enable) { _GR_->SetRotatedText(*enable); } void MGL_EXPORT mgl_set_scale_text_(uintptr_t *gr, int *enable) { mgl_set_scale_text(_GR_,*enable); } void MGL_EXPORT mgl_set_mark_size_(uintptr_t *gr, mreal *size) { _GR_->SetMarkSize(*size); } void MGL_EXPORT mgl_set_arrow_size_(uintptr_t *gr, mreal *size) { _GR_->SetArrowSize(*size); } void MGL_EXPORT mgl_set_font_size_(uintptr_t *gr, mreal *size) { _GR_->SetFontSize(*size); } void MGL_EXPORT mgl_set_font_def_(uintptr_t *gr, const char *name, int l) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; _GR_->SetFontDef(s); delete []s; } void MGL_EXPORT mgl_load_font_(uintptr_t *gr, char *name, char *path, int l,int n) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; char *d=new char[n+1]; memcpy(d,path,n); d[n]=0; _GR_->LoadFont(s,d); delete []s; delete []d; } void MGL_EXPORT mgl_copy_font_(uintptr_t *gr, uintptr_t *gr_from) { _GR_->CopyFont((mglBase *)(*gr_from)); } void MGL_EXPORT mgl_restore_font_(uintptr_t *gr) { _GR_->RestoreFont(); } void MGL_EXPORT mgl_define_symbol_(uintptr_t *gr, char *id, uintptr_t *x, uintptr_t *y, int) { _GR_->DefineGlyph(_DA_(x),_DA_(y),id?*id:0); } //----------------------------------------------------------------------------- extern mglFont mglDefFont; void MGL_EXPORT mgl_def_font(const char *name, const char *path) { mglDefFont.Load(name,path); } void MGL_EXPORT mgl_def_font_(const char *name, const char *path,int l,int n) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; char *d=new char[n+1]; memcpy(d,path,n); d[n]=0; mglDefFont.Load(name,path); delete []s; delete []d; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_check_version(const char *ver) { double v=0; int r = sscanf(ver,"2.%lg",&v); return r<1 || v>MGL_VER2; } int MGL_EXPORT mgl_check_version_(const char *ver, int l) { char *s=new char[l+1]; memcpy(s,ver,l); s[l]=0; int r=mgl_check_version(s); delete []s; return r; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_start_group(HMGL gr, const char *s) { gr->StartAutoGroup(s); } void MGL_EXPORT mgl_end_group(HMGL gr) { gr->EndGroup(); } void MGL_EXPORT mgl_start_group_(uintptr_t *gr, const char *name,int l) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; _GR_->StartAutoGroup(s); delete []s; } void MGL_EXPORT mgl_end_group_(uintptr_t *gr) { _GR_->EndGroup(); } //----------------------------------------------------------------------------- #include bool mglTestMode=false; void MGL_EXPORT mgl_test_txt(const char *str, ...) { if(mglTestMode) { char buf[256]; va_list lst; va_start(lst,str); vsnprintf(buf,256,str,lst); buf[255]=0; va_end(lst); printf(_("TEST: %s\n"),buf); fflush(stdout); } } void MGL_EXPORT mgl_set_test_mode(int enable) { mglTestMode=enable; } //--------------------------------------------------------------------------- long MGL_EXPORT mgl_use_graph(HMGL gr, int inc) { if(!gr) return 0; gr->InUse+=inc; return gr->InUse; } long MGL_EXPORT mgl_use_graph_(uintptr_t *gr, int *inc) { return mgl_use_graph(_GR_,*inc); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_set_ambbr(HMGL gr, double i) { gr->SetAmbient(i); } void MGL_EXPORT mgl_set_ambbr_(uintptr_t *gr, mreal *i){ _GR_->SetAmbient(*i); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_set_difbr(HMGL gr, double i) { gr->SetDiffuse(i); } void MGL_EXPORT mgl_set_difbr_(uintptr_t *gr, mreal *i){ _GR_->SetDiffuse(*i); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_zoom_axis(HMGL gr, double x1,double y1,double z1,double c1,double x2,double y2,double z2,double c2) { gr->ZoomAxis(mglPoint(x1,y1,z1,c1), mglPoint(x2,y2,z2,c2)); } void MGL_EXPORT mgl_zoom_axis_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *c1, mreal *x2, mreal *y2, mreal *z2, mreal *c2) { _GR_->ZoomAxis(mglPoint(*x1,*y1,*z1,*c1), mglPoint(*x2,*y2,*z2,*c2)); } //--------------------------------------------------------------------------- extern uint64_t mgl_mask_def[16]; void MGL_EXPORT mgl_set_mask(char id, const char *mask) { const char *msk = MGL_MASK_ID, *s = mglchr(msk, id); if(s) { uint64_t val = (mask && *mask) ? strtoull(mask,NULL,16) : mgl_mask_def[s-msk]; mgl_mask_val[s-msk] = val; } } void MGL_EXPORT mgl_set_mask_(const char *id, const char *mask,int,int l) { char *s=new char[l+1]; memcpy(s,mask,l); s[l]=0; mgl_set_mask(*id,s); delete []s; } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_set_mask_val(char id, uint64_t mask) { const char *msk = MGL_MASK_ID, *s = mglchr(msk, id); if(s) mgl_mask_val[s-msk]=mask; } void MGL_EXPORT mgl_set_mask_val_(const char *id, uint64_t *mask,int) { mgl_set_mask_val(*id,*mask); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_set_mask_angle(HMGL gr, int angle) { gr->SetMaskAngle(angle); } void MGL_EXPORT mgl_set_mask_angle_(uintptr_t *gr, int *angle) { _GR_->SetMaskAngle(*angle); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_ask_stop(HMGL gr, int stop) { gr->AskStop(stop); } void MGL_EXPORT mgl_ask_stop_(uintptr_t *gr, int *stop){ _GR_->AskStop(*stop); } int MGL_EXPORT mgl_need_stop(HMGL gr) { return gr->NeedStop(); } int MGL_EXPORT mgl_need_stop_(uintptr_t *gr) { return _GR_->NeedStop();} void MGL_EXPORT mgl_set_event_func(HMGL gr, void (*func)(void *), void *par) { gr->SetEventFunc(func,par); } //--------------------------------------------------------------------------- mathgl-2.4.4/src/surf.cpp0000644000175000017500000013107613513030041015427 0ustar alastairalastair/*************************************************************************** * surf.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/define.h" #include "mgl2/surf.h" #include "mgl2/data.h" #include "mgl2/eval.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- void static mgl_mesh_plot(mglBase *gr, long kq, long n, long m, int how) { int d = gr->MeshNum>0 ? gr->MeshNum+1 : n*m, dx = n>d?n/d:1, dy = m>d?m/d:1; // NOTE: number of lines in each direction can be reduced too if(how&1) for(long j=0;jValidPnt(iq) && gr->ValidPnt(iq+1)) s++; } d = gr->FaceNum>0 ? gr->FaceNum+1 : n; s = s>d?s/d:1; gr->curve_plot(1+(n-1)/s,kq+n*j,s); } if(how&2) for(long i=0;iValidPnt(iq) && gr->ValidPnt(iq+n)) s++; } d = gr->FaceNum>0 ? gr->FaceNum+1 : n; s = s>d?s/d:1; gr->curve_plot(1+(m-1)/s,kq+i,n*s); } } //----------------------------------------------------------------------------- void static mgl_surf_plot(mglBase *gr, long kq, long n, long m) { long s=0; for(long j=0;jValidPnt(iq) && gr->ValidPnt(iq+1) && gr->ValidPnt(iq+n) && gr->ValidPnt(iq+n+1)) s++; } long dx=1,dy=1; if(gr->FaceNum && s>gr->FaceNum*gr->FaceNum) { int d = gr->FaceNum+1,ns=n*s/((n-1)*(m-1)),ms=m*s/((n-1)*(m-1)); dx = ns>d?ns/d:1; dy = ms>d?ms/d:1; } for(long j=0;jquad_plot(iq,iq+dx,iq+n*dy,iq+n*dy+dx); } } //----------------------------------------------------------------------------- // // Plot by formulas series // //----------------------------------------------------------------------------- HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector &head); //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fsurf(HMGL gr, const char *eqZ, const char *sch, const char *opt) { // NOTE Strong function variation analysis can be added here if(eqZ==0 || eqZ[0]==0) return; // nothing to plot mreal r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5); mglData z(n,n); mglDataV x(n,n,1, gr->Min.x,gr->Max.x,'x'); x.Name(L"x"); mglDataV y(n,n,1, gr->Min.y,gr->Max.y,'y'); y.Name(L"y"); mglDataV t(n,n); t.Name(L"#$mgl"); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&t); z.Move(mglFormulaCalc(eqZ,list)); mgl_surf(gr, &z, sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fsurf_xyz(HMGL gr, const char *eqX, const char *eqY, const char *eqZ, const char *sch, const char *opt) { // NOTE Strong function variation analysis can be added here if(eqZ==0 || eqZ[0]==0) return; // nothing to plot mreal r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5); mglData z(n,n), x(n,n), y(n,n); mglDataV u(n,n,1, 0,1,'x'); u.Name(L"u"); mglDataV v(n,n,1, 0,1,'y'); v.Name(L"v"); mglDataV t(n,n); t.Name(L"#$mgl"); std::vector list; list.push_back(&u); list.push_back(&v); list.push_back(&t); x.Move(mglFormulaCalc(eqX,list)); y.Move(mglFormulaCalc(eqY,list)); z.Move(mglFormulaCalc(eqZ,list)); mgl_surf_xy(gr,&x,&y,&z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fsurf_(uintptr_t *gr, const char *fy, const char *stl, const char *opt, int ly, int ls, int lo) { char *s=new char[ly+1]; memcpy(s,fy,ly); s[ly]=0; char *p=new char[ls+1]; memcpy(p,stl,ls); p[ls]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_fsurf(_GR_, s, p, o); delete []o; delete []s; delete []p; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fsurf_xyz_(uintptr_t *gr, const char *fx, const char *fy, const char *fz, const char *stl, const char *opt, int lx, int ly, int lz, int ls, int lo) { char *sx=new char[lx+1]; memcpy(sx,fx,lx); sx[lx]=0; char *sy=new char[ly+1]; memcpy(sy,fy,ly); sy[ly]=0; char *sz=new char[lz+1]; memcpy(sz,fz,lz); sz[lz]=0; char *p=new char[ls+1]; memcpy(p,stl,ls); p[ls]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_fsurf_xyz(_GR_, sx, sy, sz, p, o); delete []o; delete []sx; delete []sy; delete []sz; delete []p; } //----------------------------------------------------------------------------- // // Mesh series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mesh_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"Mesh")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Mesh",cgid++); gr->SetPenPal(sch,0,false); long ss = gr->AddTexture(sch); gr->Reserve(n*m*z->GetNz()); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; const long kq = gr->AllocPnts(n*m); #pragma omp parallel for collapse(2) for(long j=0;jv(i,j,k); gr->AddPntQ(kq+i+n*j, mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zz),gr->GetC(ss,zz)); } mgl_mesh_plot(gr,kq,n,m,3); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mesh(HMGL gr, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_mesh_xy(gr,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mesh_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_mesh_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mesh_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_mesh(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Fall series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fall_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"Fall")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Fall",cgid++); gr->SetPenPal(sch,0,false); long ss = gr->AddTexture(sch); gr->Reserve(n*m*z->GetNz()); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; const long kq = gr->AllocPnts(n*m); #pragma omp parallel for collapse(2) for(long j=0;jv(i,j,k); gr->AddPntQ(kq+i+n*j, mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zz),gr->GetC(ss,zz)); } mgl_mesh_plot(gr,kq,n,m, (mglchr(sch,'x')) ? 2:1); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fall(HMGL gr, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_fall_xy(gr,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fall_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_fall_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fall_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_fall(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Grid series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"Grid")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Grid",cgid++); double zVal = gr->Min.z; gr->SetPenPal(sch?sch:"k-"); gr->Reserve(n*m*z->GetNz()); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; if(z->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(z->GetNz()-1); const long kq = gr->AllocPnts(n*m); #pragma omp parallel for collapse(2) for(long j=0;jAddPntQ(kq+i+n*j,mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zVal),gr->CDef); mgl_mesh_plot(gr,kq,n,m,3); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid(HMGL gr, HCDT z,const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_grid_xy(gr,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grid_xy(_GR_,_DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid_(uintptr_t *gr, uintptr_t *a,const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grid(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Surf series // //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_surf_gen(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch) { long n=z->GetNx(),m=z->GetNy(); long ss = gr->AddTexture(sch); bool wire = (mglchr(sch,'#')); gr->Reserve((n+1)*(m+1)*z->GetNz()*(wire?2:1)); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; const long kq = gr->AllocPnts(n*m); if(a) { #pragma omp parallel for collapse(2) for(long j=0;jdvx(i,j,k)); mglPoint s(xx.z, yy.z, z->dvy(i,j,k)); gr->AddPntQ(kq+i+n*j,mglPoint(xx.x, yy.x, z->v(i,j,k)), gr->GetC(ss,c->v(i,j,k)), q^s, gr->GetA(a->v(i,j,k))); } } else { #pragma omp parallel for collapse(2) for(long j=0;jdvx(i,j,k)); mglPoint s(xx.z, yy.z, z->dvy(i,j,k)); gr->AddPntQ(kq+i+n*j,mglPoint(xx.x, yy.x, z->v(i,j,k)), gr->GetC(ss,c->v(i,j,k)), q^s); } } if(sch && mglchr(sch,'.')) for(long i=0;imark_plot(kq+i,'.'); else mgl_surf_plot(gr,kq,n,m); if(wire) { gr->SetPenPal("k-"); const long nq = gr->AllocPnts(n*m); #pragma omp parallel for for(long i=0;iCopyNtoC(nq+i,kq+i,gr->CDef); mgl_mesh_plot(gr,nq,n,m,3); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,z,0,"Surf")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Surf",cgid++); mgl_surf_gen(gr, x, y, z, z, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf(HMGL gr, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_surf_xy(gr,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // SurfCA series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfca_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,z,c,"SurfCA")) return; if(mgl_check_dim2(gr,x,y,z,a,"SurfCA")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("SurfCA",cgid++); mgl_surf_gen(gr, x, y, z, c, a, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfca(HMGL gr, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_surfca_xy(gr,&x,&y,z,c,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfca_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surfca_xy(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(c), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfca_(uintptr_t *gr, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surfca(_GR_, _DA_(z), _DA_(c), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // SurfC series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfc_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,z,c,"SurfC")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("SurfC",cgid++); mgl_surf_gen(gr, x, y, z, c, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfc(HMGL gr, HCDT z, HCDT c, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_surfc_xy(gr,&x,&y,z,c,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfc_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surfc_xy(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfc_(uintptr_t *gr, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surfc(_GR_, _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // SurfA series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfa_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,z,c,"SurfA")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("SurfA",cgid++); mgl_surf_gen(gr, x, y, z, z, c, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfa(HMGL gr, HCDT z, HCDT c, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_surfa_xy(gr,&x,&y,z,c,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfa_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surfa_xy(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surfa_(uintptr_t *gr, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surfa(_GR_, _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Belt series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_belt_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_beltc_xy(gr,x,y,z,z,sch,opt); } void MGL_EXPORT mgl_beltc_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,c,"Belt")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Belt",cgid++); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n*m, dx = n>d?n/d:1, dy = m>d?m/d:1; long ss = gr->AddTexture(sch); gr->Reserve(2*n*m*z->GetNz()); bool how = !mglchr(sch,'x'); int dk = c->GetNz()>=z->GetNz() ? 1:0; for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; if(how) for(long i=0;iAllocPnts(2*m); #pragma omp parallel for for(long j=0;jv(i,j,k)); mglPoint s(xx.z, yy.z, z->dvy(i,j,k)); mglPoint q(xx.y, yy.y, 0); s = q^s; double cc = gr->GetC(ss,c->v(i,j,dk*k)); mglPoint p2(GetX(x,i+dx,j,k).x,GetY(y,i+dx,j,k).x,p1.z); gr->AddPntQ(kq+2*j,p1,cc,s); gr->AddPntQ(kq+2*j+1,p2,cc,s); } mgl_surf_plot(gr,kq,2,m); } else for(long j=0;jAllocPnts(2*n); #pragma omp parallel for for(long i=0;iv(i,j,k)); mglPoint q(xx.y, yy.y, z->dvx(i,j,k)); mglPoint s(xx.z, yy.z, 0); s = q^s; double cc = gr->GetC(ss,c->v(i,j,dk*k)); mglPoint p2(GetX(x,i,j+dy,k).x,GetY(y,i,j+dy,k).x,p1.z); gr->AddPntQ(kq+2*i,p1,cc,s); gr->AddPntQ(kq+2*i+1,p2,cc,s); } mgl_surf_plot(gr,kq,2,n); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_belt(HMGL gr, HCDT z, const char *sch, const char *opt) { mgl_beltc(gr,z,z,sch,opt); } void MGL_EXPORT mgl_beltc(HMGL gr, HCDT z, HCDT c, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()), y(z->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_beltc_xy(gr,&x,&y,z,c,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_belt_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_belt_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_belt_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_belt(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_beltc_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_beltc_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_beltc_(uintptr_t *gr, uintptr_t *a, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_beltc(_GR_, _DA_(a), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Dens series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_xy(HMGL gr, HCDT x, HCDT y, HCDT c, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,c,0,"Dens")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Dens",cgid++); mreal zVal = gr->Min.z; mglDataV z(c->GetNx(),c->GetNy(),c->GetNz()); if(z.GetNz()>1) z.Fill(gr->Min.z,gr->Max.z,'z'); else z.Fill(zVal); mgl_surf_gen(gr, x, y, &z, c, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens(HMGL gr, HCDT c, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(c->GetNx()), y(c->GetNy()); x.Fill(gr->Min.x, gr->Max.x); y.Fill(gr->Min.y, gr->Max.y); mgl_dens_xy(gr,&x,&y,c,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens_xy(_GR_,_DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens(_GR_,_DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // STFA series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stfa_xy(HMGL gr, HCDT x, HCDT y, HCDT re, HCDT im, int dn, const char *sch, const char *opt) { mglData tmp(mglSTFA(*re,*im,dn,'x')); mgl_dens_xy(gr,x,y,&tmp,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stfa(HMGL gr, HCDT re, HCDT im, int dn, const char *sch, const char *opt) { mglData tmp(mglSTFA(*re,*im,dn,'x')); mgl_dens(gr,&tmp,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stfa_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *re, uintptr_t *im, int *dn, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_stfa_xy(_GR_,_DA_(x), _DA_(y), _DA_(re), _DA_(im), *dn, s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stfa_(uintptr_t *gr, uintptr_t *re, uintptr_t *im, int *dn, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_stfa(_GR_,_DA_(re), _DA_(im), *dn, s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Boxs series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxs_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"Boxs",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Boxs",cgid++); long ly = y->GetNy()>=m ? y->GetNy() : y->GetNx(), lx = x->GetNx(); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n*m, dx = n>d?n/d:1, dy = m>d?m/d:1; long ss = gr->AddTexture(sch); bool wire = mglchr(sch,'#'); bool full = mglchr(sch,'@'); gr->Reserve(8*n*m*z->GetNz()); mglPoint t(wire||full?NAN:0,0,1); double z0=gr->GetOrgZ('x'); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; const long ni=1+(n-1)/dx, mi=1+(m-1)/dy; const long kq = gr->AllocPnts(8*ni*mi); #pragma omp parallel for collapse(2) for(long dj=0;djv(i,j,k), c = gr->GetC(ss,zz); mglPoint xx=GetX(x,i,j,k), yy = GetY(y,i,j,k); double x1 = iv(i+dx,j,k):NAN; double z2 = jv(i,j+dy,k):NAN; mglPoint q(xx.y,yy.y,0); mglPoint s(xx.z,yy.z,0); long iq = kq+8*(di+ni*dj); gr->AddPntQ(iq,mglPoint(xx.x,yy.x,zz),c,t); gr->AddPntQ(iq+1,mglPoint(x1,y1,zz),c,t); gr->AddPntQ(iq+2,mglPoint(x2,y2,zz),c,t); gr->AddPntQ(iq+3,mglPoint(x3,y3,zz),c,t); if(full) { gr->AddPntQ(iq+4,mglPoint(xx.x,yy.x,z0),c,t); gr->AddPntQ(iq+5,mglPoint(x1,y1,z0),c,t); gr->AddPntQ(iq+6,mglPoint(x2,y2,z0),c,t); gr->AddPntQ(iq+7,mglPoint(x3,y3,z0),c,t); } else { gr->AddPntQ(iq+4,mglPoint(x1,y1,z1),c,wire?t:q); gr->AddPntQ(iq+5,mglPoint(x3,y3,z1),c,wire?t:q); gr->AddPntQ(iq+6,mglPoint(x2,y2,z2),c,wire?t:s); gr->AddPntQ(iq+7,mglPoint(x3,y3,z2),c,wire?t:s); } } if(wire) for(long dj=0;djline_plot(iq,iq+1); gr->line_plot(iq,iq+2); gr->line_plot(iq+3,iq+1); gr->line_plot(iq+3,iq+2); if(full) { gr->line_plot(iq+4,iq+5); gr->line_plot(iq+4,iq+6); gr->line_plot(iq+7,iq+5); gr->line_plot(iq+7,iq+6); gr->line_plot(iq,iq+4); gr->line_plot(iq+2,iq+6); gr->line_plot(iq+1,iq+5); gr->line_plot(iq+3,iq+7); } else { gr->line_plot(iq+1,iq+4); gr->line_plot(iq+5,iq+4); gr->line_plot(iq+5,iq+3); gr->line_plot(iq+2,iq+6); gr->line_plot(iq+3,iq+7); gr->line_plot(iq+6,iq+7); } } else for(long dj=0;djquad_plot(iq,iq+1,iq+2,iq+3); if(full) { gr->quad_plot(iq,iq+1,iq+4,iq+5); gr->quad_plot(iq,iq+2,iq+4,iq+6); gr->quad_plot(iq+3,iq+1,iq+7,iq+5); gr->quad_plot(iq+3,iq+2,iq+7,iq+6); gr->quad_plot(iq+4,iq+5,iq+6,iq+7); } else { gr->quad_plot(iq+1,iq+3,iq+4,iq+5); gr->quad_plot(iq+2,iq+3,iq+6,iq+7); } } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxs(HMGL gr, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()+1), y(z->GetNy()+1); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_boxs_xy(gr,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxs_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_boxs_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxs_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_boxs(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Tile series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tile_xyc(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,c,"Tile",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Tile",cgid++); long ly = x->GetNy()>=z->GetNy() ? y->GetNy() : y->GetNx(), lx = x->GetNx(); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n*m, dx = n>d?n/d:1, dy = m>d?m/d:1; long ss = gr->AddTexture(sch); gr->Reserve(4*n*m*z->GetNz()); bool alongX = mglchr(sch,'x'); bool alongY = mglchr(mglchr(sch,':'),'y'); const long ni=1+(n-1)/dx, mi=1+(m-1)/dy; mglPoint s(0,0,1); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; const long kq = gr->AllocPnts(4*ni*mi); if(alongX) #pragma omp parallel for collapse(2) for(long dj=0;djv(i,j,k), cc = gr->GetC(ss,c->v(i,j,k)); double xx = GetX(x,i,j,k).x, yy = GetY(y,i,j,k).x; gr->AddPntQ(iq,mglPoint(xx,yy,zz),cc,s); zz = iv(i+dx,j,k):NAN; yy = iAddPntQ(iq+1,mglPoint(xx,yy,zz),cc,s); zz = jv(i,j+dy,k):NAN; yy = jAddPntQ(iq+2,mglPoint(xx,yy,zz),cc,s); zz = iv(i+dx,j+dy,k):NAN; yy = iAddPntQ(iq+3,mglPoint(xx,yy,zz),cc,s); } else if(alongY) #pragma omp parallel for collapse(2) for(long dj=0;djv(i,j,k), cc = gr->GetC(ss,c->v(i,j,k)); double xx = GetX(x,i,j,k).x, yy = GetY(y,i,j,k).x; gr->AddPntQ(iq,mglPoint(xx,yy,zz),cc,s); xx = iv(i+dx,j,k):NAN; gr->AddPntQ(iq+1,mglPoint(xx,yy,zz),cc,s); xx = jv(i,j+dy,k):NAN; gr->AddPntQ(iq+2,mglPoint(xx,yy,zz),cc,s); xx = iv(i+dx,j+dy,k):NAN; gr->AddPntQ(iq+3,mglPoint(xx,yy,zz),cc,s); } else #pragma omp parallel for collapse(2) for(long dj=0;djv(i,j,k), cc = gr->GetC(ss,c->v(i,j,k)); double xx = GetX(x,i,j,k).x, yy = GetY(y,i,j,k).x; gr->AddPntQ(iq,mglPoint(xx,yy,zz),cc,s); xx = iAddPntQ(iq+1,mglPoint(xx,yy,zz),cc,s); xx = jAddPntQ(iq+2,mglPoint(xx,yy,zz),cc,s); xx = iAddPntQ(iq+3,mglPoint(xx,yy,zz),cc,s); } for(long i=0;iquad_plot(iq,iq+1,iq+2,iq+3); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tile_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_tile_xyc(gr,x,y,z,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tile(HMGL gr, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()+1), y(z->GetNy()+1); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_tile_xyc(gr,&x,&y,z,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tile_xyc_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tile_xyc(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tile_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tile_xy(_GR_, _DA_(x), _DA_(y), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tile_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tile(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // TileS series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tiles_xyc(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT s, HCDT c, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,s,"TileS",true)) return; if(mgl_check_dim2(gr,x,y,z,c,"TileS",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TileS",cgid++); long ly = x->GetNy()>=z->GetNy() ? y->GetNy() : y->GetNx(), lx = x->GetNx(); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n*m, dx = n>d?n/d:1, dy = m>d?m/d:1; long sc = gr->AddTexture(sch); gr->Reserve(4*n*m*z->GetNz()); bool alongX = mglchr(sch,'x'); bool alongY = mglchr(mglchr(sch,':'),'y'); const long ni=1+(n-1)/dx, mi=1+(m-1)/dy; mglPoint t(0,0,1); for(long k=0;kGetNz();k++) { if(gr->NeedStop()) break; const long kq = gr->AllocPnts(4*ni*mi); if(alongX) #pragma omp parallel for collapse(2) for(long dj=0;djGetC(sc,c->v(i,j,k)); double ss = (1-gr->GetA(s->v(i,j,k)))/2, sm = 1-ss; double x1 = z->v(i,j,k), y1 = GetY(y,i,j,k).x; double x2=NAN,x3=NAN,x4=NAN,y2=NAN,y3=NAN,y4=NAN; if(iv(i+dx,j,k)-x1; y2 = GetY(y,i+dx,j,k).x-y1; } if(jv(i,j+dy,k)-x1; y4 = GetY(y,i,j+dy,k).x-y1; } if(iv(i+dx,j+dy,k)-x2-x4-x1; y3 = GetY(y,i+dx,j+dy,k).x-y2-y4-y1; } gr->AddPntQ(iq,mglPoint(xx, y1+y2*ss+y4*ss+y3*ss*ss, x1+x2*ss+x4*ss+x3*ss*ss),cc,t); gr->AddPntQ(iq+1,mglPoint(xx, y1+y2*sm+y4*ss+y3*ss*sm, x1+x2*sm+x4*ss+x3*ss*sm),cc,t); gr->AddPntQ(iq+2,mglPoint(xx, y1+y2*ss+y4*sm+y3*ss*sm, x1+x2*ss+x4*sm+x3*ss*sm),cc,t); gr->AddPntQ(iq+3,mglPoint(xx, y1+y2*sm+y4*sm+y3*sm*sm, x1+x2*sm+x4*sm+x3*sm*sm),cc,t); } else if(alongY) #pragma omp parallel for collapse(2) for(long dj=0;djGetC(sc,c->v(i,j,k)); double ss = (1-gr->GetA(s->v(i,j,k)))/2, sm = 1-ss; double x1 = GetX(x,i,j,k).x, y1 = z->v(i,j,k); double x2=NAN,x3=NAN,x4=NAN,y2=NAN,y3=NAN,y4=NAN; if(iv(i+dx,j,k)-y1; } if(jv(i,j+dy,k)-y1; } if(iv(i+dx,j+dy,k)-y2-y4-y1; } gr->AddPntQ(iq,mglPoint(x1+x2*ss+x4*ss+x3*ss*ss, yy, y1+y2*ss+y4*ss+y3*ss*ss),cc,t); gr->AddPntQ(iq+1,mglPoint(x1+x2*sm+x4*ss+x3*ss*sm, yy, y1+y2*sm+y4*ss+y3*ss*sm),cc,t); gr->AddPntQ(iq+2,mglPoint(x1+x2*ss+x4*sm+x3*ss*sm, yy, y1+y2*ss+y4*sm+y3*ss*sm),cc,t); gr->AddPntQ(iq+3,mglPoint(x1+x2*sm+x4*sm+x3*sm*sm, yy, y1+y2*sm+y4*sm+y3*sm*sm),cc,t); } else #pragma omp parallel for collapse(2) for(long dj=0;djv(i,j,k), cc = gr->GetC(sc,c->v(i,j,k)); double ss = (1-gr->GetA(s->v(i,j,k)))/2, sm = 1-ss; double x1 = GetX(x,i,j,k).x, y1 = GetY(y,i,j,k).x; double x2=NAN,x3=NAN,x4=NAN,y2=NAN,y3=NAN,y4=NAN; if(iAddPntQ(iq,mglPoint(x1+x2*ss+x4*ss+x3*ss*ss, y1+y2*ss+y4*ss+y3*ss*ss, zz),cc,t); gr->AddPntQ(iq+1,mglPoint(x1+x2*sm+x4*ss+x3*ss*sm, y1+y2*sm+y4*ss+y3*ss*sm, zz),cc,t); gr->AddPntQ(iq+2,mglPoint(x1+x2*ss+x4*sm+x3*ss*sm, y1+y2*ss+y4*sm+y3*ss*sm, zz),cc,t); gr->AddPntQ(iq+3,mglPoint(x1+x2*sm+x4*sm+x3*sm*sm, y1+y2*sm+y4*sm+y3*sm*sm, zz),cc,t); } for(long i=0;iquad_plot(iq,iq+1,iq+2,iq+3); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tiles_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT s, const char *sch, const char *opt) { mgl_tiles_xyc(gr,x,y,z,s,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tiles(HMGL gr, HCDT z, HCDT s, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(z->GetNx()+1), y(z->GetNy()+1); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_tiles_xyc(gr,&x,&y,z,s,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tiles_xyc_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tiles_xyc(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tiles_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tiles_xy(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tiles_(uintptr_t *gr, uintptr_t *a, uintptr_t *r, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tiles(_GR_, _DA_(a), _DA_(r), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Map series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_map_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt) { long n=ax->GetNx(),m=ax->GetNy(); if(mgl_check_dim2(gr,x,y,ax,ay,"Map")) return; bool nboth = !(x->GetNx()==n && y->GetNx()==n && x->GetNy()==m && y->GetNy()==m); gr->SaveState(opt); static int cgid=1; gr->StartGroup("Map",cgid++); long ss = gr->AddTexture(mgl_have_color(sch)?sch:"rgb",2); long s = nboth ?1:n; mglPoint t(NAN); gr->Reserve(n*m); const long kq = gr->AllocPnts(n*m); #pragma omp parallel for collapse(2) for(long j=0;j0 ? 1:0, s2 = iv(i+s2,j)-ax->v(i-s1,j))/(GetX(x,i+s2,j).x-GetX(x,i-s1,j).x); mreal ydx = (ay->v(i+s2,j)-ay->v(i-s1,j))/(GetX(x,i+s2,j).x-GetX(x,i-s1,j).x); s1 = j>0 ? s:0; s2 = jv(i,j+s2)-ax->v(i,j-s1))/(GetY(y,i,j+s2).x-GetY(y,i,j-s1).x); mreal ydy = (ay->v(i,j+s2)-ay->v(i,j-s1))/(GetY(y,i,j+s2).x-GetY(y,i,j-s1).x); xdx = xdx*ydy - xdy*ydx; // Jacobian mreal xx,yy; if(nboth) { xx = (x->v(i) - gr->Min.x)/(gr->Max.x - gr->Min.x); yy = (y->v(j) - gr->Min.y)/(gr->Max.y - gr->Min.y); } else { xx = (x->v(i,j) - gr->Min.x)/(gr->Max.x - gr->Min.x); yy = (y->v(i,j) - gr->Min.y)/(gr->Max.y - gr->Min.y); } if(xx<0) xx=0; if(xx>=1) xx=1/MGL_FEPSILON; if(yy<0) yy=0; if(yy>=1) yy=1/MGL_FEPSILON; gr->AddPntQ(kq+i+n*j,mglPoint(ax->v(i,j), ay->v(i,j), xdx),gr->GetC(ss,xx,false),t,yy); } if(sch && mglchr(sch,'.')) for(long i=0;imark_plot(kq+i,'.'); else mgl_surf_plot(gr,kq,n,m); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_map(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_map_xy(gr,&x,&y,ax,ay,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_map_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_map_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_map_(uintptr_t *gr, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_map(_GR_, _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/fft.cpp0000644000175000017500000012234513513030041015226 0ustar alastairalastair/*************************************************************************** * fft.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/datac.h" #include "mgl2/data.h" #include "mgl2/thread.h" #if MGL_HAVE_GSL #include #include #include #include #endif //----------------------------------------------------------------------------- void MGL_EXPORT mglStartThreadT(void *(*func)(void *), long n, void *a, double *b, const void *v, void **w, const long *p, const void *re, const void *im) { if(!func) return; #if MGL_HAVE_PTHREAD if(mglNumThr<1) mgl_set_num_thr(0); if(mglNumThr>1) { pthread_t *tmp=new pthread_t[mglNumThr]; mglThreadT *par=new mglThreadT[mglNumThr]; for(long i=0;i0) for(long i=0;i0) for(long i=0;ip[0]; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { void *w = mgl_fft_alloc_thr(nx); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) mgl_fft(t->b+2*nx*i, 1, nx, t->v, w, t->p[3]); mgl_fft_free_thr(w); } return 0; } static void* mgl_ffty(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0],ny=t->p[1]; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { void *w = mgl_fft_alloc_thr(ny); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) mgl_fft(t->b+2*(i%nx)+2*nx*ny*(i/nx), nx, ny, t->v, w, t->p[3]); mgl_fft_free_thr(w); } return 0; } static void* mgl_fftz(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0],ny=t->p[1],nz=t->p[2]; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { void *w = mgl_fft_alloc_thr(nz); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) mgl_fft(t->b+2*i, nx*ny, nz, t->v, w, t->p[3]); mgl_fft_free_thr(w); } return 0; } void MGL_EXPORT mgl_datac_fft(HADT d, const char *dir) { if(!dir || *dir==0) return; long nx = d->nx, ny = d->ny, nz = d->nz; void *wt=0; bool clear=false; long par[4]={nx,ny,nz,strchr(dir,'i')!=0}; #if MGL_USE_DOUBLE double *a = (double *)(d->a); #else double *a = new double[2*nx*ny*nz]; // manually convert to double #pragma omp parallel for for(long i=0;ia[i]); a[2*i+1] = imag(d->a[i]); } #endif if(strchr(dir,'x') && nx>1) { if(mgl_fft_data.wnx==nx) wt = mgl_fft_data.wtx; else { clear = true; wt = mgl_fft_alloc(nx,0,0); } mglStartThreadT(mgl_fftx,ny*nz,0,a,wt,0,par); if(mgl_fft_data.wnx==0) { clear = false; mgl_fft_data.wtx = wt; mgl_fft_data.wnx=nx; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'y') && ny>1) { if(mgl_fft_data.wny==ny) wt = mgl_fft_data.wty; else { clear = true; wt = mgl_fft_alloc(ny,0,0); } mglStartThreadT(mgl_ffty,nx*nz,0,a,wt,0,par); if(mgl_fft_data.wny==0) { clear = false; mgl_fft_data.wty = wt; mgl_fft_data.wny=ny; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'z') && nz>1) { if(mgl_fft_data.wnz==nz) wt = mgl_fft_data.wtz; else { clear = true; wt = mgl_fft_alloc(nz,0,0); } mglStartThreadT(mgl_fftz,nx*ny,0,a,wt,0,par); if(mgl_fft_data.wnz==0) { clear = false; mgl_fft_data.wtz = wt; mgl_fft_data.wnz=nz; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } #if !MGL_USE_DOUBLE #pragma omp parallel for for(long i=0;ia[i] = dual(a[2*i], a[2*i+1]); delete []a; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_fourier(HMDT re, HMDT im, const char *dir) { if(!dir || *dir==0) return; long nx = re->nx, ny = re->ny, nz = re->nz; if(nx*ny*nz != im->nx*im->ny*im->nz || dir[0]==0) return; bool clear=false; void *wt=0; long par[4]={nx,ny,nz,strchr(dir,'i')!=0}; double *a = new double[2*nx*ny*nz]; #pragma omp parallel for for(long i=0;ia[i]; a[2*i+1] = im->a[i]; } if(strchr(dir,'x') && nx>1) { if(mgl_fft_data.wnx==nx) wt = mgl_fft_data.wtx; else { clear = true; wt = mgl_fft_alloc(nx,0,0); } mglStartThreadT(mgl_fftx,ny*nz,0,a,wt,0,par); if(mgl_fft_data.wnx==0) { mgl_fft_data.wtx = wt; clear = false; mgl_fft_data.wnx=nx; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'y') && ny>1) { if(mgl_fft_data.wny==ny) wt = mgl_fft_data.wty; else { clear = true; wt = mgl_fft_alloc(ny,0,0); } mglStartThreadT(mgl_ffty,nx*nz,0,a,wt,0,par); if(mgl_fft_data.wny==0) { mgl_fft_data.wty = wt; clear = false; mgl_fft_data.wny=ny; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'z') && nz>1) { if(mgl_fft_data.wnz==nz) wt = mgl_fft_data.wtz; else { clear = true; wt = mgl_fft_alloc(nz,0,0); } mglStartThreadT(mgl_fftz,nx*ny,0,a,wt,0,par); if(mgl_fft_data.wnz==0) { mgl_fft_data.wtz = wt; clear = false; mgl_fft_data.wnz=nz; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } #pragma omp parallel for for(long i=0;ia[i] = a[2*i]; im->a[i] = a[2*i+1]; } delete []a; } //----------------------------------------------------------------------------- static void* mgl_envx(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0]; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nx]; void *w = mgl_fft_alloc_thr(nx); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jv, w, false); for(long j=0;jv, w, true); for(long j=0;jp[0],ny=t->p[1]; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*ny]; void *w = mgl_fft_alloc_thr(ny); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jv, t->w[t->id], false); for(long j=0;jv, t->w[t->id], true); for(long j=0;jp[0],ny=t->p[1],nz=t->p[2],k=nx*ny; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nz]; void *w = mgl_fft_alloc_thr(nz); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jv, t->w[t->id], false); for(long j=0;jv, t->w[t->id], true); for(long j=0;jnx,ny=d->ny,nz=d->nz,par[3]={nx,ny,nz}; bool clear=false; void *wt=0; if(dir=='x' && nx>1) { if(mgl_fft_data.wnx==nx) wt = mgl_fft_data.wtx; else { clear = true; wt = mgl_fft_alloc(nx,0,0); } mglStartThreadT(mgl_envx,ny*nz,d->a,0,wt,0,par); if(mgl_fft_data.wnx==0) { mgl_fft_data.wtx = wt; clear = false; mgl_fft_data.wnx=nx; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(dir=='y' && ny>1) { if( mgl_fft_data.wny==ny) wt = mgl_fft_data.wty; else { clear = true; wt = mgl_fft_alloc(ny,0,0); } mglStartThreadT(mgl_envy,nx*nz,d->a,0,wt,0,par); if(mgl_fft_data.wny==0) { mgl_fft_data.wty = wt; clear = false; mgl_fft_data.wny=ny; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(dir=='z' && nz>1) { if(mgl_fft_data.wnz==nz) wt = mgl_fft_data.wtz; else { clear = true; wt = mgl_fft_alloc(nz,0,0); } mglStartThreadT(mgl_envz,nx*ny,d->a,0,wt,0,par); if(mgl_fft_data.wnz==0) { mgl_fft_data.wtz = wt; clear = false; mgl_fft_data.wnz=nz; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_envelop(HADT c, char dir) { mglData re(c->nx, c->ny, c->nz), im(c->nx, c->ny, c->nz); long n = c->GetNN(); #pragma omp parallel for for(long i=0;ia[i]); im.a[i]=imag(c->a[i]); } mgl_data_envelop(&re, dir); mgl_data_envelop(&im, dir); #pragma omp parallel for for(long i=0;ia[i] = dual(re.a[i], im.a[i]); } //----------------------------------------------------------------------------- static void* mgl_stfa1(void *par) { mglThreadT *t=(mglThreadT *)par; long mx=t->p[0],mz=t->p[2],dn=t->p[3],dd=dn/2,ny=t->p[4]; mreal *d = (mreal*)t->a; HCDT re = (HCDT)t->re, im = (HCDT)t->im; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *a = new double[4*dn], ff; void *w = mgl_fft_alloc_thr(2*dn); #pragma omp for nowait for(long ii=t->id;iin;ii+=mglNumThr) { long i = ii%mx, j = ii/mx, i0; for(long k=0;k<2*dn;k++) { i0 = k-dd+j*dn; ff = 1; if(i0<0) i0=0; else if(i0>=ny) i0=ny-1; if(k=dn+dd) { ff = 0.5*(k-3.5*dd)/dd; ff=0.5-ff*(3-ff*ff); } a[2*k] = re->v(i,i0)*ff; a[2*k+1] = im->v(i,i0)*ff; } mgl_fft(a, 1, 2*dn, t->v, w, false); for(long k=0;kp[0],my=t->p[1],dn=t->p[3],dd=dn/2,nx=t->p[4]; mreal *d = (mreal*)t->a; HCDT re = (HCDT)t->re, im = (HCDT)t->im; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *a = new double[4*dn], ff; void *w = mgl_fft_alloc_thr(2*dn); #pragma omp for nowait for(long ii=t->id;iin;ii+=mglNumThr) { long i = ii%my, j = ii/my, i0; for(long k=0;k<2*dn;k++) { i0 = k-dd+i*dn; ff = 1; if(i0<0) i0=0; else if(i0>=nx) i0=nx-1; if(k=3*dd) { ff = 0.5*(k-3.5*dd)/dd; ff=0.5-ff*(3-ff*ff); } a[2*k] = re->v(i0,j)*ff; a[2*k+1] = im->v(i0,j)*ff; } mgl_fft(a, 1, 2*dn, t->v, w, false); for(long k=0;kGetNx(), ny = re->GetNy(); if(nx*ny!=im->GetNx()*im->GetNy()) return 0; void *wt = mgl_fft_alloc(2*dn,0,0); long mx,my,mz; mglData *d=new mglData; if(dir=='y') { mx = nx; my = dn; mz = ny/dn; mgl_data_create(d, mx, mz, my); long par[5]={mx,my,mz,dn,ny}; mglStartThreadT(mgl_stfa1,mx*mz,d->a,0,wt,0,par,re,im); } else { mx = dn; my = nx/dn; mz = ny; mgl_data_create(d, my, mx, mz); long par[5]={mx,my,mz,dn,nx}; mglStartThreadT(mgl_stfa2,my*mz,d->a,0,wt,0,par,re,im); } mgl_fft_free(wt,0,0); return d; } //----------------------------------------------------------------------------- static void* mgl_sinx(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0]; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nx], f=sqrt(2./nx); void *w = mgl_fft_alloc_thr(nx); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { long k = i*nx; memset(b,0,2*nx*sizeof(double)); for(long j=1;jv,w,false); a[k]=0; a[k+1]=b[0]*f/2; // fill sinfft for(long j=1;jp[0],ny=t->p[1]; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*ny], f=sqrt(2./ny); void *w = mgl_fft_alloc_thr(ny); #pragma omp for nowait for(long ii=t->id;iin;ii+=mglNumThr) { long i = ii%nx, k = ii/nx; memset(b,0,2*ny*sizeof(double)); for(long j=1;jv,w,false); a[i+nx*ny*k]=0; a[i+nx*(ny*k+1)]=b[0]*f/2; // fill sinfft for(long j=1;jp[0],ny=t->p[1],nz=t->p[2],k=nx*ny; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nz], f=sqrt(2./nz); void *w = mgl_fft_alloc_thr(nz); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { memset(b,0,2*nz*sizeof(double)); for(long j=1;jv,w,false); a[i]=0; a[i+k]=b[0]*f/2; // fill sinfft for(long j=1;jnx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz}; if(strchr(dir,'x') && nx>1) { if(mgl_fft_data.wnx==nx) wt = mgl_fft_data.wtx; else { clear = true; wt = mgl_fft_alloc(nx,0,0); } mglStartThreadT(mgl_sinx,ny*nz,d->a,0,wt,0,par); if(mgl_fft_data.wnx==0) { mgl_fft_data.wtx = wt; clear = false; mgl_fft_data.wnx=nx; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'y') && ny>1) { if(mgl_fft_data.wny==ny) wt = mgl_fft_data.wty; else { clear = true; wt = mgl_fft_alloc(ny,0,0); } mglStartThreadT(mgl_siny,nx*nz,d->a,0,wt,0,par); if(mgl_fft_data.wny==0) { mgl_fft_data.wty = wt; clear = false; mgl_fft_data.wny=ny; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'z') && nz>1) { if(mgl_fft_data.wnz==nz) wt = mgl_fft_data.wtz; else { clear = true; wt = mgl_fft_alloc(nz,0,0); } mglStartThreadT(mgl_sinz,nx*ny,d->a,0,wt,0,par); if(mgl_fft_data.wnz==0) { mgl_fft_data.wtz = wt; clear = false; mgl_fft_data.wnz=nz; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_sinfft(HADT c, const char *dir) { if(!dir || *dir==0) return; mglData re(c->nx, c->ny, c->nz), im(c->nx, c->ny, c->nz); long n = c->GetNN(); #pragma omp parallel for for(long i=0;ia[i]); im.a[i]=imag(c->a[i]); } mgl_data_sinfft(&re, dir); mgl_data_sinfft(&im, dir); #pragma omp parallel for for(long i=0;ia[i] = dual(re.a[i], im.a[i]); } //----------------------------------------------------------------------------- static void* mgl_cosx(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0],nn=nx-1; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nx], f=sqrt(2./nn); void *w = mgl_fft_alloc_thr(nn); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { long k = i*nx; memset(b,0,2*nx*sizeof(double)); for(long j=0;jv,w,false); double f1=0.5*(a[k]-a[nn+k]), s=-1; a[nn+k]=0.5*(a[k]+a[nn+k]*((nn%2)?-1:1)); for(long j=1;jp[0],ny=t->p[1],nn=ny-1; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*ny], f=sqrt(2./nn); void *w = mgl_fft_alloc_thr(nn); #pragma omp for nowait for(long ii=t->id;iin;ii+=mglNumThr) { long i = ii%nx, k = ii/nx; memset(b,0,2*ny*sizeof(double)); for(long j=0;jv,w,false); double f1=0.5*(a[i+nx*ny*k]-a[i+nx*(ny*k+nn)]), s=-1; a[i+nx*(ny*k+nn)]=0.5*(a[i+nx*ny*k]+a[i+nx*(ny*k+nn)]*((nn%2)?-1:1)); for(long j=1;jp[0],ny=t->p[1],nz=t->p[2],k=nx*ny,nn=nz-1; mreal *a = (mreal*)t->a; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nz], f=sqrt(2./nn); void *w = mgl_fft_alloc_thr(nn); #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { memset(b,0,2*nz*sizeof(double)); for(long j=0;jv,w,false); double f1=0.5*(a[i]-a[i+k*nn]), s=-1; a[i+k*nn]=0.5*(a[i]+a[i+k*nn]*((nn%2)?-1:1)); for(long j=1;jnx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz}; if(strchr(dir,'x') && nx>1) { if(mgl_fft_data.wnx==nx-1) wt = mgl_fft_data.wtx; else { clear = true; wt = mgl_fft_alloc(nx-1,0,0); } mglStartThreadT(mgl_cosx,ny*nz,d->a,0,wt,0,par); if(mgl_fft_data.wnx==0) { mgl_fft_data.wtx = wt; clear = false; mgl_fft_data.wnx=nx-1; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'y') && ny>1) { if(mgl_fft_data.wny==ny-1) wt = mgl_fft_data.wty; else { clear = true; wt = mgl_fft_alloc(ny-1,0,0); } mglStartThreadT(mgl_cosy,nx*nz,d->a,0,wt,0,par); if(mgl_fft_data.wny==0) { mgl_fft_data.wty = wt; clear = false; mgl_fft_data.wny=ny-1; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } if(strchr(dir,'z') && nz>1) { if(mgl_fft_data.wnz==nz-1) wt = mgl_fft_data.wtz; else { clear = true; wt = mgl_fft_alloc(nz-1,0,0); } mglStartThreadT(mgl_cosz,nx*ny,d->a,0,wt,0,par); if(mgl_fft_data.wnz==0) { mgl_fft_data.wtz = wt; clear = false; mgl_fft_data.wnz=nz-1; } if(clear) { mgl_fft_free(wt,0,0); clear = false; } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_cosfft(HADT c, const char *dir) { if(!dir || *dir==0) return; mglData re(c->nx, c->ny, c->nz), im(c->nx, c->ny, c->nz); long n = c->GetNN(); #pragma omp parallel for for(long i=0;ia[i]); im.a[i]=imag(c->a[i]); } mgl_data_cosfft(&re, dir); mgl_data_cosfft(&im, dir); #pragma omp parallel for for(long i=0;ia[i] = dual(re.a[i], im.a[i]); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_transform_a(HCDT am, HCDT ph, const char *tr) { long nx = am->GetNx(), ny = am->GetNy(), nz = am->GetNz(); if(nx*ny*nz != ph->GetNN() || !tr || tr[0]==0) return 0; mglData re(nx,ny,nz), im(nx,ny,nz); #pragma omp parallel for for(long i=0;ivthr(i), p=ph->vthr(i); re.a[i] = a*cos(p); im.a[i] = a*sin(p); } return mgl_transform(&re, &im, tr); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_transform(HCDT re, HCDT im, const char *tr) { if(!tr || *tr==0) return 0; long nx = re->GetNx(), ny = re->GetNy(), nz = re->GetNz(); if(nx*ny*nz != im->GetNN() || tr[0]==0) return 0; mglData rr(re),ii(im); if(strchr(tr,'i') && strchr(tr,'f')) // general case { if(tr[0]=='f') mgl_data_fourier(&rr,&ii,"x"); if(tr[0]=='i') mgl_data_fourier(&rr,&ii,"xi"); if(tr[1]=='f') mgl_data_fourier(&rr,&ii,"y"); if(tr[1]=='i') mgl_data_fourier(&rr,&ii,"yi"); if(tr[2]=='f') mgl_data_fourier(&rr,&ii,"z"); if(tr[2]=='i') mgl_data_fourier(&rr,&ii,"zi"); } else if(strchr(tr,'f')) // do Fourier only once for speeding up { char str[4] = " "; if(tr[0]=='f') str[0]='x'; if(tr[1]=='f') str[1]='y'; if(tr[2]=='f') str[2]='z'; mgl_data_fourier(&rr,&ii,str); } else if(strchr(tr,'i')) // do Fourier only once for speeding up { char str[5] = " i"; if(tr[0]=='i') str[0]='x'; if(tr[1]=='i') str[1]='y'; if(tr[2]=='i') str[2]='z'; mgl_data_fourier(&rr,&ii,str); } else if(strchr(tr,'s')) // do Fourier only once for speeding up { if(tr[0]=='s') { rr.SinFFT("x"); ii.SinFFT("x"); } if(tr[1]=='s') { rr.SinFFT("y"); ii.SinFFT("y"); } if(tr[2]=='s') { rr.SinFFT("z"); ii.SinFFT("z"); } } else if(strchr(tr,'c')) // do Fourier only once for speeding up { if(tr[0]=='c') { rr.CosFFT("x"); ii.CosFFT("x"); } if(tr[1]=='c') { rr.CosFFT("y"); ii.CosFFT("y"); } if(tr[2]=='c') { rr.CosFFT("z"); ii.CosFFT("z"); } } else if(strchr(tr,'h')) // do Fourier only once for speeding up { if(tr[0]=='h') { rr.Hankel("x"); ii.Hankel("x"); } if(tr[1]=='h') { rr.Hankel("y"); ii.Hankel("y"); } if(tr[2]=='h') { rr.Hankel("z"); ii.Hankel("z"); } } mglData *d = new mglData(nx, ny, nz); #pragma omp parallel for for(long i=0;ia[i] = hypot(rr.a[i],ii.a[i]); return d; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_transform_a_(uintptr_t *am, uintptr_t *ph, const char *tr, int l) { char *s=new char[l+1]; memcpy(s,tr,l); s[l]=0; uintptr_t res = uintptr_t(mgl_transform_a(_DA_(am),_DA_(ph),s)); delete []s; return res; } uintptr_t MGL_EXPORT mgl_transform_(uintptr_t *re, uintptr_t *im, const char *tr, int l) { char *s=new char[l+1]; memcpy(s,tr,l); s[l]=0; uintptr_t res = uintptr_t(mgl_transform(_DA_(re),_DA_(im),s)); delete []s; return res; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_envelop_(uintptr_t *d, const char *dir, int) { mgl_data_envelop(_DT_,*dir); } void MGL_EXPORT mgl_datac_envelop_(uintptr_t *d, const char *dir, int) { mgl_datac_envelop(_DC_,*dir); } //----------------------------------------------------------------------------- #if MGL_HAVE_GSL static void* mgl_chnkx(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0]; dual *a = (dual*)t->a; const gsl_dht *dht = (const gsl_dht*)t->v; double mm = gsl_sf_bessel_zero_J0(nx+1); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[3*nx]; #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jp[0],ny=t->p[1]; dual *a = (dual*)t->a; const gsl_dht *dht = (const gsl_dht*)t->v; double mm = gsl_sf_bessel_zero_J0(ny+1); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[3*ny]; #pragma omp for nowait for(long ii=t->id;iin;ii+=mglNumThr) { long i = ii%nx, k = ii/nx; for(long j=0;jp[0]*t->p[1],nz=t->p[2]; dual *a = (dual*)t->a; const gsl_dht *dht = (const gsl_dht*)t->v; double mm = gsl_sf_bessel_zero_J0(nz+1); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[3*nz]; #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jnx, ny=d->ny, nz=d->nz; long par[3]={nx,ny,nz}; if(strchr(dir,'x') && nx>1) { if(mgl_fft_data.hnx==nx) dht = (gsl_dht *)mgl_fft_data.htx; else { dht = gsl_dht_new(nx,0,1); clear = true; } mglStartThreadT(mgl_chnkx,ny*nz,d->a,0,dht,0,par); if(mgl_fft_data.hnx==0) { mgl_fft_data.htx = dht; clear = false; mgl_fft_data.hnx=nx; } } if(strchr(dir,'y') && ny>1) { if(mgl_fft_data.hny==ny) dht = (gsl_dht *)mgl_fft_data.hty; else { dht = gsl_dht_new(ny,0,1); clear = true; } mglStartThreadT(mgl_chnky,nx*nz,d->a,0,dht,0,par); if(mgl_fft_data.hny==0) { mgl_fft_data.hty = dht; clear = false; mgl_fft_data.hny=ny; } } if(strchr(dir,'z') && nz>1) { if(mgl_fft_data.hnz==nz) dht = (gsl_dht *)mgl_fft_data.htz; else { dht = gsl_dht_new(nz,0,1); clear = true; } mglStartThreadT(mgl_chnkz,nx*ny,d->a,0,dht,0,par); if(mgl_fft_data.hnz==0) { mgl_fft_data.htz = dht; clear = false; mgl_fft_data.hnz=nz; } } if(clear) gsl_dht_free(dht); } #else void MGL_EXPORT mgl_datac_hankel(HADT , const char *){} #endif void MGL_EXPORT mgl_datac_hankel_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_hankel(_DC_,s); delete []s; } //----------------------------------------------------------------------------- #if MGL_HAVE_GSL static void* mgl_hnkx(void *par) { mglThreadT *t=(mglThreadT *)par; long nx=t->p[0]; mreal *a = (mreal*)t->a; const gsl_dht *dht = (const gsl_dht*)t->v; double mm = gsl_sf_bessel_zero_J0(nx+1); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nx]; #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jp[0],ny=t->p[1]; mreal *a = (mreal*)t->a; const gsl_dht *dht = (const gsl_dht*)t->v; double mm = gsl_sf_bessel_zero_J0(ny+1); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*ny]; #pragma omp for nowait for(long ii=t->id;iin;ii+=mglNumThr) { long i = ii%nx, k = ii/nx; for(long j=0;jp[0]*t->p[1],nz=t->p[2]; mreal *a = (mreal*)t->a; const gsl_dht *dht = (const gsl_dht*)t->v; double mm = gsl_sf_bessel_zero_J0(nz+1); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { double *b = new double[2*nz]; #pragma omp for nowait for(long i=t->id;in;i+=mglNumThr) { for(long j=0;jnx, ny=d->ny, nz=d->nz; long par[3]={nx,ny,nz}; if(strchr(dir,'x') && nx>1) { if(mgl_fft_data.hnx==nx) dht = (gsl_dht *)mgl_fft_data.htx; else { dht = gsl_dht_new(nx,0,1); clear = true; } mglStartThreadT(mgl_hnkx,ny*nz,d->a,0,dht,0,par); if(mgl_fft_data.hnx==0) { mgl_fft_data.htx = dht; clear = false; mgl_fft_data.hnx=nx; } } if(strchr(dir,'y') && ny>1) { if(mgl_fft_data.hny==ny) dht = (gsl_dht *)mgl_fft_data.hty; else { dht = gsl_dht_new(ny,0,1); clear = true; } mglStartThreadT(mgl_hnky,nx*nz,d->a,0,dht,0,par); if(mgl_fft_data.hny==0) { mgl_fft_data.hty = dht; clear = false; mgl_fft_data.hny=ny; } } if(strchr(dir,'z') && nz>1) { if(mgl_fft_data.hnz==nz) dht = (gsl_dht *)mgl_fft_data.htz; else { dht = gsl_dht_new(nz,0,1); clear = true; } mglStartThreadT(mgl_hnkz,nx*ny,d->a,0,dht,0,par); if(mgl_fft_data.hnz==0) { mgl_fft_data.htz = dht; clear = false; mgl_fft_data.hnz=nz; } } if(clear) gsl_dht_free(dht); } #else void MGL_EXPORT mgl_data_hankel(HMDT , const char *){} #endif void MGL_EXPORT mgl_data_hankel_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_hankel(_DT_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_fill_sample(HMDT d, const char *how) { if(!how || *how==0) return; bool kk = mglchr(how,'k'); long n=d->nx,dn=1; mreal *aa=d->a; if(mglchr(how,'y')) { n=d->ny; dn=d->nx; } if(mglchr(how,'z')) { n=d->nz; dn=d->nx*d->ny; } if(mglchr(how,'h')) // Hankel { #if MGL_HAVE_GSL gsl_dht *dht = gsl_dht_new(n,0,1); #pragma omp parallel for for(long i=0;iGetNN();i++) aa[i] = aa[((i%(n*dn))/dn)*dn]; } void MGL_EXPORT mgl_data_fill_sample_(uintptr_t *d, const char *how,int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; mgl_data_fill_sample(_DT_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_fft_(uintptr_t *d, const char *dir, int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_fft(_DC_,s); delete []s; } void MGL_EXPORT mgl_data_fourier_(uintptr_t *re, uintptr_t *im, const char *dir, int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_fourier(_DM_(re),_DM_(im),s); delete []s; } uintptr_t MGL_EXPORT mgl_data_stfa_(uintptr_t *re, uintptr_t *im, int *dn, char *dir, int) { return uintptr_t(mgl_data_stfa(_DA_(re),_DA_(im),*dn,*dir)); } void MGL_EXPORT mgl_data_cosfft_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_cosfft(_DT_,s); delete []s; } void MGL_EXPORT mgl_data_sinfft_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_sinfft(_DT_,s); delete []s; } void MGL_EXPORT mgl_datac_cosfft_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_cosfft(_DC_,s); delete []s; } void MGL_EXPORT mgl_datac_sinfft_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_sinfft(_DC_,s); delete []s; } //----------------------------------------------------------------------------- /*static void* mgl_cor(void *par) { mglThreadC *t=(mglThreadC *)par; dual *a = t->a; const dual *b = t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif for(long i=t->id;in;i+=mglNumThr) a[i] *= conj(b[i]); return 0; }*/ HADT MGL_EXPORT mgl_datac_correl(HCDT d1, HCDT d2, const char *dir) { if(!dir || *dir==0) return 0; if(d2==NULL) d2=d1; long nx = d1->GetNx(), ny = d1->GetNy(), nz = d1->GetNz(); if(nx*ny*nz!=d2->GetNN()) return 0; std::string dirs; if(strchr(dir,'x') && nx>1) dirs += 'x'; if(strchr(dir,'y') && ny>1) dirs += 'y'; if(strchr(dir,'z') && nz>1) dirs += 'z'; if(dirs.empty()) return 0; mglDataC *a = new mglDataC(d1), *b=a; a->FFT(dirs.c_str()); if(d1!=d2) { b = new mglDataC(d2); b->FFT(dirs.c_str()); } // mglStartThreadC(mgl_cor,0,nx*ny*nz,a->a,b->a); // TODO: sth strange #pragma omp parallel for for(long i=0;ia[i] *= conj(b->a[i]); dirs += 'i'; a->FFT(dirs.c_str()); if(d1!=d2) delete b; return a; } uintptr_t MGL_EXPORT mgl_datac_correl_(uintptr_t *d1, uintptr_t *d2, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; uintptr_t res = uintptr_t(mgl_datac_correl(_DA_(d1),_DA_(d2),s)); delete []s; return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_correl(HCDT d1, HCDT d2, const char *dir) { HADT a = mgl_datac_correl(d1,d2,dir); // NOTE: this is not so effective but straightforward way if(!a) return 0; const long nx = d1->GetNx(), ny = d1->GetNy(), nz = d1->GetNz(); mglData *res = new mglData(nx,ny,nz); #pragma omp parallel for for(long i=0;ia[i] = real(a->a[i]); delete a; return res; } uintptr_t MGL_EXPORT mgl_data_correl_(uintptr_t *d1, uintptr_t *d2, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; uintptr_t res = uintptr_t(mgl_data_correl(_DA_(d1),_DA_(d2),s)); delete []s; return res; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_wavelet(HMDT dat, const char *how, int k) { #if MGL_HAVE_GSL gsl_wavelet *w=0; if(mglchr(how,'d')) w = gsl_wavelet_alloc(gsl_wavelet_daubechies, k); else if(mglchr(how,'D')) w = gsl_wavelet_alloc(gsl_wavelet_daubechies_centered, k); else if(mglchr(how,'h')) w = gsl_wavelet_alloc(gsl_wavelet_haar, k); else if(mglchr(how,'H')) w = gsl_wavelet_alloc(gsl_wavelet_haar_centered, k); else if(mglchr(how,'b')) w = gsl_wavelet_alloc(gsl_wavelet_bspline, k); else if(mglchr(how,'B')) w = gsl_wavelet_alloc(gsl_wavelet_bspline_centered, k); if(!w) return; double *a; #if MGL_USE_DOUBLE a = dat->a; #else long nn = dat->GetNN(); a = new double[nn]; #pragma omp parallel for for(long i=0;ia[i]; #endif if(mglchr(how,'x')) #pragma omp parallel { long n = dat->nx; gsl_wavelet_workspace *work = gsl_wavelet_workspace_alloc(n); if(mglchr(how,'i')) #pragma omp for for(long i=0;iny*dat->nz;i++) gsl_wavelet_transform_inverse(w, a+i*n, 1, n, work); else #pragma omp for for(long i=0;iny*dat->nz;i++) gsl_wavelet_transform_forward(w, a+i*n, 1, n, work); gsl_wavelet_workspace_free(work); } if(mglchr(how,'y')) #pragma omp parallel { long n = dat->ny, s = dat->nx; gsl_wavelet_workspace *work = gsl_wavelet_workspace_alloc(n); if(mglchr(how,'i')) #pragma omp for collapse(2) for(long j=0;jnz;j++) for(long i=0;inx;i++) gsl_wavelet_transform_inverse(w, a+i+n*s*j, s, n, work); else #pragma omp for collapse(2) for(long j=0;jnz;j++) for(long i=0;inx;i++) gsl_wavelet_transform_forward(w, a+i+n*s*j, s, n, work); gsl_wavelet_workspace_free(work); } if(mglchr(how,'z')) #pragma omp parallel { long n = dat->nz, s = dat->nx*dat->ny; gsl_wavelet_workspace *work = gsl_wavelet_workspace_alloc(n); if(mglchr(how,'i')) #pragma omp for for(long i=0;inx*dat->ny;i++) gsl_wavelet_transform_inverse(w, a+i, s, n, work); else #pragma omp for for(long i=0;inx*dat->ny;i++) gsl_wavelet_transform_forward(w, a+i, s, n, work); gsl_wavelet_workspace_free(work); } #if !MGL_USE_DOUBLE #pragma omp parallel for for(long i=0;ia[i] = a[i]; delete []a; #endif gsl_wavelet_free (w); #endif } void MGL_EXPORT mgl_data_wavelet_(uintptr_t *d, const char *dir, int *k,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_wavelet(_DT_,s,*k); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_wavelet(HADT c, const char *how, int k) { mglData re(c->nx, c->ny, c->nz), im(c->nx, c->ny, c->nz); long n = c->GetNN(); #pragma omp parallel for for(long i=0;ia[i]); im.a[i]=imag(c->a[i]); } mgl_data_wavelet(&re, how, k); mgl_data_wavelet(&im, how, k); #pragma omp parallel for for(long i=0;ia[i] = dual(re.a[i], im.a[i]); } void MGL_EXPORT mgl_datac_wavelet_(uintptr_t *d, const char *dir, int *k,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_wavelet(_DC_,s,*k); delete []s; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/prim.cpp0000644000175000017500000016411513513030041015417 0ustar alastairalastair/*************************************************************************** * prim.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/canvas.h" #include "mgl2/prim.h" #include "mgl2/font.h" #include "mgl2/plot.h" #include "mgl2/data.h" std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt); //----------------------------------------------------------------------------- // // Mark & Curve series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark(HMGL gr, double x, double y, double z,const char *mark) { char mk = gr->SetPenPal(mark); if(!mk) mk = '.'; if(mgl_isnan(z)) z=2*gr->Max.z-gr->Min.z; static int cgid=1; gr->StartGroup("MarkS",cgid++); long k = gr->AddPnt(mglPoint(x,y,z),gr->CDef,mglPoint(NAN),-1,3); gr->mark_plot(k,mk,gr->GetPenWidth()); gr->AddActive(k); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, const char *pen,int l) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; mgl_mark(_GR_, *x,*y,*z,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ball(HMGL gr, double x, double y, double z) { static int cgid=1; gr->StartGroup("Ball",cgid++); if(mgl_isnan(z)) z=2*gr->Max.z-gr->Min.z; long k = gr->AddPnt(mglPoint(x,y,z),gr->AddTexture('r'),mglPoint(NAN),-1,3); gr->mark_plot(k,'.'); gr->AddActive(k); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ball_(uintptr_t *gr, mreal *x, mreal *y, mreal *z) { mgl_ball(_GR_, *x,*y,*z); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_line(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, const char *pen,int n) { static int cgid=1; gr->StartGroup("Line",cgid++); if(mgl_isnan(z1) || mgl_isnan(z2)) z1=z2=2*gr->Max.z-gr->Min.z; const mglPoint p1(x1,y1,z1), p2(x2,y2,z2), nn(NAN); gr->SetPenPal(pen); n = (n<2) ? 2 : n; const long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;iAddPntQ(kq+i,p1*(1-s)+p2*s,gr->CDef,nn,-1,3); } gr->curve_plot(n,kq); gr->arrow_plot(kq,kq+1,gr->Arrow1); gr->arrow_plot(kq+n-1,kq+n-2,gr->Arrow2); gr->AddActive(kq); gr->AddActive(kq+n-1,1); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_line_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, const char *pen,int *n,int l) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; mgl_line(_GR_, *x1,*y1,*z1, *x2,*y2,*z2,s,*n); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_curve(HMGL gr, double x1, double y1, double z1, double dx1, double dy1, double dz1, double x2, double y2, double z2, double dx2, double dy2, double dz2, const char *pen,int n) { static int cgid=1; gr->StartGroup("Curve",cgid++); if(mgl_isnan(z1) || mgl_isnan(z2)) z1=z2=2*gr->Max.z-gr->Min.z; const mglPoint p1(x1,y1,z1), p2(x2,y2,z2),nn(NAN); const mglPoint d1(3*dx1,3*dy1,3*dz1), d2(3*dx2,3*dy2,3*dz2); // NOTE use d->3*d to be exact as Bezier curve const mglPoint a(3*(p2-p1)-d2-2*d1),b(d1+d2-2*(p2-p1)); n = (n<2) ? 2 : n; gr->SetPenPal(pen); const long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;iAddPntQ(kq+i,p1+s*d1+(s*s)*a+(s*s*s)*b,gr->CDef,nn,-1,3); } gr->curve_plot(n,kq); gr->arrow_plot(kq,kq+1,gr->Arrow1); gr->arrow_plot(kq+n-1,kq+n-2,gr->Arrow2); gr->AddActive(kq); gr->AddActive(kq+n-1,1); gr->AddActive(gr->AddPnt(p1+d1/3,gr->CDef,nn,-1,3),1); gr->AddActive(gr->AddPnt(p2-d2/3,gr->CDef,nn,-1,3),3); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_curve_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *dx1, mreal *dy1, mreal *dz1, mreal *x2, mreal *y2, mreal *z2, mreal *dx2, mreal *dy2, mreal *dz2, const char *pen,int *n, int l) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; mgl_curve(_GR_, *x1,*y1,*z1, *dx1,*dy1,*dz1, *x2,*y2,*z2, *dx2,*dy2,*dz2, s, *n); delete []s;} //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_box(HMGL gr, double x, double y, double z, double ex, double ey, double ez, const char *pen) { static int cgid=1; gr->StartGroup("ErBox",cgid++); char mk=gr->SetPenPal(pen); mglPoint p(x,y,z), q,nn(NAN); gr->Reserve(7); long k1,k2; q = p; q.x += ex; k1 = gr->AddPnt(q,gr->CDef,nn,0,3); q = p; q.x -= ex; k2 = gr->AddPnt(q,gr->CDef,nn,0,3); gr->line_plot(k1,k2); gr->arrow_plot(k1,k2,'I'); gr->arrow_plot(k2,k1,'I'); q = p; q.y += ey; k1 = gr->AddPnt(q,gr->CDef,nn,0,3); q = p; q.y -= ey; k2 = gr->AddPnt(q,gr->CDef,nn,0,3); gr->line_plot(k1,k2); gr->arrow_plot(k1,k2,'I'); gr->arrow_plot(k2,k1,'I'); q = p; q.z += ez; k1 = gr->AddPnt(q,gr->CDef,nn,0,3); q = p; q.z -= ez; k2 = gr->AddPnt(q,gr->CDef,nn,0,3); gr->line_plot(k1,k2); gr->arrow_plot(k1,k2,'I'); gr->arrow_plot(k2,k1,'I'); if(mk) gr->mark_plot(gr->AddPnt(p,gr->CDef,nn,0,3),mk); gr->AddActive(gr->AddPnt(p,gr->CDef,nn,-1,3),0); gr->AddActive(gr->AddPnt(p+mglPoint(ex,ey),gr->CDef,nn,-1,3),1); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_box_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, const char *pen,int l) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; mgl_error_box(_GR_, *x1,*y1,*z1, *x2,*y2,*z2,s); delete []s; } //----------------------------------------------------------------------------- // // Face series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_face(HMGL gr, double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, const char *stl) { static int cgid=1; gr->StartGroup("Face",cgid++); long pal; gr->SetPenPal(stl,&pal); // mreal c1,c2,c3,c4,zz=(gr->Min.z+gr->Max.z)/2; mreal c1,c2,c3,c4,zz=2*gr->Max.z-gr->Min.z; c1=c2=c3=c4=gr->CDef; if(mgl_isnan(z0)) z0 = zz; if(mgl_isnan(z1)) z1 = zz; if(mgl_isnan(z2)) z2 = zz; if(mgl_isnan(z3)) z3 = zz; mglPoint p1(x0,y0,z0), p2(x1,y1,z1), p3(x2,y2,z2), p4(x3,y3,z3); if(gr->GetNumPal(pal)>=4) { c2=gr->NextColor(pal,1); c3=gr->NextColor(pal,2); c4=gr->NextColor(pal,3); } mglPoint q1,q2,q3,q4; q1 = (p2-p1)^(p3-p1); q4 = (p2-p4)^(p3-p4); q2 = (p1-p2)^(p4-p2); q3 = (p1-p3)^(p4-p3); gr->Reserve(4); long k1,k2,k3,k4; double a = gr->get(MGL_ENABLE_ALPHA)?-1:1; k1 = gr->AddPnt(p1,c1,q1,a,11); gr->AddActive(k1,0); k2 = gr->AddPnt(p2,c2,q2,a,11); gr->AddActive(k2,1); k3 = gr->AddPnt(p3,c3,q3,a,11); gr->AddActive(k3,2); k4 = gr->AddPnt(p4,c4,q4,a,11); gr->AddActive(k4,3); gr->quad_plot(k1,k2,k3,k4); if(mglchr(stl,'#')) { gr->Reserve(4); pal = gr->AddTexture('k'); k1=gr->CopyNtoC(k1,pal); k2=gr->CopyNtoC(k2,pal); k3=gr->CopyNtoC(k3,pal); k4=gr->CopyNtoC(k4,pal); gr->line_plot(k1,k2); gr->line_plot(k1,k3); gr->line_plot(k3,k4); gr->line_plot(k2,k4); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_facex(HMGL gr, double x0, double y0, double z0, double wy, double wz, const char *stl, double d1, double d2) { mgl_face(gr, x0,y0,z0, x0,y0+wy,z0, x0,y0,z0+wz, x0,y0+wy+d1,z0+wz+d2, stl); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_facey(HMGL gr, double x0, double y0, double z0, double wx, double wz, const char *stl, double d1, double d2) { mgl_face(gr, x0,y0,z0, x0+wx,y0,z0, x0,y0,z0+wz, x0+wx+d1,y0,z0+wz+d2, stl); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_facez(HMGL gr, double x0, double y0, double z0, double wx, double wy, const char *stl, double d1, double d2) { mgl_face(gr, x0,y0,z0, x0,y0+wy,z0, x0+wx,y0,z0, x0+wx+d1,y0+wy+d2,z0, stl); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_facex_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *wy, mreal *wz, const char *stl, mreal *dx, mreal *dy, int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_facex(_GR_, *x0,*y0,*z0,*wy,*wz,s,*dx,*dy); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_facey_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *wx, mreal *wz, const char *stl, mreal *dx, mreal *dy, int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_facey(_GR_, *x0,*y0,*z0,*wx,*wz,s,*dx,*dy); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_facez_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *wx, mreal *wy, const char *stl, mreal *dx, mreal *dy, int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_facez(_GR_, *x0,*y0,*z0,*wx,*wy,s,*dx,*dy); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_face_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *x3, mreal *y3, mreal *z3, const char *stl, int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_face(_GR_, *x0,*y0,*z0, *x1,*y1,*z1, *x2,*y2,*z2, *x3,*y3,*z3, stl); delete []s; } //----------------------------------------------------------------------------- // // Cone // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cone(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r1, double r2, const char *stl) { if(r2<0) r2=r1; if(r1==0 && r2==0) return; static int cgid=1; gr->StartGroup("Cone",cgid++); mglPoint p1(x1,y1,z1), p2(x2,y2,z2), p,qn(NAN,NAN),t(NAN,NAN), d=p2-p1,a,b; a=!d; a.Normalize(); b=d^a; b.Normalize(); mreal c1,c2,dr=r2-r1; const char *s; if((s=strstr(stl,"{&"))!=0) c1 = c2 = atof(s+2); else { long ss=gr->AddTexture(stl); c1=gr->GetC(ss,p1.z); c2=gr->GetC(ss,p2.z); } long *kk=new long[164],k1=-1,k2=-1; bool edge = mglchr(stl,'@'); bool wire = mglchr(stl,'#'); gr->Reserve(edge?166:82); if(edge && !wire) { k1=gr->AddPnt(p1,c1,d,-1,3); k2=gr->AddPnt(p2,c2,d,-1,3); } long n=wire?6:18; //wire?6:18; if(mglchr(stl,'4')) n=2; else if(mglchr(stl,'6')) n=3; else if(mglchr(stl,'8')) n=4; bool refr = n>6; if(refr) t=d; const long nq = (edge && !wire)?4:2; const long kq = gr->AllocPnts(nq*(2*n+1)); int sq = wire?3:11; #pragma omp parallel for for(long i=0;i<2*n+1;i++) { int f = n!=4?(2*i+1)*90/n:45*i; double co = mgl_cos[f%360], si = mgl_cos[(f+270)%360]; mglPoint p = p1+(r1*co)*a+(r1*si)*b; mglPoint q = (si*a-co*b)^(d + (dr*co)*a + (dr*si)*b); long iq = kq+nq*i; gr->AddPntQ(iq,p,c1,refr?q:qn,-1,sq); mglPoint s = p2+(r2*co)*a+(r2*si)*b; gr->AddPntQ(iq+1,s,c2,refr?q:qn,-1,sq); if(edge && !wire) { gr->AddPntQ(iq+2,p,c1,t,-1,3); gr->AddPntQ(iq+3,s,c2,t,-1,3); } } if(wire) { gr->line_plot(kq,kq+1); for(long i=1;i<2*n+1;i++) { long iq = kq+nq*i; gr->line_plot(iq,iq-nq); gr->line_plot(iq+1,iq-nq+1); gr->line_plot(iq,iq+1); } } else for(long i=0;i<2*n;i++) { long iq = kq+nq*i; gr->quad_plot(iq,iq+nq,iq+1,iq+nq+1); if(edge) { gr->trig_plot(k1,iq+2,iq+2+nq); gr->trig_plot(k2,iq+3,iq+3+nq); } } gr->EndGroup(); delete []kk; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cone_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r1, mreal *r2, const char *stl, int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_cone(_GR_, *x1,*y1,*z1, *x2,*y2,*z2,*r1,*r2,s); delete []s; } //----------------------------------------------------------------------------- // // Cones series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cones_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { long m,n=z->GetNx(),nx=x->GetNx(), nz=z->GetNy(), pal; if(mgl_check_dim1(gr,x,z,y,0,"Cones",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Cones",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = nz > m ? nz : m; bool above= mglchr(pen,'a'); bool wire = mglchr(pen,'#'); bool tube = mglchr(pen,'t'); mreal *dd=new mreal[2*n], x1,z0,zz,d, vx,vy,vz,v0,v1,dv=nx>n?1:0; if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv = -1; gr->SetPenPal(pen,&pal); std::string cb="@"; if(wire) cb += '#'; if(mglchr(pen,'4')) cb+='4'; else if(mglchr(pen,'6')) cb+='6'; else if(mglchr(pen,'8')) cb+='8'; memset(dd,0,2*n*sizeof(mreal)); z0 = gr->GetOrgZ('x'); for(long i=0;iv(i, jNeedStop()) break; sprintf(buf,"{&%g}",gr->NextColor(pal)); std::string c1=cb+buf, c2=c1; if(gr->GetNumPal(pal)==2*m) { sprintf(buf,"{&%g}",gr->NextColor(pal)); c2 = cb+buf; } long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jv(i,mx); vy=y->v(i,my); vz=z->v(i,mz); v0=y->v(i,0); v1=iv(i+1,mx):x->v(i-1,mx); d = iBarWidth); d *= 0.7*gr->BarWidth; if(above) { zz = j>0?dd[i+n]:z0; dd[i+n] += vz; mgl_cone(gr, x1,v0,zz, x1,v0,dd[i+n], tube?d:d*(dd[i]-zz)/(dd[i]-z0), tube?d:d*(dd[i]-dd[i+n])/(dd[i]-z0), c1.c_str()); } else mgl_cone(gr, x1,vy,z0, x1,vy,vz, d,tube?d:0, vz<0?c1.c_str():c2.c_str()); } } gr->EndGroup(); delete []dd; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cones_xz(HMGL gr, HCDT x, HCDT z, const char *pen, const char *opt) { gr->SaveState(opt); mglData y(z); y.Fill(gr->Min.y,gr->Max.y,'y'); mgl_cones_xyz(gr,x,&y,z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cones(HMGL gr, HCDT z, const char *pen, const char *opt) { gr->SaveState(opt); mglData x(z->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x); mgl_cones_xz(gr,&x,z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cones_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cones_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cones_xz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cones_xz(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cones_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cones(_GR_,_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Polygon & Arc // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_polygon(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, int n, const char *stl) { if(n<3) return; long pal=0, n0; static int cgid=1; gr->StartGroup("Polygon",cgid++); gr->SetPenPal(stl,&pal); mreal c=gr->NextColor(pal); mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); bool fill = !mglchr(stl,'#'), box = mglchr(stl,'@') || !fill; if(!fill) k=c; gr->Reserve(box?2*n+3:n+2); if(mgl_isnan(z1) || mgl_isnan(z2)) z1=z2=2*gr->Max.z-gr->Min.z; mglPoint p1(x1,y1,z1), p2(x2,y2,z2), d=p2-p1, u=!d, p,qq; n0 = gr->AddPnt(p1,c,qq,-1,11); u = (d.norm()/u.norm())*u; long kq=-5; if(fill) { kq=gr->AllocPnts(n+1); #pragma omp parallel for for(long i=0;i<=n;i++) { mglPoint p = p1+d*cos(2*M_PI*i/n)+u*sin(2*M_PI*i/n); gr->AddPntQ(kq+i,p,c,qq,-1,11); } for(long i=0;itrig_plot(n0,kq+i,kq+i+1); } if(box) { kq=gr->AllocPnts(n+1); #pragma omp parallel for for(long i=0;i<=n;i++) { mglPoint p = p1+d*cos(2*M_PI*i/n)+u*sin(2*M_PI*i/n); gr->AddPntQ(kq+i,p,k,qq,-1,11); } for(long i=0;iline_plot(kq+i,kq+i+1); } gr->AddActive(n0,0); gr->AddActive(kq,1); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_arc_ext(HMGL gr, double x0, double y0, double z0, double xr, double yr, double zr, double x1, double y1, double z1, double a, const char* stl) { long pal=0, n = long(fabs(a)/3+1.5); a *= M_PI/180; static int cgid=1; gr->StartGroup("Arc",cgid++); gr->SetPenPal(stl,&pal); mreal c=gr->NextColor(pal); gr->Reserve(n+2); if(mgl_isnan(z0) || mgl_isnan(z1)) z0=z1=2*gr->Max.z-gr->Min.z; mglPoint p0(x0,y0,z0), p1(x1,y1,z1), d=p1-p0, u(mglPoint(xr,yr,zr)^d), qq(NAN); if(u.norm()==0) return; // wrong vector orientation u = (d.norm()/u.norm())*u; gr->AddActive(gr->AddPnt(p0,gr->CDef,qq,-1,3),0); const long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;iAddPntQ(kq+i,p0+d*cos(s)+u*sin(s),c,qq,-1,11); } gr->curve_plot(n,kq); gr->arrow_plot(kq,kq+1,gr->Arrow1); gr->arrow_plot(kq+n-1,kq+n-2,gr->Arrow2); gr->AddActive(kq); gr->AddActive(kq+n-1,1); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_arc(HMGL gr, double x0, double y0, double x1, double y1, double a, const char* stl) { mgl_arc_ext(gr,x0,y0,NAN,0,0,1,x1,y1,NAN,a,stl); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_polygon_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, int *n, const char *stl,int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_polygon(_GR_,*x1,*y1,*z1,*x2,*y2,*z2,*n,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_arc_ext_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl,int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_arc_ext(_GR_,*x0,*y0,*z0,*x1,*y1,*z1,*x2,*y2,*z2,*r,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_arc_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *x1, mreal *y1, mreal *a, const char *stl,int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_arc(_GR_,*x0,*y0,*x1,*y1,*a,s); delete []s; } //----------------------------------------------------------------------------- // // Ellipse & Rhomb // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ellipse(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl) { const int n = 41; long pal=0,n0; static int cgid=1; gr->StartGroup("Ellipse",cgid++); gr->SetPenPal(stl,&pal); mreal c=gr->NextColor(pal), d; mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); bool fill = !mglchr(stl,'#'), box = mglchr(stl,'@') || !fill; if(!fill) k=c; gr->Reserve(2*n+1); if(mgl_isnan(z1) || mgl_isnan(z2)) z1=z2=2*gr->Max.z-gr->Min.z; mglPoint p1(x1,y1,z1), p2(x2,y2,z2), v=p2-p1; d = v.norm(); if(d==0) v.Set(1); else v /= d; mglPoint u(mglPoint(0,0,1)^v), q(u^v), p, s=(p1+p2)/2.; u *= r; v *= sqrt(d*d/4+r*r); // central point first n0 = gr->AddPnt(p1,c,q,-1,11); gr->AddActive(n0); gr->AddActive(gr->AddPnt(p2,c,q,-1,11),1); long iq=-5; if(fill) { const long kq = gr->AllocPnts(n); iq = kq+n/4; #pragma omp parallel for for(long i=0;iAddPntQ(kq+i,p,c,q,-1,11); } for(long i=1;itrig_plot(n0,kq+i-1,kq+i); } if(box) { const long kq = gr->AllocPnts(n); iq = kq+n/4; #pragma omp parallel for for(long i=0;iAddPntQ(kq+i,p,k,q,-1,11); } for(long i=1;iline_plot(kq+i-1,kq+i); } gr->AddActive(iq,2); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_rhomb(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl) { long pal=0; static int cgid=1; gr->StartGroup("Rhomb",cgid++); gr->SetPenPal(stl,&pal); mreal c=gr->NextColor(pal); mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); mreal b=(gr->GetNumPal(pal)>2)?gr->NextColor(pal):c; bool fill = !mglchr(stl,'#'), box = mglchr(stl,'@') || !fill; if(!fill) k=c; gr->Reserve(8); if(mgl_isnan(z1) || mgl_isnan(z2)) z1=z2=2*gr->Max.z-gr->Min.z; mglPoint p1(x1,y1,z1), p2(x2,y2,z2), u=!(p1-p2), p, s,qq; u = (r/u.norm())*u; s = (p1+p2)/2.; long kq=-5; if(fill) { kq = gr->AllocPnts(4); gr->AddPntQ(kq,p1,c,qq,-1,11); gr->AddPntQ(kq+1,s+u,b==c?c:k,qq,-1,11); gr->AddPntQ(kq+2,p2,b,qq,-1,11); gr->AddPntQ(kq+3,s-u,b==c?c:k,qq,-1,11); gr->quad_plot(kq,kq+1,kq+3,kq+2); } if(box) { kq = gr->AllocPnts(4); gr->AddPntQ(kq,p1,k,qq,-1,11); gr->AddPntQ(kq+1,s+u,k,qq,-1,11); gr->AddPntQ(kq+2,p2,k,qq,-1,11); gr->AddPntQ(kq+3,s-u,k,qq,-1,11); gr->line_plot(kq,kq+1); gr->line_plot(kq+1,kq+2); gr->line_plot(kq+3,kq); gr->line_plot(kq+3,kq+2); } gr->AddActive(kq,0); gr->AddActive(kq+1,2); gr->AddActive(kq+2,1); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ellipse_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl,int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_ellipse(_GR_,*x1,*y1,*z1,*x2,*y2,*z2,*r,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_rhomb_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl,int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_rhomb(_GR_,*x1,*y1,*z1,*x2,*y2,*z2,*r,s); delete []s; } //----------------------------------------------------------------------------- // // Sphere & Drop // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_sphere(HMGL gr, double x, double y, double z, double r, const char *stl) { mgl_drop(gr,x,y,z,1,0,0,2*r,stl,0,1); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_sphere_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, mreal *r, const char *stl,int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_sphere(_GR_, *x,*y,*z,*r,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_drop(HMGL gr, mglPoint p, mglPoint q, double r, double c, double sh, double a) { mglPoint p1,p2; if(q.norm()==0) { q.Set(1,0,0); sh=0; } q.Normalize(); p1 = !q; p2 = q^p1; r /= 2; static int cgid=1; gr->StartGroup("Drop",cgid++); const int m=12, n=2*m+1; // long n1 = gr->AddPnt(p + q*r*(1+sh)*(1+sh),c,q,-1,3); // long n2 = gr->AddPnt(p + q*r*(1+sh)*(sh-1),c,q,-1,3); const long kq = gr->AllocPnts((m+1)*n); #pragma omp parallel for for(long i=0;i<=m;i++) for(long j=0;jAddPntQ(kq+j+n*i,pp,c,qq,-1,11); } for(long i=0;i not for omp { long iq = kq+j+n*i; gr->quad_plot(iq-1,iq, iq+n-1,iq+n); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_drop(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl, double sh, double a) { mreal c=gr->AddTexture((stl && stl[0]) ? stl[0]:'r'); mgl_drop(gr,mglPoint(x1,y1,z1), mglPoint(x2,y2,z2), r, c, sh, a); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_drop_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl, mreal *shift, mreal *ap, int l) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; mgl_drop(_GR_, *x1,*y1,*z1, *x2,*y2,*z2, *r,s,*shift,*ap); delete []s; } //----------------------------------------------------------------------------- // // Dew series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dew_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt) { long n=ax->GetNx(),m=ax->GetNy(); if(mgl_check_dim2(gr,x,y,ax,ay,"Dew")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("DewXY",cgid++); long ss = gr->AddTexture(sch); bool inv = mglchr(sch,'i'); mreal zVal = gr->Min.z, xm=0; long tx=1,ty=1; if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); } if(tx<1) tx=1; if(ty<1) ty=1; for(long k=0;kGetNz();k++) for(long j=0;jv(i,j,k)*ax->v(i,j,k)+ay->v(i,j,k)*ay->v(i,j,k)); xm = xm>ym ? xm : ym; } xm = 1./MGL_FEPSILON/(xm==0 ? 1:xm); for(long k=0;kGetNz();k++) { if(ax->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1); for(long i=0;iNeedStop()) { gr->EndGroup(); return; } mreal xx=GetX(x,i,j,k).x, yy=GetY(y,i,j,k).x, dd; mreal dx = iv(i,j,k),ay->v(i,j,k)); dd = q.norm(); if(inv) q = -q; mgl_drop(gr,mglPoint(xx, yy, zVal),q,(dxGetC(ss,dd*xm,false),dd*xm,1); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dew_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt) { gr->SaveState(opt); mglData x(ax->GetNx()), y(ax->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_dew_xy(gr,&x,&y,ax,ay,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dew_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dew_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dew_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dew_2d(_GR_, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Symbol series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_symbol(HMGL gr, double x, double y, double z, char id, const char *how, double size) { mgl_symbol_dir(gr, x, y, z, NAN, NAN, 0, id, how, size); } void MGL_EXPORT mgl_symbol_dir(HMGL gr, double x, double y, double z, double dx, double dy, double dz, char id, const char *how, double size) { bool a=mglchr(how,'a'), A=mglchr(how,'A'); // static int cgid=1; gr->StartGroup("Puts",cgid++); mglCanvas *g = dynamic_cast(gr); if(g && (a||A)) { g->Push(); g->Identity(a); gr->set(MGL_DISABLE_SCALE); mreal s=a?1:g->GetPlotFactor(); x = (2*x-1)*s; y = (2*y-1)*s; dx= (2*dx-1)*s; dy= (2*dy-1)*s; } if(mgl_isnan(z)) z=2*gr->Max.z-gr->Min.z; mglPoint p(x,y,z), d(dx-x,dy-y,dz-z); long cc = mgl_get_num_color(how,0)?gr->AddTexture(how):gr->AddTexture('k'); long k = gr->AddPnt(p,cc,d,-1,7); gr->AddActive(k,0); gr->AddActive(gr->AddPnt(mglPoint(dx,dy,dz),cc,d,-1,7),1); if(g && (a||A)) { g->Pop(); gr->clr(MGL_DISABLE_SCALE); } if(size<0) size *= -gr->GetFontSize(); int font=0; mglGetStyle(how, &font, NULL); if(font&MGL_FONT_WIRE) size = -size; gr->smbl_plot(k,id,size); // gr->EndGroup(); } void MGL_EXPORT mgl_symbol_(uintptr_t *gr, double *x, double *y, double *z, char *id, const char *how, double *size,int,int n) { char *f=new char[n+1]; memcpy(f,how,n); f[n]=0; mgl_symbol(_GR_, *x, *y, *z, *id, f, *size); delete []f; } void MGL_EXPORT mgl_symbol_dir_(uintptr_t *gr, double *x, double *y, double *z, double *dx, double *dy, double *dz, char *id, const char *how, double *size,int,int n) { char *f=new char[n+1]; memcpy(f,how,n); f[n]=0; mgl_symbol_dir(_GR_, *x, *y, *z, *dx, *dy, *dz, *id, f, *size); delete []f; } //----------------------------------------------------------------------------- // // Puts series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_puts(HMGL gr, double x, double y, double z,const char *text, const char *font, double size) { mgl_puts_dir(gr, x, y, z, NAN, NAN, 0, text, font, size); } void MGL_EXPORT mgl_putsw(HMGL gr, double x, double y, double z,const wchar_t *text, const char *font, double size) { mgl_putsw_dir(gr, x, y, z, NAN, NAN, 0, text, font, size); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_puts_dir(HMGL gr, double x, double y, double z, double dx, double dy, double dz, const char *text, const char *font, double size) { MGL_TO_WCS(text,mgl_putsw_dir(gr, x, y, z, dx, dy, dz, wcs, font, size)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_putsw_dir(HMGL gr, double x, double y, double z, double dx, double dy, double dz, const wchar_t *text, const char *font, double size) { bool a=mglchr(font,'a'), A=mglchr(font,'A'); static int cgid=1; gr->StartGroup("Puts",cgid++); mglCanvas *g = dynamic_cast(gr); if(g && (a||A)) { g->SaveInPlot(); g->Identity(a); gr->set(MGL_DISABLE_SCALE); mreal s=a?1:g->GetPlotFactor(); x = (2*x-1)*s; y = (2*y-1)*s; dx= (2*dx-1)*s; dy= (2*dy-1)*s; } if(mgl_isnan(z)) z=2*gr->Max.z-gr->Min.z; mglPoint p(x,y,z), d(dx-x,dy-y,dz-z); long k = gr->AddPnt(p,-1,d,-1,7); gr->AddActive(k,0); gr->AddActive(gr->AddPnt(mglPoint(dx,dy,dz),-1,d,-1,7),1); gr->text_plot(k,text,font,size); if(g && (a||A)) { g->LoadInPlot(); gr->clr(MGL_DISABLE_SCALE); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_puts_(uintptr_t *gr, mreal *x, mreal *y, mreal *z,const char *text, const char *font, mreal *size, int l, int n) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,font,n); f[n]=0; mgl_putsw_dir(_GR_, *x, *y, *z, NAN, NAN, 0, s, f, *size); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_puts_dir_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, mreal *dx, mreal *dy, mreal *dz, const char *text, const char *font, mreal *size, int l, int n) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,font,n); f[n]=0; mgl_putsw_dir(_GR_, *x, *y, *z, *dx, *dy, *dz, s, f, *size); delete []s; delete []f; } //----------------------------------------------------------------------------- // // TextMark series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmarkw_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const wchar_t *text, const char *fnt, const char *opt) { long m,n=y->GetNx(); if(mgl_check_dim0(gr,x,y,z,r,"TextMark")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TextMark",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; m = r->GetNy() > m ? r->GetNy() : m; gr->Reserve(n*m); mglPoint q(NAN); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1; for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; long mz = jGetNy() ? j:0, mr = jGetNy() ? j:0; for(long i=0;iAddPnt(mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz)),-1,q); gr->text_plot(k, text, fnt, -0.5*fabs(r->v(i,mr))); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmarkw_xyr(HMGL gr, HCDT x, HCDT y, HCDT r, const wchar_t *text, const char *fnt, const char *opt) { gr->SaveState(opt); mglData z(y->GetNx()); z.Fill(gr->Min.z,gr->Min.z); mgl_textmarkw_xyzr(gr,x,y,&z,r,text,fnt,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmarkw_yr(HMGL gr, HCDT y, HCDT r, const wchar_t *text, const char *fnt, const char *opt) { long n=y->GetNx(); gr->SaveState(opt); mglData x(n); x.Fill(gr->Min.x,gr->Max.x); mglData z(n); z.Fill(gr->Min.z,gr->Min.z); mgl_textmarkw_xyzr(gr,&x,y,&z,r,text,fnt,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmarkw(HMGL gr, HCDT y, const wchar_t *text, const char *fnt, const char *opt) { long n=y->GetNx(); gr->SaveState(opt); mglData r(n); r.Fill(1,1); mglData x(n); x.Fill(gr->Min.x,gr->Max.x); mglData z(n); z.Fill(gr->Min.z,gr->Min.z); mgl_textmarkw_xyzr(gr,&x,y,&z,&r,text,fnt,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_textmarkw_xyzr(gr, x, y, z, r, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_xyr(HMGL gr, HCDT x, HCDT y, HCDT r, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_textmarkw_xyr(gr, x, y, r, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_yr(HMGL gr, HCDT y, HCDT r, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_textmarkw_yr(gr, y, r, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark(HMGL gr, HCDT y, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_textmarkw(gr, y, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_xyzr_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; memcpy(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_textmarkw_xyzr(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(r),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_xyr_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_textmarkw_xyr(_GR_, _DA_(x),_DA_(y),_DA_(r),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_yr_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_textmarkw_yr(_GR_, _DA_(y),_DA_(r),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textmark_(uintptr_t *gr, uintptr_t *y, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_textmarkw(_GR_, _DA_(y),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- // // Label series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_labelw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const wchar_t *text, const char *fnt, const char *opt) { long m,n=y->GetNx(); if(mgl_check_dim0(gr,x,y,z,0,"Label")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Label",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; mglPoint q(NAN); char fmt[8]="2",ss[2]=" "; std::string Tstl; for(const char *s="0123456789";*s;s++) if(mglchr(fnt,*s)) fmt[0] = *s; for(const char *s="f+E-F";*s;s++) if(mglchr(fnt,*s)) { ss[0] = *s; strcat(fmt,ss); } for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; for(long i=0;iv(i,mx), yy=y->v(i,my), zz=z->v(i,mz); long kk = gr->AddPnt(mglPoint(xx,yy,zz),-1,q),k,l; std::wstring buf; for(k=l=0;text[k];k++) { if(text[k]!='%' || (k>0 && text[k-1]=='\\')) { buf += text[k]; continue; } else if(text[k+1]=='%') buf+=L"%"; else if(text[k+1]=='n') { wchar_t tmp[32]; mglprintf(tmp,32,L"%ld",i); buf += tmp; } else if(text[k+1]=='x') buf += mgl_ftoa(xx,fmt); else if(text[k+1]=='y') buf += mgl_ftoa(yy,fmt); else if(text[k+1]=='z') buf += mgl_ftoa(zz,fmt); else { buf+=L"%"; continue; } k++; } gr->text_plot(kk, buf.c_str(), fnt, -0.7, 0.05); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_labelw_xy(HMGL gr, HCDT x, HCDT y, const wchar_t *text, const char *fnt, const char *opt) { gr->SaveState(opt); mglData z(y->GetNx()); z.Fill(gr->Min.z,gr->Min.z); mgl_labelw_xyz(gr,x,y,&z,text,fnt,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_labelw_y(HMGL gr, HCDT y, const wchar_t *text, const char *fnt, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"TextMark"); return; } gr->SaveState(opt); mglData x(n); x.Fill(gr->Min.x,gr->Max.x); mglData z(n); z.Fill(gr->Min.z,gr->Min.z); mgl_labelw_xyz(gr,&x,y,&z,text,fnt,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_label_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_labelw_xyz(gr, x, y, z, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_label_xy(HMGL gr, HCDT x, HCDT y, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_labelw_xy(gr, x, y, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_label_y(HMGL gr, HCDT y, const char *str, const char *fnt, const char *opt) { MGL_TO_WCS(str,mgl_labelw_y(gr, y, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_label_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_labelw_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_label_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_labelw_xy(_GR_, _DA_(x),_DA_(y),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_label_y_(uintptr_t *gr, uintptr_t *y, const char *text, const char *fnt, const char *opt, int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_labelw_y(_GR_, _DA_(y),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- // // Table series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tablew(HMGL gr, double x, double y, HCDT val, const wchar_t *text, const char *fnt, const char *opt) { mglCanvas *g = dynamic_cast(gr); if(g) g->Table(x,y,val,text,fnt,opt); } void MGL_EXPORT mgl_table(HMGL gr, double x, double y, HCDT val, const char *text, const char *fnt, const char *opt) { if(!text) mgl_tablew(gr,x,y,val,L"",fnt,opt); else MGL_TO_WCS(text,mgl_tablew(gr, x, y, val, wcs, fnt, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_table_(uintptr_t *gr, mreal *x, mreal *y, uintptr_t *val, const char *text, const char *fnt, const char *opt,int l,int n,int lo) { wchar_t *s=new wchar_t[l+1]; mbstowcs(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,fnt,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tablew(_GR_, *x, *y, _DA_(val),s,f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- // // Logo series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_logo(HMGL gr, long w, long h, const unsigned char *rgba, int smooth, const char *opt) { if(w<1 || h<1 || !rgba) { gr->SetWarn(mglWarnLow,"Logo"); return; } static int cgid=1; gr->StartGroup("Logo",cgid++); mreal z = gr->SaveState(opt); if(mgl_isnan(z)) z = gr->Min.z; mreal x1 = gr->Min.x, y1 = gr->Min.y, dx, dy; if(!smooth || w==1 || h==1) { dx = (gr->Max.x-x1)/(w==1?1:(w-1)); dy = (gr->Max.y-y1)/(h==1?1:(h-1)); gr->Reserve(4*(w+1)*(h+1)); const long kq = gr->AllocPnts(4*w*h); #pragma omp parallel for for(long j=0;jAddPntQ(iq,mglPoint(x1+dx*i,y1+dy*j,z),0); gr->SetRGBA(iq,c); gr->AddPntQ(iq+1,mglPoint(x1+dx*(i+1),y1+dy*j,z),0); gr->SetRGBA(iq+1,c); gr->AddPntQ(iq+2,mglPoint(x1+dx*i,y1+dy*(j+1),z),0); gr->SetRGBA(iq+2,c); gr->AddPntQ(iq+3,mglPoint(x1+dx*(i+1),y1+dy*(j+1),z),0);gr->SetRGBA(iq+3,c); } for(long j=0;jquad_plot(iq,iq+1,iq+2,iq+3); } } else { dx = (gr->Max.x-x1)/(w-1); dy = (gr->Max.y-y1)/(h-1); const long kq = gr->AllocPnts(w*h); #pragma omp parallel for for(long j=0;jAddPntQ(iq,mglPoint(x1+dx*i,y1+dy*j,z),0); gr->SetRGBA(iq,mglColor(rgba[i0]/255.,rgba[i0+1]/255.,rgba[i0+2]/255.)); } for(long j=0;jquad_plot(iq,iq+1,iq+w,iq+w+1); } } gr->EndGroup(); } //----------------------------------------------------------------------------- bool MGL_NO_EXPORT mgl_read_image(unsigned char **g, int &w, int &h, const char *fname); void MGL_EXPORT mgl_logo_file(HMGL gr, const char *fname, int smooth, const char *opt) { unsigned char *g = 0; int w=0, h=0; if(!mgl_read_image(&g,w,h,fname)) return; mgl_logo(gr,w,h,g,smooth,opt); delete []g; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_logo_file_(uintptr_t *gr, const char *fname, int *smooth, const char *opt,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,opt,n); f[n]=0; mgl_logo_file(_GR_,s,*smooth,f); delete []s; delete []f; } //----------------------------------------------------------------------------- // // Lamerey series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_lamerey(HMGL gr, double x0, double (*f)(double,void *), void *par, const char *stl, const char *opt) { static int cgid=1; gr->StartGroup("Lamerey",cgid++); mreal r=gr->SaveState(opt); double x=x0, dx = 1e-5*fabs(gr->Max.x-gr->Min.x); long n = r>2 ? long(r+0.5):20, n1, n2; gr->SetPenPal(stl); gr->Reserve(6*n+1); bool vect = mglchr(stl,'v'); n2 = gr->AddPnt(mglPoint(x,x,gr->Max.z)); if(!mglchr(stl,'~')) { n1 = gr->AddPnt(mglPoint(x,gr->GetOrgY('x'),gr->Max.z)); gr->line_plot(n1,n2); if(vect) gr->vect_plot(n1,n2,0.3*gr->GetArrowSize()); } for(long i=0;iAddPnt(mglPoint(x0,x,gr->Max.z)); gr->line_plot(n1,n2); if(vect) gr->vect_plot(n1,n2,0.3*gr->GetArrowSize()); n1=n2; n2 = gr->AddPnt(mglPoint(x,x,gr->Max.z)); gr->line_plot(n1,n2); if(vect) gr->vect_plot(n1,n2,0.3*gr->GetArrowSize()); } gr->EndGroup(); } //----------------------------------------------------------------------------- struct mglDatSpl { HCDT d; double x0,dx; double y0,dy; }; double static func_dat(double x, void *p) { mglDatSpl *s = (mglDatSpl *)p; return s->d->value((x-s->x0)*s->dx); } void MGL_EXPORT mgl_lamerey_dat(HMGL gr, double x0, HCDT f, const char *stl, const char *opt) { mreal r = gr->SaveState(opt); char buf[64]=""; if(r>2) sprintf(buf,"value %g",r); mglDatSpl s; s.d=f; s.x0=gr->Min.x; s.dx=f->GetNx()/(gr->Max.x-gr->Min.x); mgl_lamerey(gr,x0,func_dat,&s,stl,buf); } //----------------------------------------------------------------------------- double static func_str(double x, void *p) { HMEX s = (HMEX)p; return mgl_expr_eval(s,x,0,0); } void MGL_EXPORT mgl_lamerey_str(HMGL gr, double x0, const char *f, const char *stl, const char *opt) { HMEX eq = mgl_create_expr(f); mgl_lamerey(gr,x0,func_str,eq,stl,opt); mgl_delete_expr(eq); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_lamerey_dat_(uintptr_t *gr, double *x0, uintptr_t *f, const char *stl, const char *opt, int l,int n) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; char *o=new char[n+1]; memcpy(o,opt,n); o[n]=0; mgl_lamerey_dat(_GR_,*x0,_DA_(f),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_lamerey_str_(uintptr_t *gr, double *x0, const char *func, const char *stl, const char *opt, int m,int l,int n) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; char *o=new char[n+1]; memcpy(o,opt,n); o[n]=0; char *f=new char[m+1]; memcpy(f,func,m); f[m]=0; mgl_lamerey_str(_GR_,*x0,f,s,o); delete []f; delete []s; delete []o; } //----------------------------------------------------------------------------- // // Bifurcation series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bifurcation(HMGL gr, double dx, double (*f)(double,double,void *), void *par, const char *stl, const char *opt) { if((gr->Max.x-gr->Min.x)*dx<=0) { gr->SetWarn(mglWarnSlc,"Bifurcation"); return; } static int cgid=1; gr->StartGroup("Bifurcation",cgid++); mreal res=gr->SaveState(opt); long n = res>2 ? long(res+0.5):1024, m=(gr->Max.x-gr->Min.x)/dx, m1=0,m2=0; gr->SetPenPal(stl); gr->Reserve(2*n*m); double *v1=new double[n], *v2=new double[n], dd=0.1*fabs(gr->Max.y-gr->Min.y)/n; double r = gr->Min.y+mgl_rnd()*(gr->Max.y-gr->Min.y), r0 = r; bool fin=false; for(long i=0;i<10*n;i++) r = f(gr->Min.x,r,par); // wait for loop stabilization for(m1=0;m1Min.x,r,par); for(long j=0;jMin.x+dx;xx<=gr->Max.x;xx+=dx) { m2=m1; memcpy(v2,v1,n*sizeof(double)); r=r0; for(long i=0;i<10*n;i++) r = f(xx,r,par); // wait for loop stabilization for(fin=false,m1=0;m1=m2) for(long i=0;iline_plot(gr->AddPnt(mglPoint(xx-dx,vv,gr->Max.z)), gr->AddPnt(mglPoint(xx,v1[i],gr->Max.z))); } else for(long i=0;iline_plot(gr->AddPnt(mglPoint(xx-dx,v1[i],gr->Max.z)), gr->AddPnt(mglPoint(xx,v1[i],gr->Max.z))); } gr->EndGroup(); delete []v1; delete []v2; } //----------------------------------------------------------------------------- double static bif_dat(double x, double y, void *p) { mglDatSpl *s = (mglDatSpl *)p; return s->d->value((x-s->x0)*s->dx, (y-s->y0)*s->dy); } void MGL_EXPORT mgl_bifurcation_dat(HMGL gr, double dx, HCDT f, const char *stl, const char *opt) { if(dx==0 || (gr->Max.x-gr->Min.x)*dx<0) { gr->SetWarn(mglWarnSlc,"Bifurcation"); return; } if(f->GetNy()<2) { gr->SetWarn(mglWarnLow,"Bifurcation"); return; } mreal r = gr->SaveState(opt); char buf[64]=""; if(r>2) sprintf(buf,"value %g",r); mglDatSpl s; s.d=f; s.x0=gr->Min.x; s.dx=f->GetNx()/(gr->Max.x-gr->Min.x); s.y0=gr->Min.y; s.dy=f->GetNy()/(gr->Max.y-gr->Min.y); mgl_bifurcation(gr,dx,bif_dat,&s,stl,buf); } //----------------------------------------------------------------------------- double static bif_str(double x, double y, void *p) { HMEX s = (HMEX)p; return mgl_expr_eval(s,x,y,0); } void MGL_EXPORT mgl_bifurcation_str(HMGL gr, double dx, const char *f, const char *stl, const char *opt) { HMEX eq = mgl_create_expr(f); mgl_bifurcation(gr,dx,bif_str,eq,stl,opt); mgl_delete_expr(eq); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bifurcation_dat_(uintptr_t *gr, double *dx, uintptr_t *f, const char *stl, const char *opt, int l,int n) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; char *o=new char[n+1]; memcpy(o,opt,n); o[n]=0; mgl_bifurcation_dat(_GR_,*dx,_DA_(f),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bifurcation_str_(uintptr_t *gr, double *dx, const char *func, const char *stl, const char *opt, int m,int l,int n) { char *s=new char[l+1]; memcpy(s,stl,l); s[l]=0; char *o=new char[n+1]; memcpy(o,opt,n); o[n]=0; char *f=new char[m+1]; memcpy(f,func,m); f[m]=0; mgl_bifurcation_str(_GR_,*dx,f,s,o); delete []f; delete []s; delete []o; } //----------------------------------------------------------------------------- // // Iris series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_irisw(HMGL gr, HCDT dats, HCDT ranges, const wchar_t *ids, const char *stl, const char *opt) { long m=dats->GetNx(), nx=dats->GetNy(); // TODO parse several slices? if(m<2 || nx<2) { gr->SetWarn(mglWarnLow,"Iris"); return; } if(m!=ranges->GetNy()) { gr->SetWarn(mglWarnDim,"Iris"); return; } mglCanvas *g = dynamic_cast(gr); if(!g) return; mreal ofsize = gr->GetFontSize(); mreal res=gr->SaveState(opt), fsize = gr->GetFontSize(); if(mgl_isnan(res)) res=-1; res /= m; static int cgid=1; gr->StartGroup("Iris",cgid++); std::wstring *strs = new std::wstring[m]; bool label = ids && ids[0]; // disable axis drawing if(label) { const wchar_t *s, *p=ids; if(wcschr(ids,';')) for(long i=0;iInPlot(dx*i,dx*(i+1),dx*(m-j-1),dx*(m-j),true); if(label) g->Box(); gr->SetRanges(ranges->v(0,i),ranges->v(1,i),ranges->v(0,j),ranges->v(1,j)); gr->ResetPal(); gr->SetFontSize(fsize); if(i==j) { const char *tstl = wcschr(strs[i].c_str(),'\n') || wcsstr(strs[i].c_str(),L"\\n ") ? "a":"aV"; mgl_putsw(gr, dx*(i+0.5), dx*(m-j-0.5),0, strs[i].c_str(), tstl, res); } else mgl_plot_xy(gr,dat[i],dat[j],stl,NULL); } if(label) { for(long i=0;iSetRanges(ranges->v(0,i),ranges->v(1,i),ranges->v(0,m-i-1),ranges->v(1,m-i-1)); gr->SetFontSize(fsize); g->InPlot(dx*i,dx*(i+1),0,dx,true); g->Axis("x"); gr->SetFontSize(fsize); g->InPlot(0,dx,dx*i,dx*(i+1),true); g->Axis("y"); } for(long i=1;iSetRanges(ranges->v(0,i),ranges->v(1,i),ranges->v(0,m-i-1),ranges->v(1,m-i-1)); gr->SetFontSize(fsize); g->InPlot(dx*i,dx*(i+1),1-dx,1,true); g->Axis("x^"); gr->SetFontSize(fsize); g->InPlot(1-dx,1,dx*i,dx*(i+1),true); g->Axis("y^"); } } for(long i=0;iInPlot(0,1,0,1,true); gr->EndGroup(); gr->SetFontSize(ofsize); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_irisw_1(HMGL gr, HCDT dats, const wchar_t *ids, const char *stl, const char *opt) { long n=dats->GetNy()*dats->GetNz(), m=dats->GetNx(); mglData ranges(2,m); for(long i=0;ivthr(i+m*j); if(vv2) v2=v; } if(!mgl_isnum(v1)) { v1=-1; v2=1; } if(v1==v2) { v1-=1; v2+=1; } } mgl_irisw(gr,dats,&ranges,ids,stl,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_iris(HMGL gr, HCDT dats, HCDT ranges, const char *ids, const char *stl, const char *opt) { MGL_TO_WCS(ids,mgl_irisw(gr, dats, ranges, wcs, stl, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_iris_1(HMGL gr, HCDT dats, const char *ids, const char *stl, const char *opt) { MGL_TO_WCS(ids,mgl_irisw_1(gr, dats, wcs, stl, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_iris_(uintptr_t *gr, uintptr_t *dats, uintptr_t *ranges, const char *ids, const char *stl, const char *opt,int l,int m,int n) { char *i=new char[l+1]; memcpy(i,ids,l); i[l]=0; char *s=new char[m+1]; memcpy(s,stl,m); s[m]=0; char *o=new char[n+1]; memcpy(o,opt,n); o[n]=0; mgl_iris(_GR_,_DA_(dats),_DA_(ranges),i,s,o); delete []i; delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_iris_1_(uintptr_t *gr, uintptr_t *dats, const char *ids, const char *stl, const char *opt,int l,int m,int n) { char *i=new char[l+1]; memcpy(i,ids,l); i[l]=0; char *s=new char[m+1]; memcpy(s,stl,m); s[m]=0; char *o=new char[n+1]; memcpy(o,opt,n); o[n]=0; mgl_iris_1(_GR_,_DA_(dats),i,s,o); delete []i; delete []s; delete []o; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/c2mdual.c0000644000175000017500000000031713513030041015430 0ustar alastairalastair#include "mgl2/define.h" #if MGL_HAVE_C99_COMPLEX MGL_EXPORT dual mdual2c(cmdual c) { return c.re+1.0i*c.im; } MGL_EXPORT cmdual c2mdual(dual c) { cmdual r; r.re=creal(c); r.im=cimag(c); return r; } #endif mathgl-2.4.4/src/data_gr.cpp0000644000175000017500000002140713513030041016045 0ustar alastairalastair/*************************************************************************** * data_gr.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #ifndef WIN32 #include #endif #include "mgl2/datac.h" #include "mgl2/evalc.h" #include "mgl2/thread.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector &head); HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector &head); //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_refill_gr(HMGL gr, HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, long sl, const char *opt) { if(!vdat) return; gr->SaveState(opt); if(!ydat && !zdat) mgl_data_refill_x(dat,xdat,vdat,gr->Min.x,gr->Max.x,sl); // else if(!xdat && !zdat) mgl_data_refill_x(dat,ydat,vdat,gr->Min.y,gr->Max.y,sl); // else if(!xdat && !ydat) mgl_data_refill_x(dat,zdat,vdat,gr->Min.z,gr->Max.z,sl); else if(!zdat) mgl_data_refill_xy(dat,xdat,ydat,vdat,gr->Min.x,gr->Max.x,gr->Min.y,gr->Max.y,sl); // else if(!ydat) mgl_data_refill_xy(dat,xdat,zdat,vdat,gr->Min.x,gr->Max.x,gr->Min.z,gr->Max.z,sl); // else if(!xdat) mgl_data_refill_xy(dat,ydat,zdat,vdat,gr->Min.y,gr->Max.y,gr->Min.z,gr->Max.z,sl); else mgl_data_refill_xyz(dat,xdat,ydat,zdat,vdat,gr->Min.x,gr->Max.x,gr->Min.y,gr->Max.y,gr->Min.z,gr->Max.z); gr->LoadState(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_refill_gr(HMGL gr, HADT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, long sl, const char *opt) { if(!vdat) return; gr->SaveState(opt); if(!ydat && !zdat) mgl_datac_refill_x(dat,xdat,vdat,gr->Min.x,gr->Max.x,sl); // else if(!xdat && !zdat) mgl_datac_refill_x(dat,ydat,vdat,gr->Min.y,gr->Max.y,sl); // else if(!xdat && !ydat) mgl_datac_refill_x(dat,zdat,vdat,gr->Min.z,gr->Max.z,sl); else if(!zdat) mgl_datac_refill_xy(dat,xdat,ydat,vdat,gr->Min.x,gr->Max.x,gr->Min.y,gr->Max.y,sl); // else if(!ydat) mgl_datac_refill_xy(dat,xdat,zdat,vdat,gr->Min.x,gr->Max.x,gr->Min.z,gr->Max.z,sl); // else if(!xdat) mgl_datac_refill_xy(dat,ydat,zdat,vdat,gr->Min.y,gr->Max.y,gr->Min.z,gr->Max.z,sl); else mgl_datac_refill_xyz(dat,xdat,ydat,zdat,vdat,gr->Min.x,gr->Max.x,gr->Min.y,gr->Max.y,gr->Min.z,gr->Max.z); gr->LoadState(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_refill_x_(uintptr_t *d, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl) { mgl_data_refill_x(_DT_,_DA_(xdat),_DA_(vdat),*x1,*x2,*sl); } void MGL_EXPORT mgl_data_refill_xy_(uintptr_t *d, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, long *sl) { mgl_data_refill_xy(_DT_,_DA_(xdat),_DA_(ydat),_DA_(vdat),*x1,*x2,*y1,*y2,*sl); } void MGL_EXPORT mgl_data_refill_xyz_(uintptr_t *d, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2) { mgl_data_refill_xyz(_DT_,_DA_(xdat),_DA_(ydat),_DA_(zdat),_DA_(vdat),*x1,*x2,*y1,*y2,*z1,*z2); } void MGL_EXPORT mgl_data_refill_gr_(uintptr_t *gr, uintptr_t *d, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, long *sl, const char *opt,int l) { char *s=new char[l+1]; memcpy(s,opt,l); s[l]=0; mgl_data_refill_gr(_GR_,_DT_,_DA_(xdat),_DA_(ydat),_DA_(zdat),_DA_(vdat),*sl,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_refill_x_(uintptr_t *d, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl) { mgl_datac_refill_x(_DC_,_DA_(xdat),_DA_(vdat),*x1,*x2,*sl); } void MGL_EXPORT mgl_datac_refill_xy_(uintptr_t *d, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, long *sl) { mgl_datac_refill_xy(_DC_,_DA_(xdat),_DA_(ydat),_DA_(vdat),*x1,*x2,*y1,*y2,*sl); } void MGL_EXPORT mgl_datac_refill_xyz_(uintptr_t *d, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2) { mgl_datac_refill_xyz(_DC_,_DA_(xdat),_DA_(ydat),_DA_(zdat),_DA_(vdat),*x1,*x2,*y1,*y2,*z1,*z2); } void MGL_EXPORT mgl_datac_refill_gr_(uintptr_t *gr, uintptr_t *d, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, long *sl, const char *opt,int l) { char *s=new char[l+1]; memcpy(s,opt,l); s[l]=0; mgl_datac_refill_gr(_GR_,_DC_,_DA_(xdat),_DA_(ydat),_DA_(zdat),_DA_(vdat),*sl,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt) { if(vdat && vdat->GetNN()!=d->GetNN()) return; // incompatible dimensions if(wdat && wdat->GetNN()!=d->GetNN()) return; gr->SaveState(opt); std::wstring s = d->Name(); d->Name(L"u"); mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.Name(L"x"); mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.Name(L"y"); mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.Name(L"z"); mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i"); mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j"); mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k"); mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl"); mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w"); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&r); list.push_back(d); list.push_back(&v); list.push_back(&w); list.push_back(&i); list.push_back(&j); list.push_back(&k); d->Move(mglFormulaCalc(eq,list)); d->Name(s.c_str()); gr->LoadState(); } void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_data_fill_eq(_GR_,_DT_,s,_DA_(v),_DA_(w),o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_fill_eq(HMGL gr, HADT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt) { if(vdat && vdat->GetNN()!=d->GetNN()) return; // incompatible dimensions if(wdat && wdat->GetNN()!=d->GetNN()) return; gr->SaveState(opt); std::wstring s = d->Name(); d->Name(L"u"); mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.Name(L"x"); mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.Name(L"y"); mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.Name(L"z"); mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i"); mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j"); mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k"); mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl"); mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w"); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&r); list.push_back(d); list.push_back(&v); list.push_back(&w); list.push_back(&i); list.push_back(&j); list.push_back(&k); d->Move(mglFormulaCalcC(eq,list)); d->Name(s.c_str()); gr->LoadState(); } void MGL_EXPORT mgl_datac_fill_eq_(uintptr_t *gr, uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_datac_fill_eq(_GR_,_DC_,s,_DA_(v),_DA_(w),o); delete []o; delete []s; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/vect.cpp0000644000175000017500000021732213513030041015410 0ustar alastairalastair/*************************************************************************** * vect.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/prim.h" #include "mgl2/vect.h" #include "mgl2/eval.h" #include "mgl2/data.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- // // Traj series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { long n=ax->GetNx(),pal; if(mgl_check_dim1(gr,x,z,y,ax,"Traj")) return; if(mgl_check_dim1(gr,ax,az,ay,0,"Traj")) return; double len=gr->SaveState(opt); if(mgl_isnan(len)) len = 0; static int cgid=1; gr->StartGroup("Traj",cgid++); double fact = gr->size_opt<0 ? -gr->size_opt:1; // find maximum long m = x->GetNy()>y->GetNy() ? x->GetNy():y->GetNy(); long i = ax->GetNy()>ay->GetNy() ? ax->GetNy():ay->GetNy(); long j = z->GetNy()>az->GetNy() ? z->GetNy():az->GetNy(); if(i>m) m=i; if(j>m) m=j; double asize = gr->GetArrowSize(); gr->SetPenPal(sch,&pal); gr->Reserve(4*n*m); for(long j=0;jNeedStop()) break; gr->NextColor(pal); long nx = jGetNy() ? j:0, ny = jGetNy() ? j:0, nz = jGetNy() ? j:0; long mx = jGetNy() ? j:0,my = jGetNy() ? j:0,mz = jGetNy() ? j:0; const long kq = gr->AllocPnts(2*n); #pragma omp parallel for for(long i=0;iv(i,nx), y->v(i,ny), z->v(i,nz)); mglPoint p2(ax->v(i,mx),ay->v(i,my),az->v(i,mz)); double dd = p2.norm(); if(len==0) { double dx,dy,dz; if(iv(i+1,nx)-p1.x; dy=y->v(i+1,ny)-p1.y; dz=z->v(i+1,nz)-p1.z; } else { dx=p1.x-x->v(i-1,nx); dy=p1.y-y->v(i-1,ny); dz=p1.z-z->v(i-1,nz); } dd = dd ? sqrt(dx*dx+dy*dy+dz*dz)/dd : 0; } else dd = len; gr->AddPntQ(kq+2*i,p1); gr->AddPntQ(kq+2*i+1,p1+(fact*dd)*p2,-1,mglPoint(NAN),-1,2); } for(long i=0;ivect_plot(kq+2*i, kq+2*i+1, asize); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_traj_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV z(x->GetNx()), az(x->GetNx()); z.Fill(gr->AdjustZMin()); mgl_traj_xyz(gr,x,y,&z,ax,ay,&az,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_traj_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_traj_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_traj_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_traj_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Vect series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt) { long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(); if(mgl_check_dim2(gr,x,y,ax,ay,"Vect")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Vect",cgid++); bool dot = mglchr(sch,'.'); bool fix = mglchr(sch,'f'), end = mglchr(sch,'>'); bool beg = mglchr(sch,'<'), grd = mglchr(sch,'='); double fact = gr->size_opt<0 ? -gr->size_opt:1; gr->SetPenPal("-"); long ss = gr->AddTexture(sch); double zVal = gr->Min.z, asize = gr->GetArrowSize(); long tx=1,ty=1; if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); } if(tx<1) tx=1; if(ty<1) ty=1; double xm=0,cm=0,ca=0; double dm=(fabs(gr->Max.c)+fabs(gr->Min.c))*1e-5; // use whole array for determining maximal vectors length #pragma omp parallel { double xm1=0,cm1=0,xx,c1,c2; #pragma omp for nowait collapse(3) reduction(+:ca) for(long k=0;kv(i,j,k),ay->v(i,j,k)); c1 = v.norm(); xm1 = xm1NeedStop()) break; if(ax->GetNz()>1) zVal = gr->Min.z+k*(gr->Max.z-gr->Min.z)/(ax->GetNz()-1); const long ni = 1+((n-1)/tx), nj = 1+((m-1)/ty); const long kq = gr->AllocPnts(2*ni*nj); #pragma omp parallel for collapse(2) for(long j=0;jv(i*tx,j*ty,k),ay->v(i*tx,j*ty,k)); double dd = v.norm(), c1, c2; v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm); if(end) { p1 = d-v; p2 = d; } else if(beg){ p1 = d; p2 = d+v; } else { p1=d-v/2.; p2=d+v/2.; } if(grd) { c1=gr->GetC(ss,dd*xm-0.5,false); c2=gr->GetC(ss,dd*xm,false);} else c1 = c2 = gr->GetC(ss,dd*xm,false); long iq = kq+2*(i+ni*j); bool r1=gr->AddPntQ(iq,p1,c1); bool r2=gr->AddPntQ(iq+1,p2,c2); if(!r1 && r2) gr->AddPntQ(iq,p1,c1,mglPoint(NAN),-1,2); if(!r2 && r1) gr->AddPntQ(iq+1,p2,c2,mglPoint(NAN),-1,2); } if(dot) for(long i=0;iline_plot(iq,iq+1); gr->mark_plot(iq,'.'); } else for(long i=0;ivect_plot(iq,iq+1,asize); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_vect_xy(gr,&x,&y,ax,ay,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_vect_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_vect_2d(_GR_, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Vect3 series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(); if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect_3d")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Vect_3d",cgid++); bool dot = mglchr(sch,'.'), fix = mglchr(sch,'f'); bool end = mglchr(sch,'>'), beg = mglchr(sch,'<'); bool grd = mglchr(sch,'='); double fact = gr->size_opt<0 ? -gr->size_opt:1; gr->SetPenPal("-"); long ss = gr->AddTexture(sch); gr->Reserve(2*n*m*l); long tx=1,ty=1,tz=1; if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); tz=(l-1)/(gr->MeshNum-1);} if(tx<1) tx=1; if(ty<1) ty=1; if(tz<1) tz=1; double xm=0,cm=0,ca=0, asize = gr->GetArrowSize(); double dm=(fabs(gr->Max.c)+fabs(gr->Min.c))*1e-5; // use whole array for determining maximal vectors length #pragma omp parallel { double c1,c2,c3, xm1=0,cm1=0,xx; #pragma omp for nowait collapse(3) reduction(+:ca) for(long k=0;kv(i,j,k),ay->v(i,j,k),az->v(i,j,k)),p1; c1 = v.norm(); xm1 = xm1AllocPnts(2*ni*nj*nk); #pragma omp parallel for collapse(3) for(long k=0;kv(ii,ij,ik),ay->v(ii,ij,ik),az->v(ii,ij,ik)), p1, p2; double dd = v.norm(),c1,c2; v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm); if(end) { p1 = d-v; p2 = d; } else if(beg){ p1 = d; p2 = d+v; } else { p1=d-v/2.; p2=d+v/2.; } if(grd) { c1=gr->GetC(ss,dd*xm-0.5,false); c2=gr->GetC(ss,dd*xm,false); } else c1 = c2 = gr->GetC(ss,dd*xm,false); long iq = kq+2*(i+ni*(j+nj*k)); bool r1=gr->AddPntQ(iq,p1,c1); bool r2=gr->AddPntQ(iq+1,p2,c2); if(!r1 && r2) gr->AddPntQ(iq,p1,c1,mglPoint(NAN),-1,2); if(!r2 && r1) gr->AddPntQ(iq+1,p2,c2,mglPoint(NAN),-1,2); } if(dot) for(long i=0;iline_plot(iq,iq+1); gr->mark_plot(iq,'.'); } else for(long i=0;ivect_plot(iq,iq+1,asize); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_vect_xyz(gr,&x,&y,&z,ax,ay,az,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_vect_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_vect_3d(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Vect3 series // //----------------------------------------------------------------------------- struct _mgl_vec_slice { mglData x,y,z,ax,ay,az; }; //----------------------------------------------------------------------------- void static mgl_get_slice(_mgl_vec_slice &s, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, char dir, mreal d, bool both) { long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(), nx=1,ny=1,p; if(dir=='x') { nx = m; ny = l; if(d<0) d = n/2.; } if(dir=='y') { nx = n; ny = l; if(d<0) d = m/2.; } if(dir=='z') { nx = n; ny = m; if(d<0) d = l/2.; } s.x.Create(nx,ny); s.y.Create(nx,ny); s.z.Create(nx,ny); s.ax.Create(nx,ny); s.ay.Create(nx,ny); s.az.Create(nx,ny); p = long(d); d -= p; if(dir=='x' && p>=n-1) { d+=p-n+2; p=n-2; } if(dir=='y' && p>=m-1) { d+=p-m+2.; p=m-2; } if(dir=='z' && p>=l-1) { d+=p-l+2; p=l-2; } if(both) { if(dir=='x') #pragma omp parallel for collapse(2) for(long j=0;jv(p,i,j)*(1-d) + x->v(p+1,i,j)*d; s.y.a[i0] = y->v(p,i,j)*(1-d) + y->v(p+1,i,j)*d; s.z.a[i0] = z->v(p,i,j)*(1-d) + z->v(p+1,i,j)*d; s.ax.a[i0] = ax->v(p,i,j)*(1-d) + ax->v(p+1,i,j)*d; s.ay.a[i0] = ay->v(p,i,j)*(1-d) + ay->v(p+1,i,j)*d; s.az.a[i0] = az->v(p,i,j)*(1-d) + az->v(p+1,i,j)*d; } if(dir=='y') #pragma omp parallel for collapse(2) for(long j=0;jv(i,p,j)*(1-d) + x->v(i,p+1,j)*d; s.y.a[i0] = y->v(i,p,j)*(1-d) + y->v(i,p+1,j)*d; s.z.a[i0] = z->v(i,p,j)*(1-d) + z->v(i,p+1,j)*d; s.ax.a[i0] = ax->v(i,p,j)*(1-d) + ax->v(i,p+1,j)*d; s.ay.a[i0] = ay->v(i,p,j)*(1-d) + ay->v(i,p+1,j)*d; s.az.a[i0] = az->v(i,p,j)*(1-d) + az->v(i,p+1,j)*d; } if(dir=='z') #pragma omp parallel for collapse(2) for(long j=0;jv(i,j,p)*(1-d) + x->v(i,j,p+1)*d; s.y.a[i0] = y->v(i,j,p)*(1-d) + y->v(i,j,p+1)*d; s.z.a[i0] = z->v(i,j,p)*(1-d) + z->v(i,j,p+1)*d; s.ax.a[i0] = ax->v(i,j,p)*(1-d) + ax->v(i,j,p+1)*d; s.ay.a[i0] = ay->v(i,j,p)*(1-d) + ay->v(i,j,p+1)*d; s.az.a[i0] = az->v(i,j,p)*(1-d) + az->v(i,j,p+1)*d; } } else // x, y, z -- vectors { if(dir=='x') { mreal v = x->v(p)*(1-d)+x->v(p+1)*d; #pragma omp parallel for collapse(2) for(long j=0;jv(i); s.z.a[i0] = z->v(j); s.ax.a[i0] = ax->v(p,i,j)*(1-d) + ax->v(p+1,i,j)*d; s.ay.a[i0] = ay->v(p,i,j)*(1-d) + ay->v(p+1,i,j)*d; s.az.a[i0] = az->v(p,i,j)*(1-d) + az->v(p+1,i,j)*d; } } if(dir=='y') { mreal v = y->v(p)*(1-d)+y->v(p+1)*d; #pragma omp parallel for collapse(2) for(long j=0;jv(i); s.z.a[i0] = z->v(j); s.ax.a[i0] = ax->v(i,p,j)*(1-d) + ax->v(i,p+1,j)*d; s.ay.a[i0] = ay->v(i,p,j)*(1-d) + ay->v(i,p+1,j)*d; s.az.a[i0] = az->v(i,p,j)*(1-d) + az->v(i,p+1,j)*d; } } if(dir=='z') { mreal v = z->v(p)*(1-d)+z->v(p+1)*d; #pragma omp parallel for collapse(2) for(long j=0;jv(i); s.y.a[i0] = y->v(j); s.ax.a[i0] = ax->v(i,j,p)*(1-d) + ax->v(i,j,p+1)*d; s.ay.a[i0] = ay->v(i,j,p)*(1-d) + ay->v(i,j,p+1)*d; s.az.a[i0] = az->v(i,j,p)*(1-d) + az->v(i,j,p+1)*d; } } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt) { bool both = mgl_isboth(x,y,z,ax); if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Vect3",cgid++); char dir='y'; if(mglchr(sch,'x')) dir='x'; if(mglchr(sch,'z')) dir='z'; bool dot = mglchr(sch,'.'), fix = mglchr(sch,'f'); bool end = mglchr(sch,'>'), beg = mglchr(sch,'<'); bool grd = mglchr(sch,'='); gr->SetPenPal("-"); long ss = gr->AddTexture(sch); double fact = gr->size_opt<0 ? -gr->size_opt:1; _mgl_vec_slice s; mgl_get_slice(s,x,y,z,ax,ay,az,dir,sVal,both); long n=s.ax.nx,m=s.ax.ny, tx=1,ty=1; if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); } if(tx<1) tx=1; if(ty<1) ty=1; double xm=0,cm=0,ca=0, asize = gr->GetArrowSize(); double dm=(fabs(gr->Max.c)+fabs(gr->Min.c))*1e-5; // use whole array for determining maximal vectors length mglPoint d=(gr->Max-gr->Min)/mglPoint(1./ax->GetNx(),1./ax->GetNy(),1./ax->GetNz()); long tn=ty*n; #pragma omp parallel { double xm1=0,cm1=0, xx,yy,zz, c1,c2; mglPoint p1, p2, v; #pragma omp for nowait collapse(2) reduction(+:ca) for(long i=0;iAllocPnts(2*ni*nj); #pragma omp parallel for collapse(2) for(long j=0;jdm ? 1./dd : 0) : xm); if(end) { p1 = d-v; p2 = d; } else if(beg){ p1 = d; p2 = d+v; } else { p1=d-v/2.; p2=d+v/2.; } if(grd) { c1=gr->GetC(ss,dd*xm-0.5,false); c2=gr->GetC(ss,dd*xm,false);} else c1 = c2 = gr->GetC(ss,dd*xm,false); long iq = kq+2*(i+ni*j); bool r1=gr->AddPntQ(iq,p1,c1); bool r2=gr->AddPntQ(iq+1,p2,c2); if(!r1 && r2) gr->AddPntQ(iq,p1,c1,mglPoint(NAN),-1,2); if(!r2 && r1) gr->AddPntQ(iq+1,p2,c2,mglPoint(NAN),-1,2); } if(dot) for(long i=0;iline_plot(iq,iq+1); gr->mark_plot(iq,'.'); } else for(long i=0;ivect_plot(iq,iq+1,asize); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect3(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()),z(ax->GetNz()); // NOTE mglDataV here is useless x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_vect3_xyz(gr,&x,&y,&z,ax,ay,az,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_vect3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_vect3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_vect3(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Flow 2d series // //----------------------------------------------------------------------------- void static flow(mglBase *gr, double zVal, double u, double v, HCDT x, HCDT y, HCDT ax, HCDT ay, long ss, bool vv) { long n=100*(ax->GetNx()+ax->GetNy()); bool nboth = x->GetNx()*x->GetNy()!=ax->GetNx()*ax->GetNy() || y->GetNx()*y->GetNy()!=ax->GetNx()*ax->GetNy(); mglPoint *pp = new mglPoint[n], dp; mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z)); mglPoint nx(ax->GetNx(),ax->GetNy()); mreal dt = 0.5/(ax->GetNx() > ax->GetNy() ? ax->GetNx() : ax->GetNy()); mreal e,f,g,ff[4],gg[4],h,s=2,acc=dt/20; if(u<0 || v<0) { dt = -dt; u = -u; v = -v; s *= -1;} long k=0; bool end = false; if(nboth) do{ mglPoint dif; pp[k].x = x->Spline1(dif,u,0,0); f = ax->Spline1(u,v,0)/dif.x; pp[k].y = y->Spline1(dif,v,0,0); g = ay->Spline1(u,v,0)/dif.x; pp[k].z = zVal; if(mgl_isbad(f+g)) break; else for(long m=0;mGetC(ss,s*h); if(end || h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h; e = u+ff[0]/2; h = v+gg[0]/2; x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x; y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x; h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h; e = u+ff[1]/2; h = v+gg[1]/2; x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x; y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x; h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h; e = u+ff[2]; h = v+gg[2]; x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x; y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x; h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h; u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1; } while(!end); else do{ mglPoint dif; mreal xu,xv,yu,yv,det,xx,yy; pp[k].x = x->Spline1(dif,u,v,0); xu=dif.x; xv=dif.y; pp[k].y = y->Spline1(dif,u,v,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(u,v,0); yy = ay->Spline1(u,v,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; pp[k].z = zVal; if(mgl_isbad(f+g)) break; else for(long m=0;mGetC(ss,s*h); if(end || h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h; e = u+ff[0]/2; h = v+gg[0]/2; x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y; y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h; e = u+ff[1]/2; h = v+gg[1]/2; x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y; y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h; e = u+ff[2]; h = v+gg[2]; x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y; y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h; u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1; } while(!end); if(k>1) { long a=long(0.3*gr->GetArrowSize()/fabs(dt)); const long kq = gr->AllocPnts(k); //#pragma omp parallel for // NOTE: parallel is used in above function for(long i=0;iAddPntQ(kq+i,pp[i],pp[i].c); gr->curve_plot(k,kq); if(vv && dt<0) for(long i=a;ivect_plot(kq+i,kq+i-1,a/3.); if(vv && dt>0) for(long i=a;ivect_plot(kq+i-1,kq+i,a/3.); } delete []pp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,ax,ay,"Flow")) return; mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?5:long(r+0.5); static int cgid=1; gr->StartGroup("Flow",cgid++); gr->SetPenPal("-"); long ss = gr->AddTexture(sch); bool vv = mglchr(sch,'v'); // allocate memory mreal zVal = gr->Min.z; bool cnt=!mglchr(sch,'#'); std::vector u, v; long nx=ax->GetNx(), ny=ax->GetNy(); if(mglchr(sch,'.')) { mglData a(nx,ny); r = mgl_isnan(r)?0.5:r; const mreal di = 1/mreal(nx-1), dj = 1/mreal(ny-1), ds=r*di, dt=r*dj; #pragma omp parallel for for(long i=0;ivthr(i)*ax->vthr(i)+ay->vthr(i)*ay->vthr(i); #pragma omp parallel for collapse(2) for(long j=1;jv(i),y->v(j),0,"b."); } /* { if((ax->vthr(i0-1+nx)-ay->vthr(i0-1+nx))*(ax->vthr(i0+1-nx)-ay->vthr(i0+1-nx))<=0 && (ax->vthr(i0-1-nx)+ay->vthr(i0-1-nx))*(ax->vthr(i0+1+nx)+ay->vthr(i0+1+nx))<=0) // && (ax->vthr(i0-1)*ay->vthr(i0-nx)<0 || ax->vthr(i0+1)*ay->vthr(i0+ny)<0)) #pragma omp critical(flow) { mreal s = i*di, t = j*dj; u.push_back(s+ds); v.push_back(t+dt); u.push_back(-s-ds); v.push_back(-t-dt); u.push_back(s-ds); v.push_back(t-dt); u.push_back(-s+ds); v.push_back(-t+dt); mgl_mark(gr,x->v(i),y->v(j),0,"b."); } else if(ax->vthr(i0-1)*ax->vthr(i0+1)<=0 && ay->vthr(i0-nx)*ay->vthr(i0+nx)<=0) // && (ax->vthr(i0-1)*ay->vthr(i0-nx)<0 || ax->vthr(i0+1)*ay->vthr(i0+ny)<0)) #pragma omp critical(flow) { mreal s = i*di, t = j*dj; u.push_back(s+ds); v.push_back(t); u.push_back(-s-ds); v.push_back(-t); u.push_back(s-ds); v.push_back(t); u.push_back(-s+ds); v.push_back(-t); mgl_mark(gr,x->v(i),y->v(j),0,"r."); } }*/ } } else if(mglchr(sch,'*')) for(long i=0;iGetNz();k++) { if(gr->NeedStop()) break; if(ax->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1); HMDT bx=mgl_data_subdata(ax,-1,-1,k), by=mgl_data_subdata(ay,-1,-1,k); #pragma omp parallel for for(long i=0;iNeedStop()) flow(gr, zVal, u[i], v[i], x, y, bx, by,ss,vv); mgl_delete_data(bx); mgl_delete_data(by); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()); // NOTE mglDataV here is useless x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_flow_xy(gr,&x,&y,ax,ay,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flow_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } void MGL_EXPORT mgl_flow_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flow_2d(_GR_, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flowp_xy(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt) { if(mgl_isnan(z0)) z0 = gr->Min.z; mreal u,v; long n=ax->GetNx(), m=ax->GetNy(); bool nboth = x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m; if(mgl_check_dim2(gr,x,y,ax,ay,"FlowP")) return; bool forward=true, backward=true; if(mglchr(sch,'<')) { forward=false; backward=true; } if(mglchr(sch,'>')) { forward=true; backward=false; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("FlowP",cgid++); gr->SetPenPal("-"); long ss = gr->AddTexture(sch); bool vv = mglchr(sch,'v'); // find coordinates u, v mreal dm=INFINITY; long i0=0,j0=0; if(nboth) { mreal dx=INFINITY, dy=INFINITY; for(long i=0;iv(i)-x0); if(dv(j)-y0); if(dv(i,j)-x0,y->v(i,j)-y0); if(dv(i0)-x0; dy = y->v(j0)-y0; dxu= x->dvx(i0); dyv= y->dvx(j0); u = (i0+dx/dxu)/n; v = (j0+dy/dyv)/m; } else { dx = x->v(i0,j0)-x0; dy = y->v(i0,j0)-y0; dxu= x->dvx(i0,j0); dyu= y->dvx(i0,j0); dxv= x->dvy(i0,j0); dyv= y->dvy(i0,j0); mreal d = dxv*dyu-dxu*dyv; u = (i0+(dxv*dy-dx*dyv)/d)/n; v = (j0-(dxu*dy-dx*dyu)/d)/m; } } if(forward) flow(gr, z0, u, v, x, y, ax, ay,ss,vv); if(backward) flow(gr, z0,-u,-v, x, y, ax, ay,ss,vv); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flowp_2d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_flowp_xy(gr,x0,y0,z0,&x,&y,ax,ay,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flowp_xy_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flowp_xy(_GR_, *x0,*y0,*z0, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } void MGL_EXPORT mgl_flowp_2d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flowp_2d(_GR_, *x0,*y0,*z0, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Flow 3d series // //----------------------------------------------------------------------------- void flow(mglBase *gr, double u, double v, double w, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az,long ss,bool vv, bool xo, bool zo) { static long n=100*(ax->GetNx()+ax->GetNy()+ax->GetNz()); long nn = ax->GetNN(); bool nboth = x->GetNN()!=nn || y->GetNN()!=nn || z->GetNN()!=nn; mglPoint *pp = new mglPoint[n], dp; mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z)); mglPoint nx(ax->GetNx(),ax->GetNy(),ax->GetNz()); nn = (ax->GetNx() > ax->GetNy() ? ax->GetNz() : ax->GetNy()); nn = (nn > ax->GetNz() ? nn : ax->GetNz()); mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1,acc=dt/20; if(u<0 || v<0 || w<0) { dt = -dt; u = -u; v = -v; w = -w; s *= -1;} long k=0; bool end = false; if(nboth) do{ mglPoint dif; pp[k].x = x->Spline1(dif,u,0,0); e = ax->Spline1(u,v,w)/dif.x; pp[k].y = y->Spline1(dif,v,0,0); f = ay->Spline1(u,v,w)/dif.x; pp[k].z = z->Spline1(dif,w,0,0); g = az->Spline1(u,v,w)/dif.x; if(mgl_isbad(e+f+g)) end = true; else for(long m=0;mGetC(ss,s*h); if(h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h; u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2; x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x; y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x; z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x; h = 1+sqrt(e*e+f*f+g*g); ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h; u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2; x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x; y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x; z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x; h = 1+sqrt(e*e+f*f+g*g); ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h; u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2]; x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x; y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x; z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x; h = 1+sqrt(e*e+f*f+g*g); ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h; u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6; v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1; } while(!end); else do{ mglPoint dif; mreal xu,xv,xw,yu,yv,yw,zv,zu,zw,det,xx,yy,zz; pp[k].x = x->Spline1(dif,u,v,w); xu=dif.x; xv=dif.y; xw=dif.z; pp[k].y = y->Spline1(dif,u,v,w); yu=dif.x; yv=dif.y; yw=dif.z; pp[k].z = z->Spline1(dif,u,v,w); zu=dif.x; zv=dif.y; zw=dif.z; xx = ax->Spline1(u,v,w); yy = ay->Spline1(u,v,w); zz = az->Spline1(u,v,w); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; if(mgl_isbad(e+f+g)) end = true; else for(long m=0;mGetC(ss,s*h); if(h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h; u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2; x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1); y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1); z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; h = 1+sqrt(e*e+f*f+g*g); ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h; u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2; x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1); y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1); z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; h = 1+sqrt(e*e+f*f+g*g); ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h; u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2]; x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1); y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1); z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; h = 1+sqrt(e*e+f*f+g*g); ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h; u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6; v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1; } while(!end); if(k>1) // TODO exclude AddPnt() and use curve_plot()!!! { long j,a=long(0.3*gr->GetArrowSize()/fabs(dt)); mreal rr = mgl_anorm(gr->Max-gr->Min)*gr->BarWidth/25, ll; mglPoint q1,q2,l; long n1=-1,n2=-1,n3=-1,n4=-1; gr->Reserve(4*k); j = gr->AddPnt(pp[0],pp[0].c); l = pp[1] - pp[0]; l /= mgl_anorm(l); q1.Set(l.y,-l.x,0); ll = mgl_anorm(q1); if(ll) q1 /= ll; else q1.Set(0,1,0); q2 = q1^l; if(xo) { n1 = gr->AddPnt(pp[0],-1,q2); n2 = gr->AddPnt(pp[0]+rr*q1,-1,q2); } if(zo) { n3 = gr->AddPnt(pp[0],-1,q1); n4 = gr->AddPnt(pp[0]+rr*q2,-1,q1); } for(long i=1;iAddPnt(pp[i],pp[i].c); if(vv && i%a==0) { if(dt<0) gr->vect_plot(j,jj,a/3); else gr->vect_plot(jj,j,a/3); } else gr->line_plot(jj,j); l = pp[i]-pp[i-1]; l /= mgl_anorm(l); q1 -= l*(l*q1); q1/= mgl_anorm(q1); q2 = q1^l; long m1 = n1, m2 = n2, m3 = n3, m4 = n4; if(xo) { n1 = gr->AddPnt(pp[i],pp[i].c,q2); n2 = gr->AddPnt(pp[i]+rr*q1,pp[i].c,q2); gr->quad_plot(n1,n2,m1,m2); } if(zo) { n3 = gr->AddPnt(pp[i],pp[i].c,q1); n4 = gr->AddPnt(pp[i]+rr*q2,pp[i].c,q1); gr->quad_plot(n3,n4,m3,m4); } } /* TODO long a=long(0.3*gr->GetArrowSize()/fabs(dt)); gr->Reserve(k); long *nn = new long[k]; for(long i=0;iAddPnt(pp[i],pp[i].c); gr->curve_plot(k,nn); if(vv && dt<0) for(long i=a;ivect_plot(nn[i],nn[i-1],a/3.); if(vv && dt>0) for(long i=a;ivect_plot(nn[i-1],nn[i],a/3.); delete []nn;*/ } delete []pp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt) { if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Flow3")) return; mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?5:long(r+0.5); static int cgid=1; gr->StartGroup("Flow3",cgid++); char dir='y'; if(mglchr(sch,'x')) dir='x'; if(mglchr(sch,'z')) dir='z'; gr->SetPenPal("-"); long ss = gr->AddTexture(sch); bool vv = mglchr(sch,'v'), tt = mglchr(sch,'t'); std::vector u; const double f = 1./(num+1); if(dir=='x') { long n = ax->GetNx()-1; sVal = (sVal<0 || sVal>n) ? 0.5 : sVal/n; for(long j=0;jGetNy()-1; sVal = (sVal<0 || sVal>n) ? 0.5 : sVal/n; for(long j=0;jGetNy()-1; sVal = (sVal<0 || sVal>n) ? 0.5 : sVal/n; for(long j=0;jNeedStop()) flow(gr, u[i].x, u[i].y, u[i].z, x, y, z, ax, ay, az, ss,vv,tt,tt); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow3(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()),z(ax->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_flow3_xyz(gr,&x,&y,&z,ax,ay,az,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, double *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flow3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, *sVal, o); delete []o; delete []s; } void MGL_EXPORT mgl_flow3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, double *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flow3(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Flow3d")) return; mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?3:long(r+0.5); static int cgid=1; gr->StartGroup("Flow3d",cgid++); bool cnt=!mglchr(sch,'#'); gr->SetPenPal("-"); long ss = gr->AddTexture(sch); bool vv = mglchr(sch,'v'), xo = mglchr(sch,'x'), zo = mglchr(sch,'z'); std::vector u; for(long i=0;iNeedStop()) flow(gr, u[i].x, u[i].y, u[i].z, x, y, z, ax, ay, az,ss,vv,xo,zo); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); // NOTE mglDataV here is useless x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_flow_xyz(gr,&x,&y,&z,ax,ay,az,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flow_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flow_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } void MGL_EXPORT mgl_flow_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flow_3d(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { mglPoint p(x0,y0,z0); mreal u,v,w; long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(); bool nboth = !(x->GetNN()==n*m*l && y->GetNN()==n*m*l && z->GetNN()==n*m*l); if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"FlowP3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("FlowP3",cgid++); gr->SetPenPal("-"); long ss = gr->AddTexture(sch); bool vv = mglchr(sch,'v'), xo = mglchr(sch,'x'), zo = mglchr(sch,'z'); bool forward=true, backward=true; if(mglchr(sch,'<')) { forward=false; backward=true; } if(mglchr(sch,'>')) { forward=true; backward=false; } // find coordinates u, v, w mreal dm=INFINITY; long i0=0,j0=0,k0=0; if(nboth) // first find closest { mreal dx=INFINITY, dy=INFINITY, dz=INFINITY; for(long i=0;iv(i)-p.x); if(dv(j)-p.y); if(dv(k)-p.z); if(dv(i,j,k)-p.x, dy = y->v(i,j,k)-p.y, dz = x->v(i,j,k)-p.z; mreal d = sqrt(dx*dx+dy*dy+dz*dz); if(dv(i0)-p.x; dy = y->v(j0)-p.y; dz = z->v(k0)-p.z; dxu= x->dvx(i0); dyv= y->dvx(j0); dzw= z->dvx(k0); u = (i0+dx/dxu)/n; v = (j0+dy/dyv)/m; w = (k0+dz/dzw)/m; } else { dx = x->v(i0,j0,k0)-p.x; dy = y->v(i0,j0,k0)-p.y; dz = z->v(i0,j0,k0)-p.z; dxu= x->dvx(i0,j0,k0); dyu= y->dvx(i0,j0,k0); dzu= z->dvx(i0,j0,k0); dxv= x->dvy(i0,j0,k0); dyv= y->dvy(i0,j0,k0); dzv= z->dvy(i0,j0,k0); dxw= x->dvz(i0,j0,k0); dyw= y->dvz(i0,j0,k0); dzw= z->dvz(i0,j0,k0); mreal d = dxu*(dyw*dzv-dyv*dzw)+dxv*(dyu*dzw-dyw*dzu)+dxw*(dyv*dzu-dyu*dzv); u = (i0+(dx*(dyw*dzv-dyv*dzw)+dxv*(dy*dzw-dyw*dz)+dxw*(dyv*dz-dy*dzv))/d)/n; v = (j0-(dx*(dyw*dzu-dyu*dzw)+dxu*(dy*dzw-dyw*dz)+dxw*(dyu*dz-dy*dzu))/d)/m; w = (i0+(dx*(dyv*dzu-dyu*dzv)+dxu*(dy*dzv-dyv*dz)+dxv*(dyu*dz-dy*dzu))/d)/l; } } if(forward) flow(gr, u, v, w, x, y, z, ax, ay, az,ss,vv,xo,zo); if(backward) flow(gr,-u,-v,-w, x, y, z, ax, ay, az,ss,vv,xo,zo); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flowp_3d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); // NOTE mglDataV here is useless x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_flowp_xyz(gr, x0,y0,z0, &x,&y,&z,ax,ay,az,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_flowp_xyz_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flowp_xyz(_GR_, *x0,*y0,*z0, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } void MGL_EXPORT mgl_flowp_3d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_flowp_3d(_GR_, *x0,*y0,*z0, _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Grad series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grad_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT phi, const char *sch, const char *opt) { mglData ax(phi), ay,az,xx,yy,zz; ay.Set(ax); az.Set(ax); xx.Set(ax); yy.Set(ax); zz.Set(ax); long n=xx.nx, m=xx.ny, l=xx.nz, nn = n*m*l; if(x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn) { xx.Set(x); yy.Set(y); zz.Set(z); } // nothing to do else if(x->GetNx()==n && y->GetNx()==m && z->GetNx()==l) #pragma omp parallel for collapse(3) for(long i=0;iv(i); yy.a[i0] = y->v(j); zz.a[i0] = z->v(k); } else { gr->SetWarn(mglWarnDim,"Grad"); return; } ax.Diff(xx,yy,zz); ay.Diff(yy,xx,zz); az.Diff(zz,xx,yy); mgl_flow_xyz(gr,&xx,&yy,&zz,&ax,&ay,&az,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grad_xy(HMGL gr, HCDT x, HCDT y, HCDT phi, const char *sch, const char *opt) { mglData ax(phi), ay,xx,yy; ay.Set(ax); xx.Set(ax); yy.Set(ax); long n = phi->GetNx(), m=phi->GetNy(), nn=n*m; if(x->GetNx()*x->GetNy()==nn && y->GetNx()*y->GetNy()==nn) { xx.Set(x); yy.Set(y); } else if(x->GetNx()==n && y->GetNx()==m) #pragma omp parallel for collapse(2) for(long i=0;iv(i); yy.a[i0] = y->v(j); } else { gr->SetWarn(mglWarnDim,"Grad"); return; } ax.Diff(xx,yy); ay.Diff(yy,xx); mgl_flow_xy(gr,&xx,&yy,&ax,&ay,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grad(HMGL gr, HCDT phi, const char *sch, const char *opt) { mglDataV x(phi->GetNx()), y(phi->GetNy()), z(phi->GetNz()); gr->SaveState(opt); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); if(phi->GetNz()==1) mgl_grad_xy(gr,&x,&y,phi,sch,0); else mgl_grad_xyz(gr,&x,&y,&z,phi,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grad_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ph, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grad_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ph), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grad_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ph, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grad_xy(_GR_, _DA_(x), _DA_(y), _DA_(ph), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grad_(uintptr_t *gr, uintptr_t *ph, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grad(_GR_, _DA_(ph), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Pipe 2d series // //----------------------------------------------------------------------------- void static flowr(mglBase *gr, double zVal, double u, double v, HCDT x, HCDT y, HCDT ax, HCDT ay, double r0,long sc) { long n=100*(ax->GetNx()+ax->GetNy()); bool nboth = x->GetNx()*x->GetNy()!=ax->GetNx()*ax->GetNy() || y->GetNx()*y->GetNy()!=ax->GetNx()*ax->GetNy(); mglPoint *pp = new mglPoint[n], dp; mreal *cc = new mreal[n]; mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z)); mglPoint nx(ax->GetNx(),ax->GetNy()); double dt = 0.5/(ax->GetNx() > ax->GetNy() ? ax->GetNx() : ax->GetNy()),e,f,g,ff[4],gg[4],h,s=2,acc=dt/20; double ss = 16./mgl_ipow(gr->Max.c - gr->Min.c,2); if(u<0 || v<0) { dt = -dt; u = -u; v = -v; s *= -1;} long k=0; bool end = false; if(nboth) do{ mglPoint dif; pp[k].x = x->Spline1(dif,u,0,0); f = ax->Spline1(u,v,0)/dif.x; pp[k].y = y->Spline1(dif,v,0,0); g = ay->Spline1(u,v,0)/dif.x; pp[k].z = zVal; if(mgl_isbad(f+g)) end = true; else for(long m=0;mGetC(sc,s*h); pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5; if(h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h; e = u+ff[0]/2; h = v+gg[0]/2; x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x; y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x; h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h; e = u+ff[1]/2; h = v+gg[1]/2; x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x; y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x; h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h; e = u+ff[2]; h = v+gg[2]; x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x; y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x; h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h; u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1; } while(!end); else do{ mglPoint dif; mreal xu,xv,yu,yv,det,xx,yy; pp[k].x = x->Spline1(dif,u,v,0); xu=dif.x; xv=dif.y; pp[k].y = y->Spline1(dif,u,v,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(u,v,0); yy = ay->Spline1(u,v,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; pp[k].z = zVal; if(mgl_isbad(f+g)) end = true; else for(long m=0;mGetC(sc,s*h); pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5; if(h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h; e = u+ff[0]/2; h = v+gg[0]/2; x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y; y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h; e = u+ff[1]/2; h = v+gg[1]/2; x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y; y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h; e = u+ff[2]; h = v+gg[2]; x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y; y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y; xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0); det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det; h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h; u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1; } while(!end); if(k>1) { const int num=!(gr->GetQuality()&3)?13:25; mglPoint l=pp[1]-pp[0],t=!l,q=t^l; t.Normalize(); q.Normalize(); double rr=pp[0].c,dr=l.c; const long kq = gr->AllocPnts(num*k); for(long j=0;jAddPntQ(kq+j,p,cc[0],d); } for(long i=1;iAddPntQ(kq+i*num+j,p,cc[i],d); } } for(long i=1;iquad_plot(iq-1,iq,iq-num-1,iq-num); } } delete []pp; delete []cc; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt) { if(mgl_check_dim2(gr,x,y,ax,ay,"Pipe")) return; mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?5:long(r+0.5); static int cgid=1; gr->StartGroup("Pipe",cgid++); long ss = gr->AddTexture(sch); // allocate memory mreal zVal = gr->Min.z; bool cnt=!mglchr(sch,'#'); if(mglchr(sch,'i')) r0 = -fabs(r0); std::vector u, v; if(mglchr(sch,'*')) for(long i=0;iGetNz();k++) { if(gr->NeedStop()) break; if(ax->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1); HMDT bx=mgl_data_subdata(ax,-1,-1,k), by=mgl_data_subdata(ay,-1,-1,k); #pragma omp parallel for for(long i=0;iNeedStop()) flowr(gr, zVal, u[i], v[i], x, y, bx, by,r0,ss); mgl_delete_data(bx); mgl_delete_data(by); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pipe_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()); // NOTE mglDataV here is useless x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); mgl_pipe_xy(gr,&x,&y,ax,ay,sch,r0,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pipe_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, mreal *r0, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pipe_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, *r0, o); delete []o; delete []s; } void MGL_EXPORT mgl_pipe_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, mreal *r0, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pipe_2d(_GR_, _DA_(ax), _DA_(ay), s, *r0, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Pipe 3d series // //----------------------------------------------------------------------------- void flowr(mglBase *gr, double u, double v, double w, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, double r0,long sc) { static long n=100*(ax->GetNx()+ax->GetNy()+ax->GetNz()); long nn = ax->GetNN(); bool nboth = x->GetNN()!=nn || y->GetNN()!=nn || z->GetNN()!=nn; mglPoint *pp = new mglPoint[n], dp; mreal *cc = new mreal[n]; mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z)); mglPoint nx(ax->GetNx(),ax->GetNy(),ax->GetNz()); nn = (ax->GetNx() > ax->GetNy() ? ax->GetNx() : ax->GetNy()); nn = (nn > ax->GetNz() ? nn : ax->GetNz()); double dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1,acc=dt/20; double ss = 16./mgl_ipow(gr->Max.c - gr->Min.c,2); if(u<0 || v<0 || w<0) { dt = -dt; u = -u; v = -v; w = -w; s *= -1;} long k=0; bool end = false; if(nboth) do{ mglPoint dif; pp[k].x = x->Spline1(dif,u,0,0); e = ax->Spline1(u,v,w)/dif.x; pp[k].y = y->Spline1(dif,v,0,0); f = ay->Spline1(u,v,w)/dif.x; pp[k].z = z->Spline1(dif,w,0,0); g = az->Spline1(u,v,w)/dif.x; if(mgl_isbad(e+f+g)) end = true; else for(long m=0;mGetC(sc,s*h); pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5; if(h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h; u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2; x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x; y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x; z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x; h = 1+sqrt(e*e+f*f+g*g); ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h; u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2; x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x; y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x; z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x; h = 1+sqrt(e*e+f*f+g*g); ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h; u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2]; x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x; y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x; z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x; h = 1+sqrt(e*e+f*f+g*g); ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h; u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6; v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1; } while(!end); else do{ mglPoint dif; mreal xu,xv,xw,yu,yv,yw,zv,zu,zw,det,xx,yy,zz; pp[k].x = x->Spline1(dif,u,v,w); xu=dif.x; xv=dif.y; xw=dif.z; pp[k].y = y->Spline1(dif,u,v,w); yu=dif.x; yv=dif.y; yw=dif.z; pp[k].z = z->Spline1(dif,u,v,w); zu=dif.x; zv=dif.y; zw=dif.z; xx = ax->Spline1(u,v,w); yy = ay->Spline1(u,v,w); zz = az->Spline1(u,v,w); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; if(mgl_isbad(e+f+g)) end = true; else for(long m=0;mGetC(sc,s*h); pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5; if(h<1e-5) break; // stationary point if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++; // find next point by midpoint method h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h; u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2; x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1); y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1); z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; h = 1+sqrt(e*e+f*f+g*g); ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h; u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2; x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1); y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1); z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; h = 1+sqrt(e*e+f*f+g*g); ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h; u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2]; x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1); y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1); z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1); det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu; e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det; f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det; g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det; h = 1+sqrt(e*e+f*f+g*g); ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h; u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6; v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6; w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6; // condition of end end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1; } while(!end); if(k>1) { const int num=!(gr->GetQuality()&3)?13:25; mglPoint l=pp[1]-pp[0],t=!l,q=t^l,p,d; t.Normalize(); q.Normalize(); double rr=pp[0].c,dr=l.c; long kq = gr->AllocPnts(num*k); for(long j=0;jAddPntQ(kq+j,p,cc[0],d); } for(long i=1;iAddPntQ(kq+i*num+j,p,cc[i],d); } } for(long i=1;iquad_plot(iq-1,iq,iq-num-1,iq-num); } } delete []pp; delete []cc; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt) { if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect")) return; mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?3:long(r+0.5); static int cgid=1; gr->StartGroup("Pipe3",cgid++); if(mglchr(sch,'i')) r0 = -fabs(r0); long ss = gr->AddTexture(sch); bool cnt=!mglchr(sch,'#'); std::vector u, v, w; for(long i=0;iNeedStop()) flowr(gr, u[i], v[i], w[i], x, y, z, ax, ay, az,r0,ss); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pipe_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt) { gr->SaveState(opt); mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); // NOTE mglDataV here is useless x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_pipe_xyz(gr,&x,&y,&z,ax,ay,az,sch,r0,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pipe_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *r0, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pipe_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, *r0, o); delete []o; delete []s; } void MGL_EXPORT mgl_pipe_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *r0, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pipe_3d(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, *r0, o); delete []o; delete []s; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/pixel_gen.cpp0000644000175000017500000004765013513030041016426 0ustar alastairalastair/*************************************************************************** * pixel.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/canvas.h" #include "mgl2/thread.h" #if MGL_HAVE_OMP #include #endif //----------------------------------------------------------------------------- #if MGL_HAVE_PTHREAD static void *mgl_canvas_thr(void *par) { mglThreadG *t=(mglThreadG *)par; (t->gr->*(t->f))(t->id, t->n, t->p); return NULL; } #endif void mglStartThread(void (mglCanvas::*func)(long i, long n, const void *p), mglCanvas *gr, long n, const void *p=NULL) { if(!func || !gr) return; #if MGL_HAVE_PTHREAD if(mglNumThr<1) mgl_set_num_thr(0); if(mglNumThr>1) { pthread_t *tmp=new pthread_t[mglNumThr]; mglThreadG *par=new mglThreadG[mglNumThr]; for(long i=0;i*func)(0,n,p); } } //----------------------------------------------------------------------------- void mglCanvas::SetSize(int w,int h,bool clf) { if(w<=0 || h<=0) { SetWarn(mglWarnSize,"SetSize"); return; } if(Width==w && Height==h) { InPlot(0,1,0,1,false); if(clf || (Quality&4)) Clf(); return; } const double dx = double(w)/Width; const double dy = double(h)/Height; const double dz = sqrt(double(w*h))/Depth; Width = w; Height = h; Depth = long(sqrt(double(w*h))); const long s = long(w)*long(h); #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexClf); #elif MGL_HAVE_OMP omp_set_lock((omp_lock_t*)lockClf); #endif if(G) { delete []G; delete []C; delete []Z; delete []G4;delete []GB;delete []OI; G=0; } G = new unsigned char[s*3]; G4= new unsigned char[s*4]; GB= new unsigned char[s*4]; C = new unsigned char[s*12]; Z = new float[s*3]; // only 3 planes OI= new int[s]; #pragma omp parallel for for(long i=0;idy?dy:dx; #pragma omp parallel for // Scale text for(long i=0;i &pnt = DrwDat[k].Pnt; const long n = long(pnt.size()); #pragma omp parallel for for(long i=0;i &sub = DrwDat[k].Sub; for(size_t i=0;iObjId; PDef = gr->mask; angle = gr->MaskAn; x1 = gr->GetWidth()*mx/nx; y1 = gr->GetHeight()-gr->GetHeight()*(my+1)/ny; x2 = gr->GetWidth()*(mx+1)/nx-1; y2 = gr->GetHeight()-gr->GetHeight()*my/ny-1; } //----------------------------------------------------------------------------- void mglCanvas::PutDrawReg(mglDrawReg *d, const mglCanvas *gr) { if(gr) { const int dd = d->x2 - d->x1; for(long j=d->y1;jy2;j++) { long i = d->x1+Width*(Height-1-j); memcpy(OI+i,gr->OI+i,dd*sizeof(int)); memcpy(Z+3*i,gr->Z+3*i,3*dd*sizeof(float)); memcpy(C+12*i,gr->C+12*i,12*dd); } } } //----------------------------------------------------------------------------- void mglCanvas::PostScale(const mglMatrix *M, mglPoint &p) const { float f = 1./(2*M->pf),x=p.x,y=p.y,z=p.z; const float *b=M->b; p.x = M->x + f*(x*b[0] + y*b[1] + z*b[2]); p.y = M->y + f*(x*b[3] + y*b[4] + z*b[5]); p.z = M->z + f*(x*b[6] + y*b[7] + z*b[8]); } //----------------------------------------------------------------------------- bool mglCanvas::ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan) const { bool res = get(MGL_DISABLE_SCALE) || mglBase::ScalePoint(M,p,n,use_nan); PostScale(M,p); float nx=n.x, ny=n.y, nz=n.z; const float *b=M->b; n.x = nx*b[0] + ny*b[1] + nz*b[2]; // simpler for rotation only n.y = nx*b[3] + ny*b[4] + nz*b[5]; n.z = nx*b[6] + ny*b[7] + nz*b[8]; n.Normalize(); return res; } //----------------------------------------------------------------------------- long mglCanvas::ProjScale(int nf, long id, bool text) { const mglPnt &pi = Pnt[id]; mglPoint pp(pi.x,pi.y,pi.z), nn(pi.u,pi.v,pi.w), p, n; if(mgl_isnan(pp.x)) return -1; const float w=B1.b[0]/2, h=B1.b[4]/2, d=B1.b[8]/2, xx=B1.x-w/2, yy=B1.y-h/2; if(pi.sub>=0) { mglPoint q(RestorePnt(pp)/(2*B.pf)); mglPoint u(RestorePnt(nn,true)); u.Normalize(); if(nf==0) { p.x = xx + q.x*w; p.y = yy + q.y*h; p.z = B1.z + q.z*d; n = u; } else if(nf==1) { p.x = xx + q.x*w; p.y = yy+h + q.z*h; p.z = B1.z - q.y*d; n.Set(u.x,u.z,-u.y); } else if(nf==2) { p.x = xx+w + q.z*w; p.y = yy + q.y*h; p.z = B1.z - q.x*d; n.Set(u.z,u.y,-u.x); } else { const float *b=B.b; n = nn; p.x = xx+w + q.x*b[0]/2 + q.y*b[1]/2 + q.z*b[2]/2; p.y = yy+h + q.x*b[3]/2 + q.y*b[4]/2 + q.z*b[5]/2; p.z = B.z + q.x*b[6]/2 + q.y*b[7]/2 + q.z*b[8]/2; } } else { p.x = pi.x/2 + w*(nf/2); p.y = pi.y/2 + h*(nf%2); p.z = pi.z; n=nn; } return CopyProj(id,p,text?n:nn,pi.sub); } //----------------------------------------------------------------------------- void mglCanvas::LightScale(const mglMatrix *M, mglLight &ls) { ls.p=ls.d; ls.q=ls.r; ScalePoint(M,ls.q,ls.p,false); ls.p /= ls.p.norm(); } //----------------------------------------------------------------------------- void mglCanvas::LightScale(const mglMatrix *M) { for(long i=0;i<10;i++) if(light[i].n) LightScale(M,light[i]); for(size_t j=0;j fabs(d2) && fabs(d1) > fabs(d3)) // x-y plane { p.z = 0; p.x = s3*(c4*xx-c1*yy)/d1; p.y = s3*(c0*yy-c3*xx)/d1; } else if(fabs(d2) > fabs(d3)) // y-z { p.x = 0; p.y = s3*(c5*xx-c2*yy)/d2; p.z = s3*(c1*yy-c4*xx)/d2; } else // x-z { p.y = 0; p.x = s3*(c5*xx-c2*yy)/d3; p.z = s3*(c0*yy-c3*xx)/d3; } return p; } //----------------------------------------------------------------------------- mglPoint mglCanvas::CalcXYZ(int xs, int ys, bool real) const { if(xs<0 || ys<0 || xs>=Width || ys>=Height) return mglPoint(NAN,NAN,NAN); mglPoint p, ps(xs,Height-ys,NAN); float zz = Z[3*(xs+Width*(Height-1-ys))]; if(zz>-1e20f) { ps.z = zz; real=false; } p = RestorePnt(ps); return real ? mglPoint(NAN,NAN,NAN) : mglPoint(Min.x + (Max.x-Min.x)*(p.x+1)/2, Min.y + (Max.y-Min.y)*(p.y+1)/2, Min.z + (Max.z-Min.z)*(p.z+1)/2); } //----------------------------------------------------------------------------- void mglCanvas::CalcScr(mglPoint p, int *xs, int *ys) const { mglPoint n; ScalePoint(GetB(),p,n); if(xs) *xs=int(p.x); if(ys) *ys=int(p.y); } //----------------------------------------------------------------------------- mglPoint mglCanvas::CalcScr(mglPoint p) const { int x,y; CalcScr(p,&x,&y); return mglPoint(x,y); } //----------------------------------------------------------------------------- /*void static mgl_prm_swap(mglPrim &s1,mglPrim &s2,mglPrim *buf) { memcpy(buf, &s1, sizeof(mglPrim)); memcpy(&s1, &s2, sizeof(mglPrim)); memcpy(&s2, buf, sizeof(mglPrim)); } void static sort_prm_c(const size_t l0, const size_t r0, mglStack &s, mglPrim *buf) { if(l0==r0) return; if(l0+1==r0) { if(s[r0].n1l) mgl_prm_swap(s[i],s[l],buf); l++; } r=l; for(size_t i=l;i<=r0;i++) // now collect =0 if(s[i].n1==v) { if(i>r) mgl_prm_swap(s[i],s[r],buf); r++; } if(l>l0+1) sort_prm_c(l0,l-1,s,buf); if(r=Prm.size() || j>=Prm.size()) return 0; const mglPrim &a = Prm[i]; const mglPrim &b = Prm[j]; if(a.z!=b.z) return int(100*(a.z - b.z)); int t1 = mgl_type_prior[a.type], t2 = mgl_type_prior[b.type]; if(t1!=t2) return t2 - t1; if(a.w!=b.w) return int(100*(b.w - a.w)); return a.n3 - b.n3; } int MGL_LOCAL_PURE mgl_prm_cmp(const void *i,const void *j) { return mgl_qsort_gr->PrmCmp(*((const size_t *)i), *((const size_t *)j)); } //----------------------------------------------------------------------------- void mglCanvas::PreparePrim(int fast) { if(fast!=2) { mglStartThread(&mglCanvas::pxl_transform,this,Pnt.size()); if(fast==0) mglStartThread(&mglCanvas::pxl_setz,this,Prm.size()); else mglStartThread(&mglCanvas::pxl_setz_adv,this,Prm.size()); #pragma omp critical { ClearPrmInd(); mgl_qsort_gr = this; size_t n = Prm.size(); PrmInd = new size_t[n]; for(size_t i=0;i0) { #pragma omp critical { if(pnt_col) delete []pnt_col; pnt_col = new uint32_t[Pnt.size()]; } mglStartThread(&mglCanvas::pxl_pntcol,this,Pnt.size()); } } //----------------------------------------------------------------------------- void mglCanvas::Finish() { static mglMatrix bp; if(Quality==MGL_DRAW_NONE) return; #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexPrm); pthread_mutex_lock(&mutexPnt); pthread_mutex_lock(&mutexClf); #elif MGL_HAVE_OMP omp_set_lock((omp_lock_t*)lockClf); #endif size_t n=Width*Height; if(Quality!=MGL_DRAW_DOTS) { if((Quality&MGL_DRAW_LMEM) || ( Bp!=bp && !(Quality&MGL_DRAW_LMEM) && Prm.size()>0)) clr(MGL_FINISHED); if(!get(MGL_FINISHED)) { if(!(Quality&MGL_DRAW_LMEM) && Prm.size()>0) { PreparePrim(0); bp=Bp; clr(MGL_FINISHED); mglStartThread(&mglCanvas::pxl_primdr,this,Prm.size()); } BDef[3] = (Flag&3)!=2 ? 0:255; if(Quality&MGL_DRAW_NORM) mglStartThread(&mglCanvas::pxl_combine,this,n); else mglStartThread(&mglCanvas::pxl_memcpy,this,n); BDef[3] = 255; } } else { mglStartThread(&mglCanvas::pxl_dotsdr,this,Pnt.size()); mglStartThread(&mglCanvas::pxl_memcpy,this,n); } int x2 = BBoxX2<0?Width:BBoxX2, y2 = BBoxY2<0?Height:BBoxY2; if(BBoxX1>=0 && BBoxX1=0 && BBoxY10) for(long i=0;i0) for(long i=0;i0) #pragma omp parallel for for(long i=0;iWidth || Height!=gr->Height) return; // wrong sizes mglStartThread(&mglCanvas::pxl_other,this,Width*Height,gr); } //----------------------------------------------------------------------------- unsigned char **mglCanvas::GetRGBLines(long &w, long &h, unsigned char *&f, bool alpha) { unsigned char **p; Finish(); long c = alpha?4:3, d = c*Width; unsigned char *gg = (alpha?G4:G); int x2 = BBoxX2<0?Width:BBoxX2, y2 = BBoxY2<0?Height:BBoxY2; if(BBoxX1>=0 && BBoxX1=0 && BBoxY1 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/font.h" /// Table of LaTeX symbols and its UTF8 codes. This array MUST BE sorted!!! const size_t mgl_tex_num=1924; const mglTeXsymb mgl_tex_symb[] = { {0x23, L"#"}, {0x25, L"%"}, {0x26, L"&"}, {0xc5, L"AA"}, {0xc6, L"AE"}, {0x2370, L"APLboxquestion"}, {0x2353, L"APLboxupcaret"}, {0x2340, L"APLnotbackslash"}, {0x233f, L"APLnotslash"}, {0x391, L"Alpha"}, {0x26, L"And"}, {0x212b, L"Angstrom"}, {0x2ae7, L"Barv"}, {0x2102, L"BbbC"}, {0x213e, L"BbbGamma"}, {0x210d, L"BbbH"}, {0x2115, L"BbbN"}, {0x2119, L"BbbP"}, {0x213f, L"BbbPi"}, {0x211a, L"BbbQ"}, {0x211d, L"BbbR"}, {0x2124, L"BbbZ"}, {0x213d, L"Bbbgamma"}, {0x213c, L"Bbbpi"}, {0x2140, L"Bbbsum"}, {0x392, L"Beta"}, {0x224e, L"Bumpeq"}, {0x410, L"CYRA"}, {0x411, L"CYRB"}, {0x426, L"CYRC"}, {0x427, L"CYRCH"}, {0x414, L"CYRD"}, {0x415, L"CYRE"}, {0x42d, L"CYREREV"}, {0x42b, L"CYRERY"}, {0x424, L"CYRF"}, {0x413, L"CYRG"}, {0x425, L"CYRH"}, {0x42a, L"CYRHRDSN"}, {0x418, L"CYRI"}, {0x419, L"CYRISHRT"}, {0x41a, L"CYRK"}, {0x41b, L"CYRL"}, {0x41c, L"CYRM"}, {0x41d, L"CYRN"}, {0x41e, L"CYRO"}, {0x41f, L"CYRP"}, {0x420, L"CYRR"}, {0x421, L"CYRS"}, {0x42c, L"CYRSFTSN"}, {0x428, L"CYRSH"}, {0x429, L"CYRSHCH"}, {0x422, L"CYRT"}, {0x423, L"CYRU"}, {0x412, L"CYRV"}, {0x42f, L"CYRYA"}, {0x401, L"CYRYO"}, {0x42e, L"CYRYU"}, {0x417, L"CYRZ"}, {0x416, L"CYRZH"}, {0x22d2, L"Cap"}, {0x3a7, L"Chi"}, {0x2237, L"Colon"}, {0x2a74, L"Coloneq"}, {0x22d3, L"Cup"}, {0x27f1, L"DDownarrow"}, {0xd0, L"DH"}, {0x110, L"DJ"}, {0x2ae5, L"DashV"}, {0x27da, L"DashVDash"}, {0x2ae4, L"Dashv"}, {0x290b, L"Ddownarrow"}, {0x394, L"Delta"}, {0x3dc, L"Digamma"}, {0x2251, L"Doteq"}, {0x21d3, L"Downarrow"}, {0x395, L"Epsilon"}, {0x2263, L"Equiv"}, {0x397, L"Eta"}, {0x2107, L"Eulerconst"}, {0x203c, L"Exclam"}, {0x2132, L"Finv"}, {0x2141, L"Game"}, {0x393, L"Gamma"}, {0x2aa2, L"Gt"}, {0x26a5, L"Hermaphrodite"}, {0x2111, L"Im"}, {0x399, L"Iota"}, {0x39a, L"Kappa"}, {0x3de, L"Koppa"}, {0x141, L"L"}, {0x2b45, L"LLeftarrow"}, {0x39b, L"Lambda"}, {0x27ec, L"Lbrbrak"}, {0x21b2, L"Ldsh"}, {0x21d0, L"Leftarrow"}, {0x21d4, L"Leftrightarrow"}, {0x21da, L"Lleftarrow"}, {0x27f8, L"Longleftarrow"}, {0x27fa, L"Longleftrightarrow"}, {0x27fd, L"Longmapsfrom"}, {0x27fe, L"Longmapsto"}, {0x27f9, L"Longrightarrow"}, {0x2995, L"Lparengtr"}, {0x21b0, L"Lsh"}, {0x2aa1, L"Lt"}, {0x29da, L"Lvzigzag"}, {0x2906, L"Mapsfrom"}, {0x2907, L"Mapsto"}, {0x39c, L"Mu"}, {0x14a, L"NG"}, {0x21d7, L"Nearrow"}, {0x2aec, L"Not"}, {0x39d, L"Nu"}, {0x21d6, L"Nwarrow"}, {0xd8, L"O"}, {0x152, L"OE"}, {0x1a0, L"Ohorn"}, {0x3a9, L"Omega"}, {0x39f, L"Omicron"}, {0x2a37, L"Otimes"}, {0xb6, L"P"}, {0x3a6, L"Phi"}, {0x3a0, L"Pi"}, {0x210e, L"Planckconst"}, {0x2abb, L"Prec"}, {0x214a, L"PropertyLine"}, {0x3a8, L"Psi"}, {0x220e, L"QED"}, {0x2047, L"Question"}, {0x2b46, L"RRightarrow"}, {0x27ed, L"Rbrbrak"}, {0x21b3, L"Rdsh"}, {0x211c, L"Re"}, {0x3a1, L"Rho"}, {0x21d2, L"Rightarrow"}, {0x2996, L"Rparenless"}, {0x21db, L"Rrightarrow"}, {0x21b1, L"Rsh"}, {0x29db, L"Rvzigzag"}, {0xa7, L"S"}, {0x2abc, L"Sc"}, {0x21d8, L"Searrow"}, {0x3a3, L"Sigma"}, {0x2a4e, L"Sqcap"}, {0x2a4f, L"Sqcup"}, {0x3da, L"Stigma"}, {0x22d0, L"Subset"}, {0x22d1, L"Supset"}, {0x21d9, L"Swarrow"}, {0xde, L"TH"}, {0x3a4, L"Tau"}, {0x398, L"Theta"}, {0x27f0, L"UUparrow"}, {0x1af, L"Uhorn"}, {0x21d1, L"Uparrow"}, {0x21d5, L"Updownarrow"}, {0x290a, L"Uuparrow"}, {0x22ab, L"VDash"}, {0x2aeb, L"Vbar"}, {0x22a9, L"Vdash"}, {0x2a54, L"Vee"}, {0x2016, L"Vert"}, {0x22aa, L"Vvdash"}, {0x2980, L"Vvert"}, {0x2a53, L"Wedge"}, {0x2612, L"XBox"}, {0x39e, L"Xi"}, {0x2144, L"Yup"}, {0x1b5, L"Zbar"}, {0x396, L"Zeta"}, {0x5e, L"^"}, {0xe5, L"aa"}, {0x223e, L"ac"}, {0x23e6, L"accurrent"}, {0x267e, L"acidfree"}, {0x2940, L"acwcirclearrow"}, {0x27f2, L"acwgapcirclearrow"}, {0x2939, L"acwleftarcarrow"}, {0x21ba, L"acwopencirclearrow"}, {0x293a, L"acwoverarcarrow"}, {0x293b, L"acwundercurvearrow"}, {0x22f0, L"adots"}, {0xe6, L"ae"}, {0x2135, L"aleph"}, {0x3b1, L"alpha"}, // {0x2210, L"amalg"}, {0x2a3f, L"amalg"}, {0x299f, L"angdnr"}, {0x2220, L"angle"}, {0x299e, L"angles"}, {0x29a4, L"angleubar"}, {0x2248, L"approx"}, {0x224a, L"approxeq"}, {0x2a70, L"approxeqq"}, {0x224b, L"approxident"}, {0x2258, L"arceq"}, {0x2648, L"aries"}, {0x22a6, L"assert"}, {0x2217, L"ast"}, {0x2a6e, L"asteq"}, {0x2609, L"astrosun"}, {0x224d, L"asymp"}, {0x2a11, L"awint"}, {0x2aed, L"bNot"}, {0x224c, L"backcong"}, {0x2036, L"backdprime"}, {0x3f6, L"backepsilon"}, {0x2035, L"backprime"}, {0x223d, L"backsim"}, {0x22cd, L"backsimeq"}, {0x5c, L"backslash"}, {0x2037, L"backtrprime"}, {0x22ff, L"bagmember"}, {0x2aea, L"barV"}, {0x2a43, L"barcap"}, {0x2a42, L"barcup"}, {0x2961, L"bardownharpoonleft"}, {0x295d, L"bardownharpoonright"}, {0x21e4, L"barleftarrow"}, {0x21b9, L"barleftarrowrightarrowbar"}, {0x2956, L"barleftharpoondown"}, {0x2952, L"barleftharpoonup"}, {0x21b8, L"barovernorthwestarrow"}, {0x2920, L"barrightarrowdiamond"}, {0x295f, L"barrightharpoondown"}, {0x295b, L"barrightharpoonup"}, {0x2912, L"baruparrow"}, {0x2958, L"barupharpoonleft"}, {0x2954, L"barupharpoonright"}, {0x22bd, L"barvee"}, {0x22bc, L"barwedge"}, {0x23b6, L"bbrktbrk"}, {0x2550, L"bdHrule"}, {0x2551, L"bdVrule"}, {0x256c, L"bdbVbH"}, {0x256b, L"bdbVbh"}, {0x2563, L"bdbVlH"}, {0x2562, L"bdbVlh"}, {0x2560, L"bdbVrH"}, {0x255f, L"bdbVrh"}, {0x256a, L"bdbvbH"}, {0x253c, L"bdbvbh"}, {0x2561, L"bdbvlH"}, {0x2524, L"bdbvlh"}, {0x255e, L"bdbvrH"}, {0x251c, L"bdbvrh"}, {0x2566, L"bddVbH"}, {0x2565, L"bddVbh"}, {0x2557, L"bddVlH"}, {0x2556, L"bddVlh"}, {0x2554, L"bddVrH"}, {0x2553, L"bddVrh"}, {0x2564, L"bddvbH"}, {0x252c, L"bddvbh"}, {0x2555, L"bddvlH"}, {0x2510, L"bddvlh"}, {0x2552, L"bddvrH"}, {0x250c, L"bddvrh"}, {0x2500, L"bdhrule"}, {0x2571, L"bdnesw"}, {0x2572, L"bdnwse"}, {0x2508, L"bdquadhdash"}, {0x250a, L"bdquadvdash"}, {0x2506, L"bdtriplevdash"}, {0x2569, L"bduVbH"}, {0x2568, L"bduVbh"}, {0x255d, L"bduVlH"}, {0x255c, L"bduVlh"}, {0x255a, L"bduVrH"}, {0x2559, L"bduVrh"}, {0x2567, L"bduvbH"}, {0x2534, L"bduvbh"}, {0x255b, L"bduvlH"}, {0x2518, L"bduvlh"}, {0x2558, L"bduvrH"}, {0x2514, L"bduvrh"}, {0x2502, L"bdvrule"}, {0x2235, L"because"}, {0x23e3, L"benzenr"}, {0x3b2, L"beta"}, {0x2136, L"beth"}, {0x226c, L"between"}, {0x25bc, L"bigblacktriangledown"}, {0x25b2, L"bigblacktriangleup"}, {0x27d8, L"bigbot"}, {0x22c2, L"bigcap"}, {0x22c3, L"bigcup"}, {0x2a57, L"bigslopedvee"}, {0x2a58, L"bigslopedwedge"}, {0x2605, L"bigstar"}, {0x27d9, L"bigtop"}, {0x25bd, L"bigtriangledown"}, {0x25b3, L"bigtriangleup"}, {0x22c1, L"bigvee"}, {0x22c0, L"bigwedge"}, {0x2606, L"bigwhitestar"}, {0x29ed, L"blackcircledownarrow"}, {0x2688, L"blackcircledrightdot"}, {0x2791, L"blackcircledsanseight"}, {0x278e, L"blackcircledsansfive"}, {0x278d, L"blackcircledsansfour"}, {0x2792, L"blackcircledsansnine"}, {0x278a, L"blackcircledsansone"}, {0x2790, L"blackcircledsansseven"}, {0x278f, L"blackcircledsanssix"}, {0x2793, L"blackcircledsansten"}, {0x278c, L"blackcircledsansthree"}, {0x278b, L"blackcircledsanstwo"}, {0x2689, L"blackcircledtwodots"}, {0x25d5, L"blackcircleulquadwhite"}, {0x29ea, L"blackdiamonddownarrow"}, {0x29d7, L"blackhourglass"}, {0x25c8, L"blackinwhitediamond"}, {0x25a3, L"blackinwhitesquare"}, {0x25d6, L"blacklefthalfcircle"}, {0x25c4, L"blackpointerleft"}, {0x25ba, L"blackpointerright"}, {0x25d7, L"blackrighthalfcircle"}, {0x263b, L"blacksmiley"}, {0x25b4, L"blacktriangle"}, {0x25be, L"blacktriangledown"}, {0x25c0, L"blacktriangleleft"}, {0x25b6, L"blacktriangleright"}, {0x2b2c, L"blkhorzoval"}, {0x2b2e, L"blkvertoval"}, {0x2588, L"blockfull"}, {0x2592, L"blockhalfshaded"}, {0x258c, L"blocklefthalf"}, {0x2584, L"blocklowhalf"}, {0x2591, L"blockqtrshaded"}, {0x2590, L"blockrighthalf"}, {0x2593, L"blockthreeqtrshaded"}, {0x2580, L"blockuphalf"}, {0x22a5, L"bot"}, {0x25e1, L"botsemicircle"}, {0x22c8, L"bowtie"}, {0x25fb, L"box"}, {0x29c6, L"boxast"}, {0x25eb, L"boxbar"}, {0x29c8, L"boxbox"}, {0x29c5, L"boxbslash"}, {0x29c7, L"boxcircle"}, {0x29c4, L"boxdiag"}, {0x22a1, L"boxdot"}, {0x229f, L"boxminus"}, {0x29c9, L"boxonbox"}, {0x229e, L"boxplus"}, {0x22a0, L"boxtimes"}, {0x2b41, L"bsimilarleftarrow"}, {0x2b47, L"bsimilarrightarrow"}, {0x27c8, L"bsolhsub"}, {0x2a32, L"btimes"}, {0x2219, L"bullet"}, {0x25ce, L"bullseye"}, {0x224f, L"bumpeq"}, {0x2aae, L"bumpeqq"}, {0x212c, L"calB"}, {0x2130, L"calE"}, {0x2131, L"calF"}, {0x210b, L"calH"}, {0x2110, L"calI"}, {0x2112, L"calL"}, {0x2133, L"calM"}, {0x211b, L"calR"}, {0x2229, L"cap"}, {0x2a40, L"capdot"}, {0x2a44, L"capwedge"}, {0x2038, L"caretinsert"}, {0x23ce, L"carreturn"}, {0x21b5, L"carriagereturn"}, {0x293f, L"ccwundercurvearrow"}, {0x22c5, L"cdot"}, {0xb7, L"cdotp"}, {0x22ef, L"cdots"}, {0x2ba, L"cdprime"}, {0x2713, L"checkmark"}, {0x3c7, L"chi"}, {0x29c3, L"cirE"}, {0x27df, L"cirbot"}, {0x2218, L"circ"}, {0x2257, L"circeq"}, {0x2a10, L"circfint"}, {0x25d2, L"circlebottomhalfblack"}, {0x24b6, L"circledA"}, {0x24b7, L"circledB"}, {0x24b8, L"circledC"}, {0x24b9, L"circledD"}, {0x24ba, L"circledE"}, {0x24bb, L"circledF"}, {0x24bc, L"circledG"}, {0x24bd, L"circledH"}, {0x24be, L"circledI"}, {0x24bf, L"circledJ"}, {0x24c0, L"circledK"}, {0x24c1, L"circledL"}, {0x24c2, L"circledM"}, {0x24c3, L"circledN"}, {0x24c4, L"circledO"}, {0x24c5, L"circledP"}, {0x24c6, L"circledQ"}, {0x24c7, L"circledR"}, {0x24c8, L"circledS"}, {0x24c9, L"circledT"}, {0x24ca, L"circledU"}, {0x24cb, L"circledV"}, {0x24cc, L"circledW"}, {0x24cd, L"circledX"}, {0x24ce, L"circledY"}, {0x24cf, L"circledZ"}, {0x24d0, L"circleda"}, {0x229b, L"circledast"}, {0x24d1, L"circledb"}, {0x29bf, L"circledbullet"}, {0x24d2, L"circledc"}, {0x229a, L"circledcirc"}, {0x24d3, L"circledd"}, {0x229d, L"circleddash"}, {0x24d4, L"circlede"}, {0x2467, L"circledeight"}, {0x229c, L"circledequal"}, {0x24d5, L"circledf"}, {0x2464, L"circledfive"}, {0x2463, L"circledfour"}, {0x24d6, L"circledg"}, {0x24d7, L"circledh"}, {0x24d8, L"circledi"}, {0x24d9, L"circledj"}, {0x24da, L"circledk"}, {0x24db, L"circledl"}, {0x24dc, L"circledm"}, {0x24dd, L"circledn"}, {0x2468, L"circlednine"}, {0x24de, L"circledo"}, {0x2460, L"circledone"}, {0x29ec, L"circledownarrow"}, {0x24df, L"circledp"}, {0x29b7, L"circledparallel"}, {0x24e0, L"circledq"}, {0x24e1, L"circledr"}, {0x2686, L"circledrightdot"}, {0x24e2, L"circleds"}, {0x2787, L"circledsanseight"}, {0x2784, L"circledsansfive"}, {0x2783, L"circledsansfour"}, {0x2788, L"circledsansnine"}, {0x2780, L"circledsansone"}, {0x2786, L"circledsansseven"}, {0x2785, L"circledsanssix"}, {0x2789, L"circledsansten"}, {0x2782, L"circledsansthree"}, {0x2781, L"circledsanstwo"}, {0x2466, L"circledseven"}, {0x2465, L"circledsix"}, {0x272a, L"circledstar"}, {0x24e3, L"circledt"}, {0x2462, L"circledthree"}, {0x2461, L"circledtwo"}, {0x2687, L"circledtwodots"}, {0x24e4, L"circledu"}, {0x24e5, L"circledv"}, {0x29b6, L"circledvert"}, {0x24e6, L"circledw"}, {0x29be, L"circledwhitebullet"}, {0x24e7, L"circledx"}, {0x24e8, L"circledy"}, {0x24e9, L"circledz"}, {0x24ea, L"circledzero"}, {0x29b5, L"circlehbar"}, {0x25d0, L"circlelefthalfblack"}, {0x25f5, L"circlellquad"}, {0x25f6, L"circlelrquad"}, {0x2b30, L"circleonleftarrow"}, {0x21f4, L"circleonrightarrow"}, {0x25d1, L"circlerighthalfblack"}, {0x25d3, L"circletophalfblack"}, {0x25f4, L"circleulquad"}, {0x25f7, L"circleurquad"}, {0x25d4, L"circleurquadblack"}, {0x25cd, L"circlevertfill"}, {0x2aef, L"cirmid"}, {0x29c2, L"cirscir"}, {0x2329, L"clangle"}, {0x2a4d, L"closedvarcap"}, {0x2a4c, L"closedvarcup"}, {0x2a50, L"closedvarcupsmashprod"}, {0x2050, L"closure"}, {0x2318, L"cloverleaf"}, {0x2663, L"clubsuit"}, {0x3a, L"colon"}, {0x2236, L"colon"}, {0x2254, L"coloneq"}, {0x2a29, L"commaminus"}, {0x2201, L"complement"}, {0x27e1, L"concavediamond"}, {0x27e2, L"concavediamondtickleft"}, {0x27e3, L"concavediamondtickright"}, {0x2245, L"cong"}, {0x2a6d, L"congdot"}, {0x2332, L"conictaper"}, {0x260c, L"conjunction"}, {0x2210, L"coprod"}, {0x2b9, L"cprime"}, {0x232a, L"crangle"}, {0x2acf, L"csub"}, {0x2ad1, L"csube"}, {0x2ad0, L"csup"}, {0x2ad2, L"csupe"}, {0x221b, L"cuberoot"}, {0x222a, L"cup"}, {0x228d, L"cupdot"}, {0x228c, L"cupleftarrow"}, {0x2a45, L"cupvee"}, {0x22de, L"curlyeqprec"}, {0x22df, L"curlyeqsucc"}, {0x22ce, L"curlyvee"}, {0x22cf, L"curlywedge"}, {0x21b6, L"curvearrowleft"}, {0x293d, L"curvearrowleftplus"}, {0x21b7, L"curvearrowright"}, {0x293c, L"curvearrowrightminus"}, {0x2941, L"cwcirclearrow"}, {0x27f3, L"cwgapcirclearrow"}, {0x21bb, L"cwopencirclearrow"}, {0x2938, L"cwrightarcarrow"}, {0x293e, L"cwundercurvearrow"}, {0x232d, L"cylcty"}, {0x430, L"cyra"}, {0x431, L"cyrb"}, {0x446, L"cyrc"}, {0x447, L"cyrch"}, {0x434, L"cyrd"}, {0x435, L"cyre"}, {0x44d, L"cyrerev"}, {0x44b, L"cyrery"}, {0x444, L"cyrf"}, {0x433, L"cyrg"}, {0x445, L"cyrh"}, {0x44a, L"cyrhrdsn"}, {0x438, L"cyri"}, {0x439, L"cyrishrt"}, {0x43a, L"cyrk"}, {0x43b, L"cyrl"}, {0x43c, L"cyrm"}, {0x43d, L"cyrn"}, {0x43e, L"cyro"}, {0x43f, L"cyrp"}, {0x440, L"cyrr"}, {0x441, L"cyrs"}, {0x44c, L"cyrsftsn"}, {0x448, L"cyrsh"}, {0x449, L"cyrshch"}, {0x442, L"cyrt"}, {0x443, L"cyru"}, {0x432, L"cyrv"}, {0x44f, L"cyrya"}, {0x451, L"cyryo"}, {0x44e, L"cyryu"}, {0x437, L"cyrz"}, {0x436, L"cyrzh"}, {0x2020, L"dag"}, {0x2020, L"dagger"}, {0x2138, L"daleth"}, {0x2621, L"danger"}, {0x2ae3, L"dashV"}, {0x27db, L"dashVdash"}, {0x2239, L"dashcolon"}, {0x296b, L"dashleftharpoondown"}, {0x296d, L"dashrightharpoondown"}, {0x22a3, L"dashv"}, {0x290f, L"dbkarow"}, {0x2021, L"ddag"}, {0x2021, L"ddagger"}, {0x22f1, L"ddots"}, {0x2a77, L"ddotseq"}, {0xb0, L"degree"}, {0x3b4, L"delta"}, {0xf0, L"dh"}, {0x2300, L"diameter"}, {0x25c7, L"diamond"}, {0x2b19, L"diamondbotblack"}, {0x27d0, L"diamondcdot"}, {0x291d, L"diamondleftarrow"}, {0x291f, L"diamondleftarrowbar"}, {0x2b16, L"diamondleftblack"}, {0x2b17, L"diamondrightblack"}, {0x2662, L"diamondsuit"}, {0x2b18, L"diamondtopblack"}, {0x2680, L"dicei"}, {0x2681, L"diceii"}, {0x2682, L"diceiii"}, {0x2683, L"diceiv"}, {0x2684, L"dicev"}, {0x2685, L"dicevi"}, {0x3dd, L"digamma"}, {0x273d, L"dingasterisk"}, {0x2393, L"dircurrent"}, {0x22f2, L"disin"}, {0xf7, L"div"}, {0x22c7, L"divideontimes"}, {0x111, L"dj"}, {0x230d, L"dlcrop"}, {0x2250, L"doteq"}, {0x2a67, L"dotequiv"}, {0x2238, L"dotminus"}, {0x2214, L"dotplus"}, {0x2026, L"dots"}, {0x2a6a, L"dotsim"}, {0x223a, L"dotsminusdots"}, {0x25cc, L"dottedcircle"}, {0x2b1a, L"dottedsquare"}, {0x2a30, L"dottimes"}, {0x2a62, L"doublebarvee"}, {0x2a5e, L"doublebarwedge"}, {0x29fa, L"doubleplus"}, {0x2193, L"downarrow"}, {0x2913, L"downarrowbar"}, {0x2908, L"downarrowbarred"}, {0x21e3, L"downdasharrow"}, {0x21ca, L"downdownarrows"}, {0x297f, L"downfishtail"}, {0x21c3, L"downharpoonleft"}, {0x2959, L"downharpoonleftbar"}, {0x21c2, L"downharpoonright"}, {0x2955, L"downharpoonrightbar"}, {0x2965, L"downharpoonsleftright"}, {0x2935, L"downrightcurvedarrow"}, {0x29e8, L"downtriangleleftblack"}, {0x29e9, L"downtrianglerightblack"}, {0x21f5, L"downuparrows"}, {0x296f, L"downupharpoonsleftright"}, {0x21e9, L"downwhitearrow"}, {0x21af, L"downzigzagarrow"}, {0x2033, L"dprime"}, {0x279b, L"draftingarrow"}, {0x2910, L"drbkarow"}, {0x230c, L"drcrop"}, {0x29f6, L"dsol"}, {0x2a64, L"dsub"}, {0x29df, L"dualmap"}, {0x2641, L"earth"}, {0x2a98, L"egsdot"}, {0x266a, L"eighthnote"}, {0x23e7, L"elinters"}, {0x2113, L"ell"}, {0x2a97, L"elsdot"}, {0x2014, L"emdash"}, {0x2205, L"emptyset"}, {0x29b3, L"emptysetoarr"}, {0x29b4, L"emptysetoarrl"}, {0x29b1, L"emptysetobar"}, {0x29b2, L"emptysetocirc"}, {0x2013, L"endash"}, {0x2025, L"enleadertwodots"}, {0x2709, L"envelope"}, {0x29e3, L"eparsl"}, {0x3f5, L"epsilon"}, {0x2256, L"eqcirc"}, {0x2255, L"eqcolon"}, {0x225d, L"eqdef"}, {0x2a66, L"eqdot"}, {0x2a75, L"eqeq"}, {0x2a76, L"eqeqeq"}, {0x22dd, L"eqgtr"}, {0x22dc, L"eqless"}, {0x2a9a, L"eqqgtr"}, {0x2a99, L"eqqless"}, {0x2a71, L"eqqplus"}, {0x2a73, L"eqqsim"}, {0x2a9c, L"eqqslantgtr"}, {0x2a9b, L"eqqslantless"}, {0x2242, L"eqsim"}, {0x2a96, L"eqslantgtr"}, {0x2a95, L"eqslantless"}, {0x2b40, L"equalleftarrow"}, {0x22d5, L"equalparallel"}, {0x2971, L"equalrightarrow"}, {0x2261, L"equiv"}, {0x2a78, L"equivDD"}, {0x2a68, L"equivVert"}, {0x2a69, L"equivVvert"}, {0x29e5, L"eqvparsl"}, {0x29f3, L"errbarblackcircle"}, {0x29f1, L"errbarblackdiamond"}, {0x29ef, L"errbarblacksquare"}, {0x29f2, L"errbarcircle"}, {0x29f0, L"errbardiamond"}, {0x29ee, L"errbarsquare"}, {0x3b7, L"eta"}, {0x20ac, L"euro"}, {0x2203, L"exists"}, {0x2252, L"fallingdotseq"}, {0x29d3, L"fbowtie"}, {0x2a3e, L"fcmp"}, {0x292f, L"fdiagovnearrow"}, {0x292c, L"fdiagovrdiag"}, {0x2640, L"female"}, {0x2012, L"figdash"}, {0x2a0f, L"fint"}, {0x25c9, L"fisheye"}, {0x266d, L"flat"}, {0x23e5, L"fltns"}, {0x2200, L"forall"}, {0x2adc, L"forks"}, {0x2add, L"forksnot"}, {0x2ad9, L"forkv"}, {0x221c, L"fourthroot"}, {0x2999, L"fourvdots"}, {0x215d, L"fracfiveeighths"}, {0x215a, L"fracfivesixths"}, {0x2158, L"fracfourfifths"}, {0x215b, L"fraconeeighth"}, {0x2155, L"fraconefifth"}, {0x2159, L"fraconesixth"}, {0x2153, L"fraconethird"}, {0x215e, L"fracseveneights"}, {0x2044, L"fracslash"}, {0x215c, L"fracthreeeighths"}, {0x2157, L"fracthreefifths"}, {0x2156, L"fractwofifths"}, {0x2154, L"fractwothirds"}, {0x212d, L"frakC"}, {0x210c, L"frakH"}, {0x2128, L"frakZ"}, {0x2322, L"frown"}, {0x2639, L"frownie"}, {0x27d7, L"fullouterjoin"}, {0x3b3, L"gamma"}, {0x2265, L"ge"}, {0x2265, L"geq"}, {0x2267, L"geqq"}, {0x2a7e, L"geqslant"}, {0x2aa9, L"gescc"}, {0x2a80, L"gesdot"}, {0x2a82, L"gesdoto"}, {0x2a84, L"gesdotol"}, {0x2a94, L"gesles"}, {0x2190, L"gets"}, {0x226b, L"gg"}, {0x22d9, L"ggg"}, {0x2af8, L"gggnest"}, {0x2137, L"gimel"}, {0x2a92, L"glE"}, {0x2aa5, L"gla"}, {0x29e6, L"gleichstark"}, {0x2aa4, L"glj"}, {0x2a8a, L"gnapprox"}, {0x2a88, L"gneq"}, {0x2269, L"gneqq"}, {0x22e7, L"gnsim"}, {0x3e, L"greater"}, {0x2a8e, L"gsime"}, {0x2a90, L"gsiml"}, {0x2aa7, L"gtcc"}, {0x2a7a, L"gtcir"}, {0x29a0, L"gtlpar"}, {0x2a7c, L"gtquest"}, {0x2a86, L"gtrapprox"}, {0x2978, L"gtrarr"}, {0x22d7, L"gtrdot"}, {0x22db, L"gtreqless"}, {0x2a8c, L"gtreqqless"}, {0x2277, L"gtrless"}, {0x2273, L"gtrsim"}, {0xab, L"guillemotleft"}, {0xbb, L"guillemotright"}, {0x2039, L"guilsinglleft"}, {0x203a, L"guilsinglright"}, {0x23af, L"harrowextender"}, {0x2a6f, L"hatapprox"}, {0x210f, L"hbar"}, {0x2661, L"heartsuit"}, {0x22b9, L"hermitmatrix"}, {0x2394, L"hexagon"}, {0x2b23, L"hexagonblack"}, {0x306e, L"hiraganano"}, {0x2924, L"hknearrow"}, {0x2923, L"hknwarrow"}, {0x2925, L"hksearow"}, {0x2926, L"hkswarow"}, {0x21a9, L"hookleftarrow"}, {0x21aa, L"hookrightarrow"}, {0x2015, L"horizbar"}, {0x29d6, L"hourglass"}, {0x2302, L"house"}, {0x25ad, L"hrectangle"}, {0x25ac, L"hrectangleblack"}, {0x210f, L"hslash"}, {0x2043, L"hyphenbullet"}, {0x3030, L"hzigzag"}, {0x2a0c, L"iiiint"}, {0x222d, L"iiint"}, {0x29dc, L"iinfin"}, {0x222c, L"iint"}, {0x22b7, L"imageof"}, {0x2208, L"in"}, {0x2105, L"incare"}, {0x2206, L"increment"}, {0x221e, L"infty"}, {0x222b, L"int"}, {0x2a0e, L"intBar"}, {0x2a0d, L"intbar"}, {0x2321, L"intbottom"}, {0x2a19, L"intcap"}, {0x2231, L"intclockwise"}, {0x2a1a, L"intcup"}, {0x22ba, L"intercal"}, {0x2af4, L"interleave"}, {0x23ae, L"intextender"}, {0x2a17, L"intlharhk"}, {0x2a3c, L"intprod"}, {0x2a3d, L"intprodr"}, {0x2320, L"inttop"}, {0x2a18, L"intx"}, {0x25d8, L"inversebullet"}, {0x25d9, L"inversewhitecircle"}, {0x2310, L"invnot"}, {0x25db, L"invwhitelowerhalfcircle"}, {0x25da, L"invwhiteupperhalfcircle"}, {0x3b9, L"iota"}, {0x2e0, L"ipasupgamma"}, {0x2e1, L"ipasupl"}, {0x2e4, L"ipasuprerglotstpp"}, {0x2e2, L"ipasups"}, {0x2e3, L"ipasupx"}, {0x2ed, L"ipaunaspirated"}, {0x2ec, L"ipavoicing"}, {0x22f9, L"isinE"}, {0x22f5, L"isindot"}, {0x22f7, L"isinobar"}, {0x22f4, L"isins"}, {0x22f8, L"isinvb"}, {0x2145, L"itBbbD"}, {0x2146, L"itBbbd"}, {0x2147, L"itBbbe"}, {0x2148, L"itBbbi"}, {0x2149, L"itBbbj"}, {0x2643, L"jupiter"}, {0x3ba, L"kappa"}, {0x223b, L"kernelcontraction"}, {0x3df, L"koppa"}, {0x142, L"l"}, {0x27ea, L"lAngle"}, {0x2983, L"lBrace"}, {0x27e6, L"lBrack"}, {0x2985, L"lParen"}, {0x3bb, L"lambda"}, {0x19b, L"lambdabar"}, {0x27e8, L"langle"}, {0x2991, L"langledot"}, {0x29e0, L"laplac"}, {0x2bd, L"lasp"}, {0x2aab, L"lat"}, {0x2aad, L"late"}, {0x27c5, L"lbag"}, {0x2997, L"lblkbrbrak"}, {0x7b, L"lbrace"}, {0x23a9, L"lbracelend"}, {0x23a8, L"lbracemid"}, {0x23a7, L"lbraceuend"}, {0x5b, L"lbrack"}, {0x23a2, L"lbrackextender"}, {0x23a3, L"lbracklend"}, {0x298f, L"lbracklltick"}, {0x298b, L"lbrackubar"}, {0x23a1, L"lbrackuend"}, {0x298d, L"lbrackultick"}, {0x2772, L"lbrbrak"}, {0x2308, L"lceil"}, {0x29fc, L"lcurvyangle"}, {0x21e0, L"ldasharrhead"}, {0x2264, L"le"}, {0x219d, L"leadsto"}, {0x2190, L"leftarrow"}, {0x2b4a, L"leftarrowapprox"}, {0x2b42, L"leftarrowbackapprox"}, {0x2b4b, L"leftarrowbsimilar"}, {0x2977, L"leftarrowless"}, {0x2b32, L"leftarrowonoplus"}, {0x2946, L"leftarrowplus"}, {0x2943, L"leftarrowshortrightarrow"}, {0x2973, L"leftarrowsimilar"}, {0x297a, L"leftarrowsubset"}, {0x21a2, L"leftarrowtail"}, {0x21fd, L"leftarrowtriangle"}, {0x2b3e, L"leftarrowx"}, {0x290c, L"leftbkarrow"}, {0x2b3f, L"leftcurvedarrow"}, {0x21e0, L"leftdasharrow"}, {0x21e1, L"leftdasharrowhead"}, {0x290e, L"leftdbkarrow"}, {0x291b, L"leftdbltail"}, {0x2b38, L"leftdotarrow"}, {0x2936, L"leftdowncurvedarrow"}, {0x297c, L"leftfishtail"}, {0x21bd, L"leftharpoondown"}, {0x295e, L"leftharpoondownbar"}, {0x2962, L"leftharpoonsupdown"}, {0x21bc, L"leftharpoonup"}, {0x295a, L"leftharpoonupbar"}, {0x296a, L"leftharpoonupdash"}, {0x21c7, L"leftleftarrows"}, {0x263e, L"leftmoon"}, {0x27d5, L"leftouterjoin"}, {0x2194, L"leftrightarrow"}, {0x2948, L"leftrightarrowcircle"}, {0x21c6, L"leftrightarrows"}, {0x21ff, L"leftrightarrowtriangle"}, {0x2950, L"leftrightharpoondowndown"}, {0x294b, L"leftrightharpoondownup"}, {0x21cb, L"leftrightharpoons"}, {0x2967, L"leftrightharpoonsdown"}, {0x2966, L"leftrightharpoonsup"}, {0x294a, L"leftrightharpoonupdown"}, {0x294e, L"leftrightharpoonupup"}, {0x21ad, L"leftrightsquigarrow"}, {0x219c, L"leftsquigarrow"}, {0x21dc, L"leftsquigarrow"}, {0x2919, L"lefttail"}, {0x2b31, L"leftthreearrows"}, {0x22cb, L"leftthreetimes"}, {0x21e6, L"leftwhitearrow"}, {0x2264, L"leq"}, {0x2266, L"leqq"}, {0x2af9, L"leqqslant"}, {0x2afa, L"leqqslant"}, {0x2a7d, L"leqslant"}, {0x2aa8, L"lescc"}, {0x2a7f, L"lesdot"}, {0x2a81, L"lesdoto"}, {0x2a83, L"lesdotor"}, {0x2a93, L"lesges"}, {0x3c, L"less"}, {0x2a85, L"lessapprox"}, {0x22d6, L"lessdot"}, {0x22da, L"lesseqgtr"}, {0x2a8b, L"lesseqqgtr"}, {0x2276, L"lessgtr"}, {0x2272, L"lesssim"}, {0x29d1, L"lfbowtie"}, {0x230a, L"lfloor"}, {0x29d4, L"lftimes"}, {0x2a91, L"lgE"}, {0x2b24, L"lgblkcircle"}, {0x2b1b, L"lgblksquare"}, {0x25ef, L"lgwhtcircle"}, {0x2b1c, L"lgwhtsquare"}, {0x22b2, L"lhd"}, {0x21b4, L"linefeed"}, {0x226a, L"ll"}, {0x2989, L"llangle"}, {0x25df, L"llarc"}, {0x25e3, L"llblacktriangle"}, {0x231e, L"llcorner"}, {0x22d8, L"lll"}, {0x2af7, L"lllnest"}, {0x2987, L"llparenthesis"}, {0x25fa, L"lltriangle"}, {0x23b0, L"lmoustache"}, {0x2a89, L"lnapprox"}, {0x2a87, L"lneq"}, {0x2268, L"lneqq"}, {0x22e6, L"lnsim"}, {0x27de, L"longdashv"}, {0x27cc, L"longdivision"}, {0x27f5, L"longleftarrow"}, {0x27f7, L"longleftrightarrow"}, {0x2b33, L"longleftsquigarrow"}, {0x27fb, L"longmapsfrom"}, {0x27fc, L"longmapsto"}, {0x27f6, L"longrightarrow"}, {0x27ff, L"longrightsquigarrow"}, {0x21ab, L"looparrowleft"}, {0x21ac, L"looparrowright"}, {0x2a1c, L"lowint"}, {0x25ca, L"lozenge"}, {0x27e0, L"lozengeminus"}, {0x239c, L"lparenextender"}, {0x239d, L"lparenlend"}, {0x2993, L"lparenless"}, {0x239b, L"lparenuend"}, {0x2018, L"lq"}, {0x25de, L"lrarc"}, {0x25e2, L"lrblacktriangle"}, {0x231f, L"lrcorner"}, {0x25ff, L"lrtriangle"}, {0x29e1, L"lrtriangleeq"}, {0x2a8d, L"lsime"}, {0x2a8f, L"lsimg"}, {0x2acd, L"lsqhook"}, {0x2aa6, L"ltcc"}, {0x2a79, L"ltcir"}, {0x22c9, L"ltimes"}, {0x2976, L"ltlarr"}, {0x2a7b, L"ltquest"}, {0x29cf, L"ltrivb"}, {0x23b8, L"lvboxline"}, {0x29d8, L"lvzigzag"}, {0x2642, L"male"}, {0x2720, L"maltese"}, {0x21a7, L"mapsdown"}, {0x21a4, L"mapsfrom"}, {0x21a6, L"mapsto"}, {0x21a5, L"mapsup"}, {0x2b25, L"mdblkdiamond"}, {0x2b27, L"mdblklozenge"}, {0x26ab, L"mdblkrcl"}, {0x25fc, L"mdblksquare"}, {0x25cf, L"mdlgblkcircle"}, {0x25c6, L"mdlgblkdiamond"}, {0x29eb, L"mdlgblklozenge"}, {0x25a0, L"mdlgblksquare"}, {0x25cb, L"mdlgwhtcircle"}, {0x25c7, L"mdlgwhtdiamond"}, {0x25a1, L"mdlgwhtsquare"}, {0x2981, L"mdsmblkcircle"}, {0x25fe, L"mdsmblksquare"}, {0x26ac, L"mdsmwhtcircl"}, {0x25fd, L"mdsmwhtsquare"}, {0x26aa, L"mdwhtcircl"}, {0x2b26, L"mdwhtdiamond"}, {0x2b28, L"mdwhtlozenge"}, {0x25fb, L"mdwhtsquare"}, {0x29af, L"measangledltosw"}, {0x29ae, L"measangledrtose"}, {0x29ab, L"measangleldtosw"}, {0x29a9, L"measanglelutonw"}, {0x29aa, L"measanglerdtose"}, {0x29a8, L"measanglerutone"}, {0x29ad, L"measangleultonw"}, {0x29ac, L"measangleurtone"}, {0x225e, L"measeq"}, {0x2221, L"measuredangle"}, {0x299b, L"measuredangleleft"}, {0x22be, L"measuredrightangle"}, {0x2b51, L"medblackstar"}, {0x205f, L"medmathspace"}, {0x2b50, L"medwhitestar"}, {0x263f, L"mercury"}, {0x2127, L"mho"}, {0x2223, L"mid"}, {0x2a5d, L"midbarvee"}, {0x2a5c, L"midbarwedge"}, {0x2af0, L"midcir"}, {0x2212, L"minus"}, {0x2a2a, L"minusdot"}, {0x2a2b, L"minusfdots"}, {0x2a2c, L"minusrdots"}, {0x2adb, L"mlcp"}, {0x22a7, L"models"}, {0x2213, L"mp"}, {0x3bc, L"mu"}, {0x22b8, L"multimap"}, {0x27dc, L"multimapinv"}, {0x21df, L"nHdownarrow"}, {0x21de, L"nHuparrow"}, {0x21cd, L"nLeftarrow"}, {0x21ce, L"nLeftrightarrow"}, {0x21cf, L"nRightarrow"}, {0x22af, L"nVDash"}, {0x22ae, L"nVdash"}, {0x21fa, L"nVleftarrow"}, {0x2b3a, L"nVleftarrowtail"}, {0x21fc, L"nVleftrightarrow"}, {0x21fb, L"nVrightarrow"}, {0x2915, L"nVrightarrowtail"}, {0x2b35, L"nVtwoheadleftarrow"}, {0x2b3d, L"nVtwoheadleftarrowtail"}, {0x2901, L"nVtwoheadrightarrow"}, {0x2918, L"nVtwoheadrightarrowtail"}, {0x2207, L"nabla"}, {0x2249, L"napprox"}, {0x226d, L"nasymp"}, {0x266e, L"natural"}, {0x2247, L"ncong"}, {0x2260, L"ne"}, {0x2197, L"nearrow"}, {0xac, L"neg"}, {0x2931, L"neovnwarrow"}, {0x292e, L"neovsearrow"}, {0x2646, L"neptune"}, {0x2260, L"neq"}, {0x2262, L"nequiv"}, {0x2922, L"neswarrow"}, {0x26b2, L"neuter"}, {0x2204, L"nexists"}, {0x14b, L"ng"}, {0x2271, L"ngeq"}, {0x226f, L"ngtr"}, {0x2279, L"ngtrless"}, {0x2275, L"ngtrsim"}, {0x2af5, L"nhVvert"}, {0x2af2, L"nhpar"}, {0x220b, L"ni"}, {0x22fe, L"niobar"}, {0x22fc, L"nis"}, {0x22fa, L"nisd"}, {0x219a, L"nleftarrow"}, {0x21ae, L"nleftrightarrow"}, {0x2270, L"nleq"}, {0x226e, L"nless"}, {0x2278, L"nlessgtr"}, {0x2274, L"nlesssim"}, {0x2224, L"nmid"}, {0x220c, L"nni"}, {0x2011, L"nobreakhyphen"}, {0x2209, L"notin"}, {0x2226, L"nparallel"}, {0x2a14, L"npolint"}, {0x2280, L"nprec"}, {0x22e0, L"npreccurlyeq"}, {0x219b, L"nrightarrow"}, {0x2241, L"nsim"}, {0x2244, L"nsime"}, {0x22e2, L"nsqsubseteq"}, {0x22e3, L"nsqsupseteq"}, {0x2284, L"nsubset"}, {0x2288, L"nsubseteq"}, {0x2281, L"nsucc"}, {0x22e1, L"nsucccurlyeq"}, {0x2285, L"nsupset"}, {0x2289, L"nsupseteq"}, {0x22ea, L"ntriangleleft"}, {0x22ec, L"ntrianglelefteq"}, {0x22eb, L"ntriangleright"}, {0x22ed, L"ntrianglerighteq"}, {0x3bd, L"nu"}, {0x22ad, L"nvDash"}, {0x2902, L"nvLeftarrow"}, {0x2904, L"nvLeftrightarrow"}, {0x2903, L"nvRightarrow"}, {0x22ac, L"nvdash"}, {0x29de, L"nvinfty"}, {0x21f7, L"nvleftarrow"}, {0x2b39, L"nvleftarrowtail"}, {0x21f9, L"nvleftrightarrow"}, {0x21f8, L"nvrightarrow"}, {0x2914, L"nvrightarrowtail"}, {0x2b34, L"nvtwoheadleftarrow"}, {0x2b3c, L"nvtwoheadleftarrowtail"}, {0x2900, L"nvtwoheadrightarrow"}, {0x2917, L"nvtwoheadrightarrowtail"}, {0x2196, L"nwarrow"}, {0x2932, L"nwovnearrow"}, {0x2921, L"nwsearrow"}, {0xf8, L"o"}, {0x233d, L"obar"}, {0x29ba, L"obot"}, {0x23e0, L"obrbrak"}, {0x29b8, L"obslash"}, {0x2a38, L"odiv"}, {0x2299, L"odot"}, {0x29bc, L"odotslashdot"}, {0x153, L"oe"}, {0x29c1, L"ogreaterthan"}, {0x1a1, L"ohorn"}, {0x2230, L"oiiint"}, {0x222f, L"oiint"}, {0x222e, L"oint"}, {0x2233, L"ointctrclockwise"}, {0x29bb, L"olcross"}, {0x3d8, L"oldKoppa"}, {0x3d9, L"oldkoppa"}, {0x29c0, L"olessthan"}, {0x3c9, L"omega"}, {0x3bf, L"omicron"}, {0x2296, L"ominus"}, {0x29b9, L"operp"}, {0x2295, L"oplus"}, {0x2a2d, L"opluslhrim"}, {0x2a2e, L"oplusrhrim"}, {0x22b6, L"origof"}, {0x2298, L"oslash"}, {0x2297, L"otimes"}, {0x2a36, L"otimeshat"}, {0x2a34, L"otimeslhrim"}, {0x2a35, L"otimesrhrim"}, {0x23de, L"overbrace"}, {0x23b4, L"overbracket"}, {0x203e, L"overline"}, {0x23dc, L"overparen"}, {0x220b, L"owns"}, {0x2225, L"parallel"}, {0x25b1, L"parallelogram"}, {0x25b0, L"parallelogramblack"}, {0x2af3, L"parsim"}, {0x2202, L"partial"}, {0x2aa3, L"partialmeetcontraction"}, {0x2b20, L"pentagon"}, {0x2b1f, L"pentagonblack"}, {0x27c2, L"perp"}, {0x2ae1, L"perps"}, {0x3d5, L"phi"}, {0x260e, L"phone"}, {0x3c0, L"pi"}, {0x22d4, L"pitchfork"}, {0x2a25, L"plusdot"}, {0x2a72, L"pluseqq"}, {0x2a23, L"plushat"}, {0x2a26, L"plussim"}, {0x2a27, L"plussubtwo"}, {0x2a28, L"plustrif"}, {0x2647, L"pluto"}, {0xb1, L"pm"}, {0x2a15, L"pointnt"}, {0x3012, L"postalmark"}, {0x227a, L"prec"}, {0x2ab7, L"precapprox"}, {0x227c, L"preccurlyeq"}, {0x2aaf, L"preceq"}, {0x2ab3, L"preceqq"}, {0x2ab9, L"precnapprox"}, {0x2ab1, L"precneq"}, {0x2ab5, L"precneqq"}, {0x22e8, L"precnsim"}, {0x227e, L"precsim"}, {0x2032, L"prime"}, {0x220f, L"prod"}, {0x232e, L"profalar"}, {0x2312, L"profline"}, {0x2313, L"profsurf"}, {0x221d, L"propto"}, {0x22b0, L"prurel"}, {0x3c8, L"psi"}, {0x27d3, L"pullback"}, {0x27d4, L"pushout"}, {0x2057, L"qprime"}, {0x2669, L"quarternote"}, {0x225f, L"questeq"}, {0x201e, L"quotdblbase"}, {0x201f, L"quotdblright"}, {0x27, L"quote"}, {0x201a, L"quotsinglbase"}, {0x201b, L"quotsinglright"}, {0x27eb, L"rAngle"}, {0x2984, L"rBrace"}, {0x27e7, L"rBrack"}, {0x2986, L"rParen"}, {0x27e9, L"rangle"}, {0x2992, L"rangledot"}, {0x237c, L"rangledownzigzagarrow"}, {0x2bc, L"rasp"}, {0x27c6, L"rbag"}, {0x2998, L"rblkbrbrak"}, {0x7d, L"rbrace"}, {0x23ad, L"rbracelend"}, {0x23ac, L"rbracemid"}, {0x23ab, L"rbraceuend"}, {0x5d, L"rbrack"}, {0x23a5, L"rbrackextender"}, {0x23a6, L"rbracklend"}, {0x298e, L"rbracklrtick"}, {0x298c, L"rbrackubar"}, {0x23a4, L"rbrackuend"}, {0x2990, L"rbrackurtick"}, {0x2773, L"rbrbrak"}, {0x2309, L"rceil"}, {0x29fd, L"rcurvyangle"}, {0x292b, L"rdiagovfdiag"}, {0x2930, L"rdiagovsearrow"}, {0x2315, L"recorder"}, {0x29a3, L"revangle"}, {0x29a5, L"revangleubar"}, {0x29b0, L"revemptyset"}, {0x2aee, L"revnmid"}, {0x29d2, L"rfbowtie"}, {0x230b, L"rfloor"}, {0x29d5, L"rftimes"}, {0x22b3, L"rhd"}, {0x3c1, L"rho"}, {0x2b4c, L"righarrowbsimilar"}, {0x221f, L"rightangle"}, {0x299d, L"rightanglemdot"}, {0x299c, L"rightanglesqr"}, {0x2192, L"rightarrow"}, {0x2975, L"rightarrowapprox"}, {0x2b48, L"rightarrowbackapprox"}, {0x21e5, L"rightarrowbar"}, {0x291e, L"rightarrowdiamond"}, {0x2b43, L"rightarrowgtr"}, {0x27f4, L"rightarrowonoplus"}, {0x2945, L"rightarrowplus"}, {0x2942, L"rightarrowshortleftarrow"}, {0x2974, L"rightarrowsimilar"}, {0x2b44, L"rightarrowsupset"}, {0x21a3, L"rightarrowtail"}, {0x21fe, L"rightarrowtriangle"}, {0x2947, L"rightarrowx"}, {0x290d, L"rightbkarrow"}, {0x2933, L"rightcurvedarrow"}, {0x21e2, L"rightdasharrow"}, {0x291c, L"rightdbltail"}, {0x2911, L"rightdotarrow"}, {0x2937, L"rightdowncurvedarrow"}, {0x297d, L"rightfishtail"}, {0x21c1, L"rightharpoondown"}, {0x2957, L"rightharpoondownbar"}, {0x2964, L"rightharpoonsupdown"}, {0x21c0, L"rightharpoonup"}, {0x2953, L"rightharpoonupbar"}, {0x296c, L"rightharpoonupdash"}, {0x2970, L"rightimply"}, {0x21c4, L"rightleftarrows"}, {0x21cc, L"rightleftharpoons"}, {0x2969, L"rightleftharpoonsdown"}, {0x2968, L"rightleftharpoonsup"}, {0x263d, L"rightmoon"}, {0x27d6, L"rightouterjoin"}, {0x2b54, L"rightpentagon"}, {0x2b53, L"rightpentagonblack"}, {0x21c9, L"rightrightarrows"}, {0x219d, L"rightsquigarrow"}, {0x21dd, L"rightsquigarrow"}, {0x291a, L"righttail"}, {0x21f6, L"rightthreearrows"}, {0x22cc, L"rightthreetimes"}, {0x21e8, L"rightwhitearrow"}, {0x2a22, L"ringplus"}, {0x2253, L"risingdotseq"}, {0x23b1, L"rmoustache"}, {0x239f, L"rparenextender"}, {0x2994, L"rparengtr"}, {0x23a0, L"rparenlend"}, {0x239e, L"rparenuend"}, {0x2a12, L"rppolint"}, {0x2019, L"rq"}, {0x298a, L"rrangle"}, {0x2988, L"rrparenthesis"}, {0x29f7, L"rsolbar"}, {0x2ace, L"rsqhook"}, {0x2a65, L"rsub"}, {0x22ca, L"rtimes"}, {0x29ce, L"rtriltri"}, {0x29f4, L"ruledelayed"}, {0x23b9, L"rvboxline"}, {0x29d9, L"rvzigzag"}, {0x3e1, L"sampi"}, {0x2143, L"sansLmirrored"}, {0x2142, L"sansLturned"}, {0x2644, L"saturn"}, {0x2702, L"scissors"}, {0x2a13, L"scpolint"}, {0x212c, L"scrB"}, {0x2130, L"scrE"}, {0x2131, L"scrF"}, {0x210b, L"scrH"}, {0x2110, L"scrI"}, {0x2112, L"scrL"}, {0x2133, L"scrM"}, {0x211b, L"scrR"}, {0x212f, L"scre"}, {0x210a, L"scrg"}, {0x2134, L"scro"}, {0x22b1, L"scurel"}, {0x2198, L"searrow"}, {0x292d, L"seovnearrow"}, {0x2216, L"setminus"}, {0x29f5, L"setminus"}, {0x266f, L"sharp"}, {0x2adf, L"shortdowntack"}, {0x2190, L"shortleftarrow"}, {0x2ade, L"shortlefttack"}, {0x2192, L"shortrightarrow"}, {0x2944, L"shortrightarrowleftarrow"}, {0x2ae0, L"shortuptack"}, {0x29e2, L"shuffle"}, {0x3c3, L"sigma"}, {0x3c5, L"silon"}, {0x3d2, L"silon"}, {0x223c, L"sim"}, {0x2243, L"simeq"}, {0x2aa0, L"simgE"}, {0x2a9e, L"simgtr"}, {0x2b49, L"similarleftarrow"}, {0x2972, L"similarrightarrow"}, {0x2a9f, L"simlE"}, {0x2a9d, L"simless"}, {0x2a6c, L"simminussim"}, {0x2246, L"simneqq"}, {0x2a24, L"simplus"}, {0x2a6b, L"simrdots"}, {0x223f, L"sinewave"}, {0x2215, L"slash"}, {0x25c2, L"smallblacktriangleleft"}, {0x25b8, L"smallblacktriangleright"}, {0x22c4, L"smalldiamond"}, {0x220a, L"smallin"}, {0x222b, L"smallint"}, {0x220d, L"smallni"}, {0x2216, L"smallsetminus"}, {0x25c3, L"smalltriangleleft"}, {0x25b9, L"smalltriangleright"}, {0x2a33, L"smashtimes"}, {0x2b29, L"smblkdiamond"}, {0x2b2a, L"smblklozenge"}, {0x25aa, L"smblksquare"}, {0x29e4, L"smeparsl"}, {0x2323, L"smile"}, {0x263a, L"smiley"}, {0x2aaa, L"smt"}, {0x2aac, L"smte"}, {0x2b52, L"smwhitestar"}, {0x25e6, L"smwhtcircle"}, {0x2b2b, L"smwhtlozenge"}, {0x25ab, L"smwhtsquare"}, {0x2660, L"spadesuit"}, {0x2222, L"sphericalangle"}, {0x29a1, L"sphericalangleup"}, {0x2293, L"sqcap"}, {0x2294, L"sqcup"}, {0x2a16, L"sqint"}, {0x2311, L"sqlozenge"}, {0x800221a, L"sqrt"}, {0x800221b, L"sqrt3"}, {0x800221c, L"sqrt4"}, {0x23b7, L"sqrtbottom"}, {0x228f, L"sqsubset"}, {0x2291, L"sqsubseteq"}, {0x22e4, L"sqsubsetneq"}, {0x2290, L"sqsupset"}, {0x2292, L"sqsupseteq"}, {0x22e5, L"sqsupsetneq"}, {0x25a9, L"squarecrossfill"}, {0x25a9, L"squaregrayfill"}, {0x25a4, L"squarehfill"}, {0x25a6, L"squarehvfill"}, {0x25e7, L"squareleftblack"}, {0x25e8, L"squareleftblack"}, {0x2b15, L"squarellblack"}, {0x25f1, L"squarellquad"}, {0x25ea, L"squarelrblack"}, {0x25f2, L"squarelrquad"}, {0x25a8, L"squareneswfill"}, {0x25a7, L"squarenwsefill"}, {0x25e9, L"squareulblack"}, {0x25f0, L"squareulquad"}, {0x2b14, L"squareurblack"}, {0x25f3, L"squareurquad"}, {0x25a5, L"squarevfill"}, {0x25a2, L"squoval"}, {0xdf, L"ss"}, {0x22c6, L"star"}, {0x225b, L"stareq"}, {0xa3, L"sterling"}, {0x3db, L"stigma"}, {0x23e4, L"strns"}, {0x2ac3, L"subedot"}, {0x2ac1, L"submult"}, {0x2979, L"subrarr"}, {0x2282, L"subset"}, {0x2ac9, L"subsetapprox"}, {0x27c3, L"subsetcirc"}, {0x2abd, L"subsetdot"}, {0x2286, L"subseteq"}, {0x2ac5, L"subseteqq"}, {0x228a, L"subsetneq"}, {0x2acb, L"subsetneqq"}, {0x2abf, L"subsetplus"}, {0x2ac7, L"subsim"}, {0x2ad5, L"subsub"}, {0x2ad3, L"subsup"}, {0x227b, L"succ"}, {0x2ab8, L"succapprox"}, {0x227d, L"succcurlyeq"}, {0x2ab0, L"succeq"}, {0x2ab4, L"succeqq"}, {0x2aba, L"succnapprox"}, {0x2ab2, L"succneq"}, {0x2ab6, L"succneqq"}, {0x22e9, L"succnsim"}, {0x227f, L"succsim"}, {0x2211, L"sum"}, {0x23b3, L"sumbottom"}, {0x2a0b, L"sumint"}, {0x23b2, L"sumtop"}, {0x263c, L"sun"}, {0x2ad8, L"supdsub"}, {0x2ac4, L"supedot"}, {0x27c9, L"suphsol"}, {0x2ad7, L"suphsub"}, {0x297b, L"suplarr"}, {0x2ac2, L"supmult"}, {0x207f, L"supn"}, {0x2283, L"supset"}, {0x2aca, L"supsetapprox"}, {0x27c4, L"supsetcirc"}, {0x2abe, L"supsetdot"}, {0x2287, L"supseteq"}, {0x2ac6, L"supseteqq"}, {0x228b, L"supsetneq"}, {0x2acc, L"supsetneqq"}, {0x2ac0, L"supsetplus"}, {0x2ac8, L"supsim"}, {0x2ad4, L"supsub"}, {0x2ad6, L"supsup"}, {0x221a, L"surd"}, {0x2199, L"swarrow"}, {0x2afe, L"talloblong"}, {0x2316, L"target"}, {0x3c4, L"tau"}, {0x2649, L"taurus"}, {0x1d8d, L"testhookx"}, {0x2051, L"textAsterisks"}, {0x2ca, L"textacute"}, {0x2d6, L"textadvanced"}, {0x2bf, L"textain"}, {0xb4, L"textasciiacute"}, {0x5e, L"textasciicircum"}, {0xa8, L"textasciidieresis"}, {0x60, L"textasciigrave"}, {0xaf, L"textasciimacron"}, {0x7e, L"textasciitilde"}, {0x204e, L"textasterisklow"}, {0x2036, L"textbackdprime"}, {0x2035, L"textbackprime"}, {0x2037, L"textbacktrprime"}, {0x25f, L"textbardotlessj"}, {0x284, L"textbardotlessjvar"}, {0x2a1, L"textbarglotstop"}, {0x268, L"textbari"}, {0x19a, L"textbarl"}, {0x275, L"textbaro"}, {0x2a2, L"textbarrevglotstop"}, {0x289, L"textbaru"}, {0x26c, L"textbeltl"}, {0x1ba, L"textbenttailyogh"}, {0x2d8, L"textbreve"}, {0xa6, L"textbrokenbar"}, {0x2022, L"textbullet"}, {0x298, L"textbullseye"}, {0xa2, L"textcent"}, {0x2117, L"textcircledP"}, {0x29a, L"textcloseepsilon"}, {0x277, L"textcloseomega"}, {0x25e, L"textcloserevepsilon"}, {0xa9, L"textcopyright"}, {0x180, L"textcrb"}, {0x127, L"textcrh"}, {0x1be, L"textcrinvglotstop"}, {0x19b, L"textcrlambda"}, {0x1bb, L"textcrtwo"}, {0x255, L"textctc"}, {0x221, L"textctd"}, {0x286, L"textctesh"}, {0x29d, L"textctj"}, {0x234, L"textctl"}, {0x235, L"textctn"}, {0x236, L"textctt"}, {0x293, L"textctyogh"}, {0x291, L"textctz"}, {0xa4, L"textcurrency"}, {0x2a5, L"textdctzlig"}, {0xb0, L"textdegree"}, {0x2052, L"textdiscount"}, {0x24, L"textdollar"}, {0x2d9, L"textdotaccent"}, {0x237, L"textdotlessj"}, {0x2dd, L"textdoubleacute"}, {0x1c2, L"textdoublebarpipe"}, {0x1c1, L"textdoublepipe"}, {0x2033, L"textdprime"}, {0x2c5, L"textdptr"}, {0x2a4, L"textdyoghlig"}, {0x2a3, L"textdzlig"}, {0x25b, L"textepsilon"}, {0x283, L"textesh"}, {0x212e, L"textestimated"}, {0x1c3, L"textexclam"}, {0xa1, L"textexclamdown"}, {0x27e, L"textfishhookr"}, {0x192, L"textflorin"}, {0x20a3, L"textfranc"}, {0x263, L"textgamma"}, {0x294, L"textglotstop"}, {0x2cb, L"textgrave"}, {0x2d1, L"texthalflength"}, {0x2be, L"texthamza"}, {0xa727, L"texthen"}, {0xa727, L"textheng"}, {0x1d8a, L"texthooks"}, {0x1d8e, L"texthookz"}, {0x253, L"texthtb"}, {0x188, L"texthtc"}, {0x257, L"texthtd"}, {0x260, L"texthtg"}, {0x266, L"texthth"}, {0x267, L"texththeng"}, {0x199, L"texthtk"}, {0x1a5, L"texthtp"}, {0x2a0, L"texthtq"}, {0x29b, L"texthtscg"}, {0x1ad, L"texthtt"}, {0x195, L"texthvlig"}, {0x2010, L"texthyphen"}, {0x296, L"textinvglotstop"}, {0x281, L"textinvscr"}, {0x269, L"textiota"}, {0x2d0, L"textlengthmark"}, {0x2d3, L"textlhalfring"}, {0x1d81, L"textlhookd"}, {0x1d84, L"textlhookk"}, {0x1d85, L"textlhookl"}, {0x1ab, L"textlhookt"}, {0x27f, L"textlhti"}, {0x20a4, L"textlira"}, {0x27c, L"textlonglegr"}, {0x2ae, L"textlongy"}, {0x2af, L"textlongy"}, {0x1aa, L"textlooptoprevesh"}, {0x2cf, L"textlowacute"}, {0x2d5, L"textlowered"}, {0x2ce, L"textlowgrave"}, {0x2cd, L"textlowmacron"}, {0x2c2, L"textlptr"}, {0x271, L"textltailm"}, {0x272, L"textltailn"}, {0x26b, L"textltilde"}, {0x26e, L"textlyoghlig"}, {0x2c9, L"textmacron"}, {0xb5, L"textmu"}, {0x2116, L"textnumero"}, {0x2db, L"textogonek"}, {0x2126, L"textohm"}, {0xbd, L"textonehalf"}, {0xbc, L"textonequarter"}, {0xb9, L"textonesuperior"}, {0x254, L"textopeno"}, {0xaa, L"textordfeminine"}, {0xba, L"textordmasculine"}, {0x2df, L"textovercross"}, {0x2125, L"textoz"}, {0x2031, L"textpertenthousand"}, {0x2030, L"textperthousand"}, {0x20a7, L"textpesetas"}, {0x278, L"textphi"}, {0x1c0, L"textpipe"}, {0x2032, L"textprime"}, {0x2c8, L"textprimstress"}, {0x2057, L"textqprime"}, {0xbf, L"textquestiondown"}, {0x22, L"textquotedbl"}, {0x201c, L"textquotedblleft"}, {0x201d, L"textquotedblright"}, {0x2d4, L"textraised"}, {0x2c0, L"textraiseglotstop"}, {0x2c1, L"textraiserevglotstop"}, {0x264, L"textramshorns"}, {0x211e, L"textrecipe"}, {0x203b, L"textreferencemark"}, {0xae, L"textregistered"}, {0x2d7, L"textretracted"}, {0x258, L"textreve"}, {0x25c, L"textrevepsilon"}, {0x295, L"textrevglotstop"}, {0x2d2, L"textrhalfring"}, {0x25d, L"textrhookrevepsilon"}, {0x25a, L"textrhookschwa"}, {0x2de, L"textrhoticity"}, {0x2da, L"textringaccent"}, {0x2c3, L"textrptr"}, {0x256, L"textrtaild"}, {0x26d, L"textrtaill"}, {0x273, L"textrtailn"}, {0x27d, L"textrtailr"}, {0x282, L"textrtails"}, {0x288, L"textrtailt"}, {0x290, L"textrtailz"}, {0x1d00, L"textsca"}, {0x299, L"textscb"}, {0x1d07, L"textsce"}, {0x262, L"textscg"}, {0x29c, L"textsch"}, {0x259, L"textschwa"}, {0x26a, L"textsci"}, {0x29f, L"textscl"}, {0x274, L"textscn"}, {0x276, L"textscoelig"}, {0x280, L"textscr"}, {0x251, L"textscripta"}, {0x261, L"textscriptg"}, {0x28b, L"textscriptv"}, {0x1d1c, L"textscu"}, {0x28f, L"textscy"}, {0x2cc, L"textsecstress"}, {0x204f, L"textsemicolonreversed"}, {0x3a5, L"textsilon"}, {0x2dc, L"textsmalltilde"}, {0x297, L"textstretchcvar"}, {0x77, L"textsubw"}, {0x2b0, L"textsuph"}, {0x2b1, L"textsuphth"}, {0x2b6, L"textsupinvscr"}, {0x2b2, L"textsupj"}, {0x2b3, L"textsupr"}, {0x2b4, L"textsupturnr"}, {0x2b5, L"textsupturnrrtail"}, {0x2b7, L"textsupw"}, {0x2b8, L"textsupy"}, {0x2a7, L"texttctctlig"}, {0x2a8, L"texttctctlig"}, {0xbe, L"textthreequarters"}, {0xb3, L"textthreesuperior"}, {0x2122, L"texttrademark"}, {0x2034, L"texttrprime"}, {0x2a6, L"texttslig"}, {0x250, L"textturna"}, {0x2bb, L"textturncomma"}, {0x265, L"textturnh"}, {0x29e, L"textturnk"}, {0x27a, L"textturnlonglegr"}, {0x26f, L"textturnm"}, {0x270, L"textturnmrleg"}, {0x279, L"textturnr"}, {0x27b, L"textturnrrtail"}, {0x252, L"textturnscripta"}, {0x287, L"textturnt"}, {0x28c, L"textturnv"}, {0x28d, L"textturnw"}, {0x28e, L"textturny"}, {0xb2, L"texttwosuperior"}, {0x28a, L"textupsilon"}, {0x2c4, L"textuptr"}, {0x285, L"textvibyi"}, {0x2423, L"textvisiblespace"}, {0x292, L"textyogh"}, {0xfe, L"th"}, {0x2234, L"therefore"}, {0x29e7, L"thermod"}, {0x3b8, L"theta"}, {0x2248, L"thickapprox"}, {0x223c, L"thicksim"}, {0x27c0, L"threedangle"}, {0x2af6, L"threedotcolon"}, {0x2040, L"tieconcat"}, {0x29dd, L"tieinfty"}, {0xd7, L"times"}, {0x2a31, L"timesbar"}, {0x29ff, L"tminus"}, {0x2192, L"to"}, {0x2928, L"toea"}, {0x2927, L"tona"}, {0x2e5, L"tonebarextrahigh"}, {0x2e9, L"tonebarextralow"}, {0x2e6, L"tonebarhigh"}, {0x2e8, L"tonebarlow"}, {0x2e7, L"tonebarmid"}, {0x22a4, L"top"}, {0x2336, L"topbot"}, {0x2af1, L"topcir"}, {0x2ada, L"topfork"}, {0x25e0, L"topsemicircle"}, {0x2929, L"tosa"}, {0x292a, L"towa"}, {0x29fe, L"tplus"}, {0x23e2, L"trapezium"}, {0x25ec, L"trianglecdot"}, {0x25bf, L"triangledown"}, {0x26a0, L"triangleexclam"}, {0x25c1, L"triangleleft"}, {0x25ed, L"triangleleftblack"}, {0x22b4, L"trianglelefteq"}, {0x2a3a, L"triangleminus"}, {0x29ca, L"triangleodot"}, {0x2a39, L"triangleplus"}, {0x225c, L"triangleq"}, {0x25b7, L"triangleright"}, {0x25ee, L"trianglerightblack"}, {0x22b5, L"trianglerighteq"}, {0x29cc, L"triangles"}, {0x29cd, L"triangleserifs"}, {0x2a3b, L"triangletimes"}, {0x29cb, L"triangleubar"}, {0x29fb, L"tripleplus"}, {0x2034, L"trprime"}, {0x29a2, L"turnangle"}, {0x2129, L"turnediota"}, {0x2319, L"turnednot"}, {0x2a4b, L"twocaps"}, {0x2a4a, L"twocups"}, {0x21a1, L"twoheaddownarrow"}, {0x219e, L"twoheadleftarrow"}, {0x2b3b, L"twoheadleftarrowtail"}, {0x2b37, L"twoheadleftdbkarrow"}, {0x2b36, L"twoheadmapsfrom"}, {0x2905, L"twoheadmapsto"}, {0x21a0, L"twoheadrightarrow"}, {0x2916, L"twoheadrightarrowtail"}, {0x219f, L"twoheaduparrow"}, {0x2949, L"twoheaduparrowcircle"}, {0x2017, L"twolowline"}, {0x266b, L"twonotes"}, {0x2982, L"typecolon"}, {0x23e1, L"ubrbrak"}, {0x1b0, L"uhorn"}, {0x25dc, L"ularc"}, {0x25e4, L"ulblacktriangle"}, {0x231c, L"ulcorner"}, {0x230f, L"ulcrop"}, {0x25f8, L"ultriangle"}, {0x2a41, L"uminus"}, {0x23df, L"underbrace"}, {0x23b5, L"underbracket"}, {0x23dd, L"underparen"}, {0x22b4, L"unlhd"}, {0x22b5, L"unrhd"}, {0x214b, L"upand"}, {0x2191, L"uparrow"}, {0x2909, L"uparrowbarred"}, {0x29bd, L"uparrowoncircle"}, {0x21e2, L"updasharrow"}, {0x2195, L"updownarrow"}, {0x21a8, L"updownarrowbar"}, {0x21c5, L"updownarrows"}, {0x2951, L"updownharpoonleftleft"}, {0x294d, L"updownharpoonleftright"}, {0x294c, L"updownharpoonrightleft"}, {0x294f, L"updownharpoonrightright"}, {0x296e, L"updownharpoonsleftright"}, {0x297e, L"upfishtail"}, {0x21bf, L"upharpoonleft"}, {0x2960, L"upharpoonleftbar"}, {0x21be, L"upharpoonright"}, {0x295c, L"upharpoonrightbar"}, {0x2963, L"upharpoonsleftright"}, {0x27d2, L"upin"}, {0x2a1b, L"upint"}, {0x228e, L"uplus"}, {0x2934, L"uprightcurvearrow"}, {0x2127, L"upsilon"}, {0x21c8, L"upuparrows"}, {0x21e7, L"upwhitearrow"}, {0x25dd, L"urarc"}, {0x25e5, L"urblacktriangle"}, {0x231d, L"urcorner"}, {0x230e, L"urcrop"}, {0x25f9, L"urtriangle"}, {0x2c7, L"v"}, {0x2ae8, L"vBar"}, {0x2ae9, L"vBarv"}, {0x22a8, L"vDash"}, {0x2ae2, L"vDdash"}, {0x3f4, L"varTheta"}, {0x2ae6, L"varVdash"}, {0x2305, L"varbarwedge"}, {0x3d0, L"varbeta"}, {0x2667, L"varclubsuit"}, {0x2666, L"vardiamondsuit"}, {0x2306, L"vardoublebarwedge"}, {0x3b5, L"varepsilon"}, {0x2665, L"varheartsuit"}, {0x2b21, L"varhexagon"}, {0x2b22, L"varhexagonblack"}, {0x232c, L"varhexagonlrbonds"}, {0x2208, L"varin"}, {0x22f6, L"varisinobar"}, {0x22f3, L"varisins"}, {0x3f0, L"varkappa"}, {0x22bf, L"varlrtriangle"}, {0x220b, L"varni"}, {0x22fd, L"varniobar"}, {0x22fb, L"varnis"}, {0x2205, L"varnothing"}, {0x2232, L"varointclockwise"}, {0x3c6, L"varphi"}, {0x3d6, L"varpi"}, {0x221d, L"varpropto"}, {0x3f1, L"varrho"}, {0x23d0, L"varrowextender"}, {0x3c2, L"varsigma"}, {0x2664, L"varspadesuit"}, {0x2736, L"varstar"}, {0x3d1, L"vartheta"}, {0x25b5, L"vartriangle"}, {0x22b2, L"vartriangleleft"}, {0x22b3, L"vartriangleright"}, {0x2a61, L"varveebar"}, {0x23aa, L"vbraceextender"}, {0x29d0, L"vbrtri"}, {0x22a2, L"vdash"}, {0x22ee, L"vdots"}, {0x2a2f, L"vectimes"}, {0x2228, L"vee"}, {0x22bb, L"veebar"}, {0x27c7, L"veedot"}, {0x2a63, L"veedoublebar"}, {0x225a, L"veeeq"}, {0x2a5b, L"veemidvert"}, {0x2a52, L"veeodot"}, {0x2a56, L"veeonvee"}, {0x2a59, L"veeonwedge"}, {0x7c, L"vert"}, {0x2317, L"viewdata"}, {0x27dd, L"vlongdash"}, {0x25af, L"vrectangle"}, {0x25ae, L"vrectangleblack"}, {0x2b1d, L"vysmlblksquare"}, {0x2b1e, L"vysmlwhtsquare"}, {0x299a, L"vzigzag"}, {0x231a, L"watchicon"}, {0x2227, L"wedge"}, {0x2a5f, L"wedgebar"}, {0x27d1, L"wedgedot"}, {0x2a60, L"wedgedoublebar"}, {0x2a5a, L"wedgemidvert"}, {0x2a51, L"wedgeodot"}, {0x2a55, L"wedgeonwedge"}, {0x2259, L"wedgeq"}, {0x21ea, L"whitearrowupfrombar"}, {0x27c1, L"whiteinwhitetriangle"}, {0x25c5, L"whitepointerleft"}, {0x25bb, L"whitepointerright"}, {0x27e4, L"whitesquaretickleft"}, {0x27e5, L"whitesquaretickright"}, {0x2b2d, L"whthorzoval"}, {0x2b2f, L"whtvertoval"}, {0x29a6, L"wideangledown"}, {0x29a7, L"wideangleup"}, {0x2118, L"wp"}, {0x2240, L"wr"}, {0x29f9, L"xbsol"}, {0x3be, L"xi"}, {0x29f8, L"xsol"}, {0xa5, L"yen"}, {0x3b6, L"zeta"}, {0x2a20, L"zpipe"}, {0, L""}}; //----------------------------------------------------------------------------- mathgl-2.4.4/src/plot.cpp0000644000175000017500000026152013513030041015424 0ustar alastairalastair/*************************************************************************** * plot.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/plot.h" #include "mgl2/eval.h" #include "mgl2/data.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- // // Plot by formulas series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fplot(HMGL gr, const char *eqY, const char *pen, const char *opt) { if(eqY==0 || eqY[0]==0) return; // nothing to plot double r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5); long nm = gr->FaceNum?gr->FaceNum*n:10000, nd = gr->FaceNum?gr->FaceNum*10:1000; mglDataS x, y; x.dat.reserve(nm); y.dat.reserve(nm); mglFormula *eq = new mglFormula(eqY); // initial data filling x.clear(); y.clear(); if(gr->Min.x>0 && gr->Max.x>100*gr->Min.x) { double d = log(2*gr->Max.x/gr->Min.x)/(n-1); for(long i=0;iMax.x*exp(d*i)/(2*gr->Max.x/gr->Min.x+exp(d*i)); x.dat.push_back(xx); y.dat.push_back(eq->Calc(xx)); } } else if(gr->Max.x<0 && gr->Min.x<100*gr->Max.x) { double d = log(2*gr->Min.x/gr->Max.x)/(n-1); for(long i=0;iMin.x*exp(d*i)/(2*gr->Min.x/gr->Max.x+exp(d*i)); x.dat.push_back(xx); y.dat.push_back(eq->Calc(xx)); } } else { double d = (gr->Max.x - gr->Min.x)/(n-1.); for(long i=0;iMin.x + i*d; x.dat.push_back(xx); y.dat.push_back(eq->Calc(xx)); } } bool check=true; double ym=fabs(gr->Max.y - gr->Min.y)/nd; while(check && long(x.dat.size())NeedStop()) { delete eq; return; } check = false; for(long i=1;iCalc(xs); if(fabs(yr-ys)>ym) // bad approximation here { x.dat.insert(x.dat.begin()+i,xs); y.dat.insert(y.dat.begin()+i,yr); check = true; i++; } } } delete eq; mgl_plot_xy(gr,&x,&y,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fplot_xyz(HMGL gr, const char *eqX, const char *eqY, const char *eqZ, const char *pen, const char *opt) { double r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5); long nm = gr->FaceNum?gr->FaceNum*n:10000, nd = gr->FaceNum?gr->FaceNum*10:1000; mglDataS x, y, z, t; x.dat.reserve(nm); y.dat.reserve(nm); z.dat.reserve(nm); t.dat.reserve(nm); mglFormula *ex, *ey, *ez; ex = new mglFormula(eqX ? eqX : "0"); ey = new mglFormula(eqY ? eqY : "0"); ez = new mglFormula(eqZ ? eqZ : "0"); t.clear(); x.clear(); y.clear(); z.clear(); for(long i=0;iCalc(0,0,t[i])); y.push_back(ey->Calc(0,0,t[i])); z.push_back(ez->Calc(0,0,t[i])); } bool check=true; double xm=fabs(gr->Max.x-gr->Min.x)/nd, ym=fabs(gr->Max.y-gr->Min.y)/nd, zm=fabs(gr->Max.z-gr->Min.z)/nd; while(check && long(x.dat.size())NeedStop()) { delete ex; delete ey; delete ez; return; } check = false; for(long i=1;iCalc(0,0,ts); double ys=(y[i]+y[i-1])/2, yr=ey->Calc(0,0,ts); double zs=(z[i]+z[i-1])/2, zr=ez->Calc(0,0,ts); if(fabs(xr-xs)>xm || fabs(yr-ys)>ym || fabs(zr-zs)>zm) // bad approximation here { t.dat.insert(t.dat.begin()+i,ts); x.dat.insert(x.dat.begin()+i,xr); y.dat.insert(y.dat.begin()+i,yr); z.dat.insert(z.dat.begin()+i,zr); check = true; i++; } } } delete ex; delete ey; delete ez; mgl_plot_xyz(gr,&x,&y,&z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fplot_(uintptr_t *gr, const char *fy, const char *stl, const char *opt, int ly, int ls, int lo) { char *s=new char[ly+1]; memcpy(s,fy,ly); s[ly]=0; char *p=new char[ls+1]; memcpy(p,stl,ls); p[ls]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_fplot(_GR_, s, p, o); delete []s; delete []p; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fplot_xyz_(uintptr_t *gr, const char *fx, const char *fy, const char *fz, const char *stl, const char *opt, int lx, int ly, int lz, int ls, int lo) { char *sx=new char[lx+1]; memcpy(sx,fx,lx); sx[lx]=0; char *sy=new char[ly+1]; memcpy(sy,fy,ly); sy[ly]=0; char *sz=new char[lz+1]; memcpy(sz,fz,lz); sz[lz]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; char *p=new char[ls+1]; memcpy(p,stl,ls); p[ls]=0; mgl_fplot_xyz(_GR_, sx, sy, sz, p, o); delete []sx; delete []sy; delete []sz; delete []p; delete []o; } //----------------------------------------------------------------------------- // // Radar series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_radar(HMGL gr, HCDT a, const char *pen, const char *opt) { long n = a->GetNx(), ny=a->GetNy(); if(n<2) { gr->SetWarn(mglWarnLow,"Radar"); return; } mglData x(n+1,ny), y(n+1,ny); double m=a->Minimal(), r=gr->SaveState(opt); if(mgl_isnan(r) || r<0) r = m<0 ? -m:0; double *co=new double[2*n]; for(long i=0;iv(i,j); x.a[i+(n+1)*j] = (r+v)*co[i]; y.a[i+(n+1)*j] = (r+v)*co[i+n]; } x.a[n+(n+1)*j] = r+a->v(0,j); y.a[n+(n+1)*j] = 0; } mgl_plot_xy(gr,&x,&y,pen,0); if(mglchr(pen,'#')) // draw "grid" { m = 1.1*(a->Maximal()+r); x.Create(2); y.Create(2); for(long i=0;i0) { x.Create(101); y.Create(101); for(long i=0;i<91;i++) { x.a[i]=r*mgl_cos[(4*i)%360]; y.a[i]=r*mgl_cos[(270+4*i)%360]; } mgl_plot_xy(gr,&x,&y,"k",0); } } delete []co; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_radar_(uintptr_t *gr, uintptr_t *a, const char *pen, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_radar(_GR_, _DA_(a),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- // // Candle series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt) { long n=v1->GetNx(),pal,nx=x->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Candle"); return; } if(nxGetNx()!=n) { gr->SetWarn(mglWarnDim,"Candle"); return; } bool d1=false,d2=false; if(!y1) { y1 = new mglData(n); d1=true; ((mglData *)y1)->Fill(NAN,NAN); } if(!y2) { y2 = new mglData(n); d2=true; ((mglData *)y2)->Fill(NAN,NAN); } if(y1->GetNx()!=n || y2->GetNx()!=n) { if(d1) delete y1; if(d2) delete y2; gr->SetWarn(mglWarnDim,"Candle"); return; } static int cgid=1; gr->StartGroup("Candle",cgid++); gr->SaveState(opt); gr->SetPenPal(pen,&pal); long kq = gr->AllocPnts(8*n); bool sh = mglchr(pen,'!'); bool wire = mglchr(pen,'#'); double dv=nx>n?1:0; if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv =-1; double zm = gr->AdjustZMin(); double c1=gr->NextColor(pal), c2=c1; bool col2 = (gr->GetNumPal(pal)==2 && !sh); if(col2) c2 = gr->NextColor(pal); #pragma omp parallel for for(long i=0;iv(i), m2 = v2->v(i), xx = x->v(i); double d = iv(i+1)-xx : xx-x->v(i-1), c; double x1 = xx + d/2*(dv-gr->BarWidth); double x2 = x1 + gr->BarWidth*d; xx = (x1+x2)/2; if(sh) c = gr->NextColor(pal,i); else if(wire) c = (i>0 && m2>v2->v(i-1))?c2:c1; else c = (m1>m2)?c1:c2; long iq = kq+8*i; gr->AddPntQ(iq,mglPoint(xx,y1->v(i),zm),c); gr->AddPntQ(iq+1,mglPoint(xx,m1,zm),c); gr->AddPntQ(iq+2,mglPoint(xx,y2->v(i),zm),c); gr->AddPntQ(iq+3,mglPoint(xx,m2,zm),c); gr->AddPntQ(iq+4,mglPoint(x1,m1,zm),c); gr->AddPntQ(iq+5,mglPoint(x2,m1,zm),c); gr->AddPntQ(iq+6,mglPoint(x1,m2,zm),c); gr->AddPntQ(iq+7,mglPoint(x2,m2,zm),c); } for(long i=0;iline_plot(iq, iq+1); gr->line_plot(iq+2,iq+3); gr->line_plot(iq+4,iq+5); gr->line_plot(iq+4,iq+6); gr->line_plot(iq+7,iq+5); gr->line_plot(iq+7,iq+6); if(v1->v(i)>v2->v(i) || (col2 && !wire)) gr->quad_plot(iq+4,iq+5,iq+6,iq+7); } if(d1) delete y1; if(d2) delete y2; gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_candle_yv(HMGL gr, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(v1->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x); mgl_candle_xyv(gr,&x,v1,v2,y1,y2,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_candle(HMGL gr, HCDT v1, HCDT y1, HCDT y2, const char *pen, const char *opt) { mglData v2(v1); v2.Roll('x',1); v2.a[0]=NAN; mgl_candle_yv(gr,v1,&v2,y1,y2,pen,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_candle_xyv_(uintptr_t *gr, uintptr_t *x, uintptr_t *v1, uintptr_t *v2, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_candle_xyv(_GR_,_DA_(x),_DA_(v1),_DA_(v2),_DA_(y1),_DA_(y2),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_candle_yv_(uintptr_t *gr, uintptr_t *v1, uintptr_t *v2, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_candle_yv(_GR_,_DA_(v1),_DA_(v2),_DA_(y1),_DA_(y2),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_candle_(uintptr_t *gr, uintptr_t *y, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_candle(_GR_,_DA_(y),_DA_(y1),_DA_(y2),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- // // Plot series // //----------------------------------------------------------------------------- struct mglPointA { mglPoint p; bool orig; mglPointA(const mglPoint &pp, bool o) : p(pp), orig(o) {} }; std::vector static mgl_pnt_prepare(const mglPoint &p1, const mglPoint &p2, HCDT xx, HCDT yy, HCDT zz, HCDT cc) { std::vector out; long n = xx->GetNx(); mglPoint p(xx->v(0),yy->v(0),zz->v(0),cc?cc->v(0):0); if(p>p1 && pv(i),yy->v(i),zz->v(i),cc?cc->v(i):0); double x1,x2,y1,y2,z1,z2,t; x1=mgl_d(p1.x, p.x, q.x); x2=mgl_d(p2.x, p.x, q.x); if(x2d1) d1=y1; if(y2d1) d1=z1; if(z20 && d1<1) out.push_back(mglPointA(p+d1*(q-p),false)); if(d2>0 && d2<1) out.push_back(mglPointA(p+d2*(q-p),false)); if(d1<1 && d2>=1) out.push_back(mglPointA(q,true)); else if(i==n-1) out.push_back(mglPointA(mglPoint(NAN),true)); p = q; } return out; } std::vector static mgl_pnt_copy(HCDT xx, HCDT yy, HCDT zz, HCDT cc) { std::vector out; long n = xx->GetNx(); for(long i=0;iv(i),yy->v(i),zz->v(i),cc?cc->v(i):0),true)); return out; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark(HMGL gr, double x, double y, double z,const char *mark); void MGL_EXPORT mgl_plot_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { static int cgid=1; long n=y->GetNx(),pal; if(n<2 && !mgl_check_dim0(gr,x,y,z,0,"Plot")) { gr->StartGroup("Plot",cgid++); gr->SaveState(opt); char mk = gr->SetPenPal(pen); if(mk) { long k = gr->AddPnt(mglPoint(x->v(0),y->v(0),z->v(0)),gr->CDef,mglPoint(NAN),-1,3); gr->mark_plot(k,mk,gr->GetPenWidth()); gr->AddActive(k); } gr->EndGroup(); return; } if(mgl_check_dim1(gr,x,y,z,0,"Plot")) return; gr->StartGroup("Plot",cgid++); gr->SaveState(opt); long m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); bool sh = mglchr(pen,'!'), orig = !mglchr(pen,'a'); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1; for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; gr->NextColor(pal); mglDataR xx(x,mx), yy(y,my), zz(z,mz); const std::vector &pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, 0) : mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, 0); size_t num = pp.size(); long kq = gr->AllocPnts(num); #pragma omp parallel for for(msize i=0;iNextColor(pal,i):gr->CDef; gr->AddPntQ(kq+i, pp[i].p, c); } if(mk) for(size_t i=0;imark_plot(kq+i, mk); if(num>1) { gr->arrow_plot(kq,kq+1,gr->Arrow1); gr->arrow_plot(kq+num-1,kq+num-2,gr->Arrow2); } gr->curve_plot(num, kq); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_plot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_plot_xyz(gr,x,y,&z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_plot(HMGL gr, HCDT y, const char *pen, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Plot"); return; } gr->SaveState(opt); mglDataV x(n), z(n); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_plot_xyz(gr,&x,y,&z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_plot_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_plot_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_plot_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_plot_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_plot_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_plot(_GR_, _DA_(y),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- // // Tens series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tens_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *pen, const char *opt) { long m,n=y->GetNx(), pal; if(mgl_check_dim1(gr,x,y,z,0,"Tens")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Tens",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; char mk=gr->SetPenPal(pen, &pal); gr->Reserve(2*n*m); long ss=gr->AddTexture(pen); bool orig = !mglchr(pen,'a'); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1; for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; long mz = jGetNy() ? j:0, mc = jGetNy() ? j:0; mglDataR xx(x,mx), yy(y,my), zz(z,mz), cc(c,mc); const std::vector &pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, &cc) : mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, &cc); size_t num = pp.size(); long kq = gr->AllocPnts(num); #pragma omp parallel for for(msize i=0;iAddPntQ(kq+i,pp[i].p, gr->GetC(ss,pp[i].p.c)); } if(mk) for(size_t i=0;imark_plot(kq+i, mk); if(num>1) { gr->arrow_plot(kq,kq+1,gr->Arrow1); gr->arrow_plot(kq+num-1,kq+num-2,gr->Arrow2); } gr->curve_plot(num, kq); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tens_xy(HMGL gr, HCDT x, HCDT y, HCDT c, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_tens_xyz(gr,x,y,&z,c,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tens(HMGL gr, HCDT y, HCDT c, const char *pen, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Tens"); return; } gr->SaveState(opt); mglDataV x(n), z(n); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_tens_xyz(gr,&x,y,&z,c,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tens_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tens_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(c),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tens_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *c, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tens_xy(_GR_, _DA_(x),_DA_(y),_DA_(c),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tens_(uintptr_t *gr, uintptr_t *y, uintptr_t *c, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tens(_GR_, _DA_(y),_DA_(c),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Area series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { long n=y->GetNx(),m,pal; if(mgl_check_dim1(gr,x,y,z,0,"Area")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Area3",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a'); double z0=gr->GetOrgZ('x'); gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal); long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; mglDataR xx(x,mx), yy(y,my), zz(z,mz); std::vector pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, 0) : mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, 0); size_t np = pp.size(); mglPoint nn(pp[0].p.y-pp[1].p.y, pp[1].p.x-pp[0].p.x); long kq = gr->AllocPnts(2*np); #pragma omp parallel for for(msize i=0;iNextColor(pal,i); if(i>0 && iAddPntQ(kq+2*i,pp[i].p, sh?cc:c1,nn,-1,27); pp[i].p.z = z0; bool r2 = gr->AddPntQ(kq+2*i+1,pp[i].p, sh?cc:c2,nn,-1,27); if(!r1 && !r2) { gr->DisablePnt(kq+2*i); gr->DisablePnt(kq+2*i+1); } } for(size_t i=1;iSamePnt(iq,iq-2) || gr->SamePnt(iq+1,iq-1)) continue; if(wire) { gr->line_plot(iq,iq+1); gr->line_plot(iq-1,iq+1); gr->line_plot(iq,iq-2); gr->line_plot(iq-1,iq-2); } else gr->quad_plot(iq,iq+1,iq-2,iq-1); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_area_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { long n=y->GetNx(),m=y->GetNy(),pal; if(mgl_check_dim1(gr,x,y,0,0,"Area")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Curve",cgid++); double zm = gr->AdjustZMin(); double y0=gr->GetOrgY('x'); mglPoint nn(0,0,1); bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a'); gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2=gr->NextColor(pal); long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; double z0 = zm + (m-1-j)*(gr->Max.z-zm)/m; mglDataR xx(x,mx), yy(y,my); mglDataV zz(n,1,1,z0); std::vector pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, 0) : mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, 0); size_t np = pp.size(); long kq = gr->AllocPnts(2*np); #pragma omp parallel for for(msize i=0;iNextColor(pal,i); bool r1 = gr->AddPntQ(kq+2*i,pp[i].p, sh?cc:c1,nn,-1,27); pp[i].p.y = y0; bool r2 = gr->AddPntQ(kq+2*i+1,pp[i].p, sh?cc:c2,nn,-1,27); if(!r1 && !r2) { gr->DisablePnt(kq+2*i); gr->DisablePnt(kq+2*i+1); } } if(wire) gr->line_plot(kq,kq+1); for(size_t i=1;iSamePnt(iq,iq-2) || gr->SamePnt(iq+1,iq-1)) continue; if(wire) { gr->line_plot(iq,iq+1); gr->line_plot(iq-1,iq+1); gr->line_plot(iq,iq-2); } else gr->quad_plot(iq,iq+1,iq-2,iq-1); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_area(HMGL gr, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x); mgl_area_xy(gr,&x,y,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_area_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_area_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_area_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_area_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_area_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_area(_GR_, _DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Region series // //----------------------------------------------------------------------------- struct mglPointB { mglPoint p1, p2; bool orig; mglPointB(const mglPoint &pp1, const mglPoint &pp2, bool o) : p1(pp1), p2(pp2), orig(o) {} }; std::vector static mgl_pnt_prepare(const mglPoint &a1, const mglPoint &a2, HCDT xx1, HCDT yy1, HCDT zz1, HCDT xx2, HCDT yy2, HCDT zz2) { std::vector out; long n = xx1->GetNx(); mglPoint p1(xx1->v(0),yy1->v(0),zz1->v(0)), p2(xx2->v(0),yy2->v(0),zz2->v(0)); if(p1>a1 && p1a1 && p2v(i),yy1->v(i),zz1->v(i)), q2(xx2->v(i),yy2->v(i),zz2->v(i)); double x1,x2,y1,y2,z1,z2,t; x1=mgl_d(a1.x, p1.x, q1.x); x2=mgl_d(a2.x, p1.x, q1.x); if(x2d11) d11=y1; if(y2d11) d11=z1; if(z2d21) d21=y1; if(y2d21) d21=z1; if(z2 dd; if(d11>0 && d11<1) dd.push_back(d11); if(d21>0 && d21<1) dd.push_back(d21); if(d12>0 && d12<1) dd.push_back(d12); if(d22>0 && d22<1) dd.push_back(d22); // now add all intersections to be sure x1=mgl_d(0, p2.x-p1.x, q2.x-q1.x); if(x1>0 && x1<1) dd.push_back(x1); y1=mgl_d(0, p2.y-p1.y, q2.y-q1.y); if(y1>0 && y1<1) dd.push_back(y1); z1=mgl_d(0, p2.z-p1.z, q2.z-q1.z); if(z1>0 && z1<1) dd.push_back(z1); std::sort(dd.begin(),dd.end()); for(size_t j=0;j=1) || (d21<1 && d22>=1)) out.push_back(mglPointB(q1,q2,true)); else if(i==n-1) out.push_back(mglPointB(mglPoint(NAN),mglPoint(NAN),true)); p1 = q1; p2 = q2; } return out; } std::vector static mgl_pnt_copy(HCDT xx1, HCDT yy1, HCDT zz1, HCDT xx2, HCDT yy2, HCDT zz2) { std::vector out; long n = xx1->GetNx(); for(long i=0;iv(i),yy1->v(i),zz1->v(i)), mglPoint(xx2->v(i),yy2->v(i),zz2->v(i)), true)); return out; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_region_3d(HMGL gr, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT y2, HCDT z2, const char *pen, const char *opt) { long n=y1->GetNx(), m, pal; if(mgl_check_dim1(gr,x1,y1,z1,0,"Region")) return; if(mgl_check_dim1(gr,x1,x2,y2,z2,"Region")) return; m = x1->GetNy() > y1->GetNy() ? x1->GetNy() : y1->GetNy(); m = (z1 && z1->GetNy() > m) ? z1->GetNy() : m; bool zhave = z1 && z2; if(x1->GetNy()!=x2->GetNy() || y1->GetNy()!=y2->GetNy()) { gr->SetWarn(mglWarnDim,"Region"); return; } if(zhave && z1->GetNy()!=z2->GetNy()) { gr->SetWarn(mglWarnDim,"Region"); return; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("Region",cgid++); mglPoint nn(0,0,1); double zm = gr->AdjustZMin(); // bool inside = (mglchr(pen,'i')); // NOTE: check if 'i' is free (used here for inside flag) bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a'); gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2=gr->NextColor(pal); long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; long mz = (zhave && jGetNy()) ? j:0; double z0 = zm + (m-1-j)*(gr->Max.z-zm)/m; mglDataR xx1(x1,mx), yy1(y1,my), xx2(x2,mx), yy2(y2,my); mglDataV zz0(n,1,1,z0); std::vector pp; if(zhave) { mglDataR zz1(z1,mz), zz2(z2,mz); pp = orig ? mgl_pnt_copy(&xx1, &yy1, &zz1, &xx2, &yy2, &zz2) : mgl_pnt_prepare(gr->Min, gr->Max, &xx1, &yy1, &zz1, &xx2, &yy2, &zz2); } else { pp = orig ? mgl_pnt_copy(&xx1, &yy1, &zz0, &xx2, &yy2, &zz0) : mgl_pnt_prepare(gr->Min, gr->Max, &xx1, &yy1, &zz0, &xx2, &yy2, &zz0); } size_t np = pp.size(); long kq = gr->AllocPnts(2*np); #pragma omp parallel for for(msize i=0;iNextColor(pal,i); bool r1 = gr->AddPntQ(kq+2*i,pp[i].p1, sh?cc:c1,nn,-1,27); bool r2 = gr->AddPntQ(kq+2*i+1,pp[i].p2, sh?cc:c2,nn,-1,27); if(!r1 && !r2) { gr->DisablePnt(kq+2*i); gr->DisablePnt(kq+2*i+1); } } if(wire) gr->line_plot(kq,kq+1); for(size_t i=1;iSamePnt(iq,iq-2) || gr->SamePnt(iq+1,iq-1)) continue; if(wire) { gr->line_plot(iq,iq+1); gr->line_plot(iq-1,iq+1); gr->line_plot(iq,iq-2); } else gr->quad_plot(iq,iq+1,iq-2,iq-1); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen, const char *opt) { long n=y1->GetNx(), m=y1->GetNy(), pal; if(mgl_check_dim1(gr,x,y1,y2,0,"Region")) return; if(y2->GetNy()!=m) { gr->SetWarn(mglWarnDim,"Region"); return; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("Region",cgid++); mglPoint nn(0,0,1); double zm = gr->AdjustZMin(); bool inside = mglchr(pen,'i'); // NOTE: check if 'i' is free (used here for inside flag) bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a'); gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2=gr->NextColor(pal); long mx = jGetNy() ? j:0; double z0 = zm + (m-1-j)*(gr->Max.z-zm)/m; mglDataR xx(x,mx), yy1(y1,j), yy2(y2,j); mglDataV zz0(n,1,1,z0); std::vector pp = orig ? mgl_pnt_copy(&xx, &yy1, &zz0, &xx, &yy2, &zz0) : mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy1, &zz0, &xx, &yy2, &zz0); size_t np = pp.size(); long kq = gr->AllocPnts(2*np); #pragma omp parallel for for(msize i=0;iNextColor(pal,i); bool r1 = gr->AddPntQ(kq+2*i,pp[i].p1, sh?cc:c1,nn,-1,27); bool r2 = gr->AddPntQ(kq+2*i+1,pp[i].p2, sh?cc:c2,nn,-1,27); if(!r1 && !r2) { gr->DisablePnt(kq+2*i); gr->DisablePnt(kq+2*i+1); } } if(wire) gr->line_plot(kq,kq+1); for(size_t i=1;iSamePnt(iq,iq-2) || gr->SamePnt(iq+1,iq-1)) continue; if(wire) { gr->line_plot(iq,iq+1); gr->line_plot(iq-1,iq+1); gr->line_plot(iq,iq-2); } else if(!inside) gr->quad_plot(iq,iq+1,iq-2,iq-1); else { const mglPointB &a=pp[i-1], &b=pp[i]; if(a.p1.y<=a.p2.y && b.p1.y<=b.p2.y) gr->quad_plot(iq,iq+1,iq-2,iq-1); else if(a.p1.y<=a.p2.y) { double cc=gr->NextColor(pal,i); double dd = (a.p1.y-a.p2.y)/(b.p2.y-b.p1.y-a.p2.y+a.p1.y); long ns = gr->AddPnt(b.p1*dd+a.p1*(1-dd), sh?cc:c1,nn,-1,27); gr->trig_plot(iq-2,iq-1,ns); } else if(b.p1.y<=b.p2.y) { double cc=gr->NextColor(pal,i); double dd = (a.p1.y-a.p2.y)/(b.p2.y-b.p1.y-a.p2.y+a.p1.y); long ns = gr->AddPnt(b.p1*dd+a.p1*(1-dd), sh?cc:c1,nn,-1,27); gr->trig_plot(iq,iq+1,ns); } } } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_region(HMGL gr, HCDT y1, HCDT y2, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y1->GetNx()); x.Fill(gr->Min.x, gr->Max.x); mgl_region_xy(gr,&x,y1,y2,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_region_3d_(uintptr_t *gr, uintptr_t *x1, uintptr_t *y1, uintptr_t *z1, uintptr_t *x2, uintptr_t *y2, uintptr_t *z2, const char *pen, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_region_3d(_GR_, _DA_(x1),_DA_(y1),_DA_(z1),_DA_(x2),_DA_(y2),_DA_(z2),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_region_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_region_xy(_GR_, _DA_(x),_DA_(y1),_DA_(y2),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_region_(uintptr_t *gr, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_region(_GR_, _DA_(y1),_DA_(y2),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Step series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_step_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { long m,n=y->GetNx(), pal; if(mgl_check_dim1(gr,x,y,z,0,"Step")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Step3",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; bool sh = mglchr(pen,'!'); char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1; for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; gr->NextColor(pal); long kq = gr->AllocPnts(2*n); gr->SetPntOff(kq); gr->AddPntQ(kq+1,mglPoint(x->v(0,mx), y->v(0,my), z->v(0,mz))); if(mk) gr->mark_plot(kq+1,mk); #pragma omp parallel for for(long i=1;iv(i,mx), y->v(i,my), z->v(i-1,mz)); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+2*i,p,c); p.z = z->v(i,mz); gr->AddPntQ(kq+2*i+1,p,c); } for(long i=1;iline_plot(iq,iq-1); gr->line_plot(iq,iq+1); if(mk && i%dx==0) gr->mark_plot(iq+1,mk); } gr->arrow_plot(kq+1,kq+2,gr->Arrow2); gr->arrow_plot(kq+2*n-1,kq+2*n-2,gr->Arrow2); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_step_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { long m,n=y->GetNx(), pal; if(mgl_check_dim1(gr,x,y,0,0,"Step",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Step",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); bool sh = mglchr(pen,'!'); bool same = x->GetNx()==n; double zVal =gr->AdjustZMin(); char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1; for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; gr->NextColor(pal); long kq = gr->AllocPnts(2*n); gr->SetPntOff(kq); gr->AddPntQ(kq+1,mglPoint(x->v(0,mx), y->v(0,my), zVal)); if(same && mk) gr->mark_plot(kq+1,mk); #pragma omp parallel for for(long i=1;iv(i,mx), y->v(i-1,my), zVal); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+2*i,p,c); p.y = y->v(i,my); gr->AddPntQ(kq+2*i+1,p,c); } for(long i=1;iline_plot(iq,iq-1); gr->line_plot(iq,iq+1); if(same && mk && i%dx==0) gr->mark_plot(iq+1,mk); } gr->arrow_plot(kq+1,kq+2,gr->Arrow2); gr->arrow_plot(kq+2*n-1,kq+2*n-2,gr->Arrow2); if(!same && mk) { kq = gr->AllocPnts(1+(n-1)/dx); #pragma omp parallel for for(long i=0;iv(i,mx)+x->v(i+1,mx))/2, y->v(i,my), zVal); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+i,p,c); } for(long i=0;imark_plot(kq+i,mk); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_step(HMGL gr, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x); mgl_step_xy(gr,&x,y,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_step_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_step_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_step_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_step_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_step_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_step(_GR_, _DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Stem series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stem_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { long m,n=y->GetNx(), pal; if(mgl_check_dim0(gr,x,y,z,0,"Stem")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Stem3",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; bool sh = mglchr(pen,'!'); double z0=gr->GetOrgZ('x'); char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; gr->NextColor(pal); long kq = gr->AllocPnts(2*n); #pragma omp parallel for for(long i=0;iNextColor(pal,i):gr->CDef; gr->AddPntQ(kq+2*i,mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz)),c); gr->AddPntQ(kq+2*i+1,mglPoint(x->v(i,mx), y->v(i,my), z0),c); } for(long i=0;iline_plot(iq,iq+1); if(mk) gr->mark_plot(iq,mk); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stem_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { long m,n=y->GetNx(), pal; if(mgl_check_dim0(gr,x,y,0,0,"Stem")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Stem",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); bool sh = mglchr(pen,'!'); double zVal = gr->AdjustZMin(), y0=gr->GetOrgY('x'); char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m); for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; gr->NextColor(pal); long kq = gr->AllocPnts(2*n); #pragma omp parallel for for(long i=0;iNextColor(pal,i):gr->CDef; gr->AddPntQ(kq+2*i,mglPoint(x->v(i,mx), y->v(i,my), zVal),c); gr->AddPntQ(kq+2*i+1,mglPoint(x->v(i,mx), y0, zVal),c); } for(long i=0;iline_plot(iq,iq+1); if(mk) gr->mark_plot(iq,mk); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stem(HMGL gr, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x); mgl_stem_xy(gr,&x,y,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stem_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_stem_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stem_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_stem_xy(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_stem_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_stem(_GR_,_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Bars series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bars_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { long m,n=z->GetNx(), pal,nx=x->GetNx(),ny=y->GetNx(); if(mgl_check_dim1(gr,x,z,y,0,"Bars",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Bars3",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; const bool sh = mglchr(pen,'!'); bool wire = mglchr(pen,'#'), fixed = mglchr(pen,'F'); bool above = mglchr(pen,'a'), fall = mglchr(pen,'f'); if(above) fall = false; double *dd=new double[n], *zp=0, dv=nx>n?1:0; if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv = -1; memset(dd,0,n*sizeof(double)); if(fall) zp = new double[n]; double dc=INFINITY; if(fixed) for(long j=0;jGetNy() ? j:0, my = jGetNy() ? j:0; for(long i=0;iv(i+1,mx)-x->v(i,mx), y->v(i+1,my)-y->v(i,my)); if(cxSetPenPal(pen,&pal); gr->Reserve(4*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal); const long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; const double z0 = gr->GetOrgZ('x'); if(fall) { zp[0]=z0; for(long i=0;iv(i,mz); } const long kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), dx = iv(i+1,mx)-vv : vv-x->v(i-1,mx), dy, zz; double x1 = vv + dx/2*(dv-gr->BarWidth), x2 = x1 + gr->BarWidth*dx; vv = y->v(i,my); dy = iv(i+1,my)-vv : vv-y->v(i-1,my); if(fixed) { double ff = dc/hypot(dx,dy); dx *= ff; dy *= ff; } double y1 = vv + dy/2*(dv-gr->BarWidth), y2 = y1 + gr->BarWidth*dy; vv = zz = z->v(i,mz); double zt = z0; if(!above) { x2 = (x2-x1)/m; x1 += j*x2; x2 += x1; y2 = (y2-y1)/m; y1 += j*y2; y2 += y1; if(fall) { zt = zp[i]; zz += zp[i]; } } else { zt = gr->GetOrgZ('x') + dd[i]; dd[i] += zz; zz += zt; } double c = !sh ? (vv<0 ? c1 : c2) : gr->NextColor(pal,i); mglPoint nn(-y->dvx(i,my),x->dvx(i,mx)); gr->AddPntQ(kq+4*i,mglPoint(x1,y1,zz),c,nn); gr->AddPntQ(kq+4*i+1,mglPoint(x1,y1,zt),c,nn); gr->AddPntQ(kq+4*i+2,mglPoint(x2,y2,zt),c,nn); gr->AddPntQ(kq+4*i+3,mglPoint(x2,y2,zz),c,nn); } for(long i=0;iline_plot(iq,iq+1); gr->line_plot(iq,iq+3); gr->line_plot(iq+2,iq+1); gr->line_plot(iq+2,iq+3); } else gr->quad_plot(iq,iq+1,iq+3,iq+2); } } gr->EndGroup(); delete []dd; if(fall) delete []zp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bars_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { long m,n=y->GetNx(),nx=x->GetNx(),pal; if(mgl_check_dim1(gr,x,y,0,0,"Bars",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Bars",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); bool sh = mglchr(pen,'!'); bool wire = mglchr(pen,'#'), fixed = mglchr(pen,'F'); bool above = mglchr(pen,'a'), fall = mglchr(pen,'f'); if(above) fall = false; double *dd=new double[n], dv=nx>n?1:0, *yp=0; memset(dd,0,n*sizeof(double)); if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv = -1; const double zm = gr->AdjustZMin(); if(fall) yp = new double[n]; double dx=INFINITY; if(fixed) { long nn=x->GetNy(); for(long j=0;jv(i+1,j)-x->v(i,j)); if(cxSetPenPal(pen,&pal); gr->Reserve(4*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal); const long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; const double y0 = gr->GetOrgY('x'); if(fall) { yp[0]=y0; for(long i=0;iv(i,my); } const long kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), d = iv(i+1,mx)-vv : vv-x->v(i-1,mx), yy; if(fixed) d = dx; double x1 = vv + d/2*(dv-gr->BarWidth), x2 = x1 + gr->BarWidth*d; vv = yy = y->v(i,my); double yt = y0; if(!above) { x2 = (x2-x1)/m; x1 += j*x2; x2 += x1; if(fall) { yt = yp[i]; yy += yp[i]; } } else { yt = y0 + dd[i]; dd[i] += yy; yy += yt; } double c = !sh ? (vv<0 ? c1 : c2) : gr->NextColor(pal,i); gr->AddPntQ(kq+4*i,mglPoint(x1,yy,zm),c); gr->AddPntQ(kq+4*i+1,mglPoint(x1,yt,zm),c); gr->AddPntQ(kq+4*i+2,mglPoint(x2,yt,zm),c); gr->AddPntQ(kq+4*i+3,mglPoint(x2,yy,zm),c); } for(long i=0;iline_plot(iq,iq+1); gr->line_plot(iq,iq+3); gr->line_plot(iq+2,iq+1); gr->line_plot(iq+2,iq+3); } else gr->quad_plot(iq,iq+1,iq+3,iq+2); } } gr->EndGroup(); delete []dd; if(fall) delete []yp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bars(HMGL gr, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x); mgl_bars_xy(gr,&x,y,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bars_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_bars_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bars_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_bars_xy(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_bars_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_bars(_GR_,_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Barh series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char *opt) { long m,n=v->GetNx(),ny=y->GetNx(),pal; if(mgl_check_dim1(gr,y,v,0,0,"Barh",true)) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Barh",cgid++); m = y->GetNy() > v->GetNy() ? y->GetNy() : v->GetNy(); bool sh = mglchr(pen,'!'); bool wire = mglchr(pen,'#'), fixed = mglchr(pen,'F'); bool above = mglchr(pen,'a'), fall = mglchr(pen,'f'); if(above) fall = false; double *dd=new double[n], *xp=0,dv=ny>n?1:0; if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv = -1; const double zm = gr->AdjustZMin(); memset(dd,0,n*sizeof(double)); if(fall) xp = new double[n]; double dy=INFINITY; if(fixed) { long nn=y->GetNy(); for(long j=0;jv(i+1,j)-y->v(i,j)); if(cxSetPenPal(pen,&pal); gr->Reserve(4*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal); const long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; const double x0 = gr->GetOrgX('y'); if(fall) { xp[0]=x0; for(long i=0;iv(i,mx); } const long kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,my), d = iv(i+1,my)-vv : vv-y->v(i-1,my), xx; if(fixed) d = dy; double y1 = vv + d/2*(dv-gr->BarWidth), y2 = y1 + gr->BarWidth*d; vv = xx = v->v(i,mx); double xt = x0; if(!above) { y2 = (y2-y1)/m; y1 += j*y2; y2 += y1; if(fall) { xt = xp[i]; xx += xp[i]; } } else { xt = x0 + dd[i]; dd[i] += xx; xx += xt; } double c = !sh ? (vv<0 ? c1 : c2) : gr->NextColor(pal,i); gr->AddPntQ(kq+4*i,mglPoint(xx,y1,zm),c); gr->AddPntQ(kq+4*i+1,mglPoint(xx,y2,zm),c); gr->AddPntQ(kq+4*i+2,mglPoint(xt,y2,zm),c); gr->AddPntQ(kq+4*i+3,mglPoint(xt,y1,zm),c); } for(long i=0;iline_plot(iq,iq+1); gr->line_plot(iq,iq+3); gr->line_plot(iq+2,iq+1); gr->line_plot(iq+2,iq+3); } else gr->quad_plot(iq,iq+1,iq+3,iq+2); } } gr->EndGroup(); delete []dd; if(fall) delete []xp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_barh(HMGL gr, HCDT v, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV y(v->GetNx()+1); y.Fill(gr->Min.y,gr->Max.y); mgl_barh_yx(gr,&y,v,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_barh_yx_(uintptr_t *gr, uintptr_t *y, uintptr_t *v, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_barh_yx(_GR_,_DA_(y),_DA_(v),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_barh_(uintptr_t *gr, uintptr_t *v, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_barh(_GR_,_DA_(v),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // OHLC series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ohlc_x(HMGL gr, HCDT x, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt) { long n=open->GetNx(), nx=x->GetNx(), m=open->GetNy(), mx; if(nxGetNx()*high->GetNy() || n*m!=low->GetNx()*low->GetNy() || n*m!=close->GetNx()*close->GetNy()) { gr->SetWarn(mglWarnDim,"OHLC"); return; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("OHLC",cgid++); double dv=nx>n?1:0; if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv = -1; double zVal = gr->AdjustZMin(); bool sh = mglchr(pen,'!'); long pal; gr->SetPenPal(pen,&pal); gr->Reserve(6*n*m); for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal); mx = jGetNy() ? j:0; const long kq = gr->AllocPnts(6*n); #pragma omp parallel for for(long i=0;iv(i,mx); dd = iv(i+1)-vv : vv-x->v(i-1); x1 = vv + dd/2*(dv-gr->BarWidth); x2 = x1 + gr->BarWidth*dd; x2 = (x2-x1)/m; x1 += j*x2; x2 += x1; vv = (x2+x1)/2; dd = close->v(i,j); double c = !sh? ((i==0 || dd>=close->v(i-1,j)) ? c1:c2) : gr->NextColor(pal,i); gr->AddPntQ(kq+6*i,mglPoint(vv,dd,zVal),c); gr->AddPntQ(kq+6*i+1,mglPoint(x2,dd,zVal),c); dd = open->v(i,j); gr->AddPntQ(kq+6*i+2,mglPoint(x1,dd,zVal),c); gr->AddPntQ(kq+6*i+3,mglPoint(vv,dd,zVal),c); gr->AddPntQ(kq+6*i+4,mglPoint(vv,low->v(i,j),zVal),c); gr->AddPntQ(kq+6*i+5,mglPoint(vv,high->v(i,j),zVal),c); } for(long i=0;iline_plot(iq,iq+1); gr->line_plot(iq+2,iq+3); gr->line_plot(iq+4,iq+5); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ohlc(HMGL gr, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(open->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x); mgl_ohlc_x(gr,&x,open,high,low,close,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ohlc_x_(uintptr_t *gr, uintptr_t *x, uintptr_t *open, uintptr_t *high, uintptr_t *low, uintptr_t *close, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_ohlc_x(_GR_,_DA_(x),_DA_(open),_DA_(high),_DA_(low),_DA_(close),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ohlc_(uintptr_t *gr, uintptr_t *open, uintptr_t *high, uintptr_t *low, uintptr_t *close, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_ohlc(_GR_,_DA_(open),_DA_(high),_DA_(low),_DA_(close),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // BoxPlot series // //----------------------------------------------------------------------------- double sgn(double a); int static mgl_cmp_flt(const void *a, const void *b) { const double *aa = (const double *)a; const double *bb = (const double *)b; return int(sgn(*aa-*bb)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxplot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { long n=y->GetNx(), m=y->GetNy(), nx=x->GetNx(); if(nxSetWarn(mglWarnDim,"BoxPlot"); return; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("BoxPlot",cgid++); double *b = new double[5*n], dv=nx>n?1:0; if(mglchr(pen,'<')) dv = 1; if(mglchr(pen,'^')) dv = 0; if(mglchr(pen,'>')) dv = -1; double zVal = gr->AdjustZMin(); bool sh = mglchr(pen,'!'); double *d = new double[m]; for(long i=0;iv(i,j); if(mgl_isnum(vv)) { d[mm]=vv; mm++; } } qsort(d, mm, sizeof(double), mgl_cmp_flt); b[i] = d[0]; b[i+4*n] = d[mm-1]; k = mm/4; b[i+n] = (mm%4) ? d[k] : (d[k]+d[k-1])/2.; b[i+2*n] = (mm%2) ? d[mm/2] : (d[mm/2]+d[mm/2-1])/2.; b[i+3*n] = (mm%4) ? d[mm-k-1] : (d[mm-k-1]+d[mm-k])/2.; } delete []d; long pal; gr->SetPenPal(pen,&pal); gr->NextColor(pal); const long kq = gr->AllocPnts(18*n); #pragma omp parallel for for(long i=0;iv(i); const double dd = iv(i+1)-vv : vv-x->v(i-1); const double x1 = vv + dd/2*(dv-gr->BarWidth); const double x2 = x1 + gr->BarWidth*dd; const double c = sh ? gr->NextColor(pal,i):gr->CDef; const long iq = kq+18*i; gr->AddPntQ(iq,mglPoint(x1,b[i],zVal),c); // horizontal lines gr->AddPntQ(iq+1,mglPoint(x2,b[i],zVal),c); gr->AddPntQ(iq+2,mglPoint(x1,b[i+n],zVal),c); gr->AddPntQ(iq+3,mglPoint(x2,b[i+n],zVal),c); gr->AddPntQ(iq+4,mglPoint(x1,b[i+2*n],zVal),c); gr->AddPntQ(iq+5,mglPoint(x2,b[i+2*n],zVal),c); gr->AddPntQ(iq+6,mglPoint(x1,b[i+3*n],zVal),c); gr->AddPntQ(iq+7,mglPoint(x2,b[i+3*n],zVal),c); gr->AddPntQ(iq+8,mglPoint(x1,b[i+4*n],zVal),c); gr->AddPntQ(iq+9,mglPoint(x2,b[i+4*n],zVal),c); gr->AddPntQ(iq+10,mglPoint(x1,b[i+n],zVal),c); //vertical lines gr->AddPntQ(iq+11,mglPoint(x1,b[i+3*n],zVal),c); gr->AddPntQ(iq+12,mglPoint(x2,b[i+n],zVal),c); gr->AddPntQ(iq+13,mglPoint(x2,b[i+3*n],zVal),c); gr->AddPntQ(iq+14,mglPoint((x1+x2)/2,b[i],zVal),c); gr->AddPntQ(iq+15,mglPoint((x1+x2)/2,b[i+n],zVal),c); gr->AddPntQ(iq+16,mglPoint((x1+x2)/2,b[i+3*n],zVal),c); gr->AddPntQ(iq+17,mglPoint((x1+x2)/2,b[i+4*n],zVal),c); } for(long i=0;iline_plot(kq+18*i+2*j, kq+18*i+2*j+1); delete []b; gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxplot(HMGL gr, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x); mgl_boxplot_xy(gr,&x,y,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxplot_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_boxplot_xy(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_boxplot_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_boxplot(_GR_,_DA_(y),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Error series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const char *pen, const char *opt) { long m,n=ey->GetNx(),pal; if(mgl_check_dim0(gr,x,y,ey,ex,"Error")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Error",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = ex->GetNy() > m ? ex->GetNy() : m; m = ey->GetNy() > m ? ey->GetNy() : m; bool sh = mglchr(pen,'!'); bool ma = mglchr(pen,'@'); char mk = gr->SetPenPal(pen,&pal); double zVal=gr->AdjustZMin(); gr->Reserve(5*n*m); if(ma && (mk==0 || !strchr("PXsSdD+xoOC",mk) )) mk = 'S'; gr->ResetMask(); mglPoint q(NAN,NAN); for(long j=0;jNeedStop()) break; long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; long m1 = jGetNy() ? j:0,m2 = jGetNy() ? j:0; gr->NextColor(pal); if(ma) { if(strchr("PXsS",mk)) // boundary of square { const long kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+4*i,mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+1,mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+2,mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+3,mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27); } for(long i=0;iline_plot(iq,iq+1); gr->line_plot(iq,iq+2); gr->line_plot(iq+3,iq+1); gr->line_plot(iq+3,iq+2); } } if(strchr("dD",mk)) { const long kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+4*i,mglPoint(vx, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+1,mglPoint(vx-ve, vy, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+2,mglPoint(vx, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+3,mglPoint(vx+ve, vy, zVal),c,q,-1,27); } for(long i=0;iline_plot(iq,iq+1); gr->line_plot(iq+1,iq+2); gr->line_plot(iq+2,iq+3); gr->line_plot(iq+3,iq); } } if(strchr("oOC",mk)) { const long kq = gr->AllocPnts(40*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; for(long k=0;k<40;k++) gr->AddPntQ(kq+40*i+k,mglPoint(vx+ve*mgl_cos[(18*k)%360], vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,27); } for(long i=0;iline_plot(iq+39,iq); for(long k=1;k<40;k++) gr->line_plot(iq+k-1,iq+k); } } long kq; switch(mk) { case 'P': case '+': kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+4*i,mglPoint(vx, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+1,mglPoint(vx-ve, vy, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+2,mglPoint(vx, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+3,mglPoint(vx+ve, vy, zVal),c,q,-1,27); } for(long i=0;iline_plot(iq,iq+2); gr->line_plot(iq+1,iq+3); } break; case 'X': case 'x': kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+4*i,mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+1,mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+2,mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+3,mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27); } for(long i=0;iline_plot(iq,iq+3); gr->line_plot(iq+1,iq+2); } break; case 'S': kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+4*i,mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+1,mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+2,mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+3,mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27); } for(long i=0;iquad_plot(iq,iq+1,iq+2,iq+3); } break; case 'D': kq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; gr->AddPntQ(kq+4*i,mglPoint(vx, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+1,mglPoint(vx-ve, vy, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+2,mglPoint(vx, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(kq+4*i+3,mglPoint(vx+ve, vy, zVal),c,q,-1,27); } for(long i=0;iquad_plot(iq,iq+3,iq+1,iq+2); } break; case 'O': kq = gr->AllocPnts(41*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; long iq = kq+41*i+1; gr->AddPntQ(iq-1,mglPoint(vx,vy,zVal),c); for(long k=0;k<40;k++) gr->AddPntQ(iq+k,mglPoint(vx+ve*mgl_cos[(18*k)%360], vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,27); } for(long i=0;itrig_plot(iq-1,iq+39,iq); for(long k=1;k<40;k++) gr->trig_plot(iq-1,iq+k-1,iq+k); } break; case 'C': for(long i=0;imark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),zVal),-1,q,-1,3), '.'); if(sh) gr->NextColor(pal); } } } else { const long nq = mk?5:4, kq = gr->AllocPnts(nq*n); #pragma omp parallel for for(long i=0;iv(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2); double c = sh ? gr->NextColor(pal,i):gr->CDef; long iq = kq + nq*i; gr->AddPntQ(iq,mglPoint(vx, vy+vf, zVal),c,q,-1,27); gr->AddPntQ(iq+1,mglPoint(vx, vy-vf, zVal),c,q,-1,27); gr->AddPntQ(iq+2,mglPoint(vx+ve, vy, zVal),-1,q,c,27); gr->AddPntQ(iq+3,mglPoint(vx-ve, vy, zVal),-1,q,c,27); if(mk) gr->AddPntQ(iq+4,mglPoint(vx,vy,zVal),c); } for(long i=0;imark_plot(iq+4, mk); gr->line_plot(iq,iq+1); gr->line_plot(iq+2,iq+3); gr->arrow_plot(iq,iq+1,'I'); gr->arrow_plot(iq+1,iq,'I'); gr->arrow_plot(iq+2,iq+3,'I'); gr->arrow_plot(iq+3,iq+2,'I'); } } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_xy(HMGL gr, HCDT x, HCDT y, HCDT ey, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV ex(y->GetNx()); ex.Fill(NAN); mgl_error_exy(gr,x,y,&ex,ey,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error(HMGL gr, HCDT y, HCDT ey, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()), ex(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x); ex.Fill(NAN); mgl_error_exy(gr,&x,y,&ex,ey,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_(uintptr_t *gr, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_error(_GR_,_DA_(y),_DA_(ey),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_error_xy(_GR_,_DA_(x),_DA_(y),_DA_(ey),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_error_exy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ex, uintptr_t *ey, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_error_exy(_GR_,_DA_(x),_DA_(y),_DA_(ex),_DA_(ey),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Chart series // //----------------------------------------------------------------------------- void face_plot(mglBase *gr, mglPoint o, mglPoint d1, mglPoint d2, double c, bool wire) { const int num=10; mglPoint nn=d1^d2; d1 = d1/num; d2 = d2/num; const long n=num+1, kq = gr->AllocPnts(n*n); #pragma omp parallel for for(long j=0;jAddPntQ(kq+i+n*j,o+d1*i+d2*j,c,nn); for(long j=0;jquad_plot(ii,ii+1,ii+n,ii+n+1); } if(wire) { gr->SetPenPal("k-"); const long jq = gr->AllocPnts(4*n); #pragma omp parallel for for(long i=0;iCopyNtoC(jq+4*i,kq+i,gr->CDef); gr->CopyNtoC(jq+4*i+1,kq+n*i,gr->CDef); gr->CopyNtoC(jq+4*i+2,kq+n*n-1-i,gr->CDef); gr->CopyNtoC(jq+4*i+3,kq+n*n-1-n*i,gr->CDef); } for(long i=0;iline_plot(jj+4,jj); gr->line_plot(jj+5,jj+1); gr->line_plot(jj+6,jj+2); gr->line_plot(jj+7,jj+3); } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_chart(HMGL gr, HCDT a, const char *cols, const char *opt) { if(a->Minimal()<0) { gr->SetWarn(mglWarnNeg,"Chart"); return; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("Chart",cgid++); bool wire = mglchr(cols,'#'); // draw edges long n=a->GetNx(),i,j=0,len=cols?long(strlen(cols)):0; if(cols) for(i=0;iAddTexture(cols[i]); nc++; } // NOTE: nc>0 since j>0 or MGL_DEF_PAL is not empty double dy = (gr->Max.y-gr->Min.y)/a->GetNy(), dx, ss, cs, x1, y1, dz=gr->Max.z-gr->Min.z, vv; mglPoint d1,d2,o; for(j=0;jGetNy();j++) { if(gr->NeedStop()) break; y1 = gr->Min.y + dy*j; for(i=0,ss=0;iv(i,j); if(ss==0) continue; for(cs=0,i=0;iv(i,j); dx = vv/ss; cc = c[i%nc]; if(dx==0) continue; x1 = gr->Min.x + (gr->Max.x-gr->Min.x)*cs/ss; dx *= (gr->Max.x-gr->Min.x); if(cc>=0) { face_plot(gr,mglPoint(x1,y1,gr->Min.z),mglPoint(dx,0,0),mglPoint(0,0,dz),cc,wire); face_plot(gr,mglPoint(x1,y1,gr->Min.z),mglPoint(dx,0,0),mglPoint(0,dy,0),cc,wire); face_plot(gr,mglPoint(x1,y1,gr->Min.z),mglPoint(0,dy,0),mglPoint(0,0,dz),cc,wire); face_plot(gr,mglPoint(x1+dx,y1+dy,gr->Max.z),mglPoint(-dx,0,0),mglPoint(0,0,-dz),cc,wire); face_plot(gr,mglPoint(x1+dx,y1+dy,gr->Max.z),mglPoint(-dx,0,0),mglPoint(0,-dy,0),cc,wire); face_plot(gr,mglPoint(x1+dx,y1+dy,gr->Max.z),mglPoint(0,-dy,0),mglPoint(0,0,-dz),cc,wire); } cs += vv; } } gr->EndGroup(); delete []c; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_chart_(uintptr_t *gr, uintptr_t *a, const char *col, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,col,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_chart(_GR_, _DA_(a), s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Mark series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt) { long m,n=y->GetNx(),pal; if(mgl_check_dim0(gr,x,y,z,r,"Mark")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Mark",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; char mk=gr->SetPenPal(pen,&pal); gr->Reserve(n*m); if(mk==0) mk='.'; bool sh = mglchr(pen,'!'); int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1; for(long j=0;jNeedStop()) break; gr->NextColor(pal); long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; long mz = jGetNy() ? j:0, mr = jGetNy() ? j:0; const long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;iNextColor(pal,i):gr->CDef; gr->AddPntQ(kq+i,mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz)),c); } for(long i=0;imark_plot(kq+i, mk, fabs(r->v(i,mr))); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_xy(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_mark_xyz(gr,x,y,&z,r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_y(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt) { long n=y->GetNx(); gr->SaveState(opt); mglDataV x(n), z(n); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_mark_xyz(gr,&x,y,&z,r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_mark_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_mark_xy(_GR_, _DA_(x), _DA_(y), _DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mark_y_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_mark_y(_GR_,_DA_(y),_DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Tube series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt) { long m,n=y->GetNx(),pal; if(mgl_check_dim1(gr,x,y,z,r,"Tube")) return; mreal rnum = gr->SaveState(opt); static int cgid=1; gr->StartGroup("Tube",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; m = r->GetNy() > m ? r->GetNy() : m; bool sh = mglchr(pen,'!'); bool wire = mglchr(pen,'#'); int num = rnum>2?rnum:!(gr->GetQuality()&3)?13:25; gr->SetPenPal(pen,&pal); gr->Reserve(n*m*num); for(long j=0;jNeedStop()) break; gr->NextColor(pal); const long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; const long mz = jGetNy() ? j:0, mr = jGetNy() ? j:0; const long kq = gr->AllocPnts(n*num); #pragma omp parallel for collapse(2) for(long i=0;idvx(i,mx),y->dvx(i,my),z->dvx(i,mz)); mglPoint t(!l); t.Normalize(); mglPoint u(t^l); u.Normalize(); const mglPoint q(x->v(i,mx),y->v(i,my),z->v(i,mz)); const double rr=r->v(i,mr), dr=r->dvx(i,mr); const double c = sh ? gr->NextColor(pal,i):gr->CDef; const int kk = k*360/(num-1); const float co = mgl_cos[kk%360], si = mgl_cos[(270+kk)%360]; const mglPoint p(q + t*(rr*co) + u*(rr*si)); const mglPoint d((t*si - u*co)^(l + t*(dr*co) + u*(dr*si))); gr->AddPntQ(kq+num*i+k, p,c,wire?mglPoint(NAN,NAN):d,-1,3); } if(!wire) for(long i=1;iquad_plot(jj,jj-1,jj-num,jj-num-1); } if(wire) { for(long i=1;iline_plot(jj,jj-num); } for(long i=0;iline_plot(jj,jj-1); } } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xyr(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_tube_xyzr(gr,x,y,&z,r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_r(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Tube"); return; } gr->SaveState(opt); mglDataV x(n), z(n); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_tube_xyzr(gr,&x,y,&z,r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube(HMGL gr, HCDT y, double rr, const char *pen, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Tube"); return; } gr->SaveState(opt); mglDataV x(n), r(n), z(n); x.Fill(gr->Min.x,gr->Max.x); r.Fill(rr); z.Fill(gr->AdjustZMin()); mgl_tube_xyzr(gr,&x,y,&z,&r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xy(HMGL gr, HCDT x, HCDT y, double rr, const char *pen, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Tube"); return; } gr->SaveState(opt); mglDataV r(n), z(n); r.Fill(rr); z.Fill(gr->AdjustZMin()); mgl_tube_xyzr(gr,x,y,&z,&r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, double rr, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV r(y->GetNx()); r.Fill(rr); mgl_tube_xyzr(gr,x,y,z,&r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xyzr_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tube_xyzr(_GR_,_DA_(x),_DA_(y),_DA_(z), _DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xyr_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tube_xyr(_GR_,_DA_(x),_DA_(y),_DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_r_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tube_r(_GR_,_DA_(y),_DA_(r),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, mreal *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tube_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),*r,s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, mreal *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tube_xy(_GR_,_DA_(x),_DA_(y),*r,s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tube_(uintptr_t *gr, uintptr_t *y, mreal *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tube(_GR_,_DA_(y),*r,s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- // // Tape series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tape_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt) { long m,n=y->GetNx(),pal; if(mgl_check_dim1(gr,x,y,z,0,"Tape")) return; static int cgid=1; gr->StartGroup("Tape",cgid++); double rr = gr->SaveState(opt); if(rr==0 || mgl_isnan(rr)) rr = mgl_norm(gr->Max-gr->Min)*gr->BarWidth/25; m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; gr->SetPenPal(pen,&pal); gr->Reserve(4*n*m); mglPoint qn(NAN,NAN); bool sh = mglchr(pen,'!'), xo = mglchr(pen,'x'), zo = mglchr(pen,'z'), wire = mglchr(pen,'#'); if(!xo && !zo) xo = zo = true; int nv = xo && zo ? 4:2; for(long j=0;jNeedStop()) break; double c1=gr->NextColor(pal), c2=c1; if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal); long mx = jGetNy() ? j:0, my = jGetNy() ? j:0, mz = jGetNy() ? j:0; const long kq = gr->AllocPnts(nv*n); // TODO: use AddPntQ() -- problem is vector q1 // initial values for normales mglPoint p2(x->v(0,mx), y->v(0,my), z->v(0,mz)); mglPoint l(x->v(1,mx)-p2.x, y->v(1,my)-p2.y, z->v(1,mz)-p2.z); l /= mgl_norm(l); mglPoint q1(-l.y,l.x,0); double ll = mgl_norm(q1); if(ll) q1 /= ll; else q1.Set(0,1,0); mglPoint q2(q1^l); if(xo&&zo) { gr->AddPntQ(kq,p2,c1,q2,-1,3); gr->AddPntQ(kq+1,p2+rr*q1,c1,q2,-1,3); gr->AddPntQ(kq+2,p2,c2,q1,-1,3); gr->AddPntQ(kq+3,p2+rr*q2,c2,q1,-1,3); } else if(xo) { gr->AddPntQ(kq,p2,c1,q2,-1,3); gr->AddPntQ(kq+1,p2+rr*q1,c1,q2,-1,3); } else { gr->AddPntQ(kq,p2,c2,q1,-1,3); gr->AddPntQ(kq+1,p2+rr*q2,c2,q1,-1,3); } for(long i=1;iv(i,mx), y->v(i,my), z->v(i,mz)); l = p2-p1; l /= mgl_norm(l); q1 -= l*(l*q1); q1/= mgl_norm(q1); q2 = (q1^l); // NOTE: not thread safe!!! if(sh) c2=c1=gr->NextColor(pal,i); // NOTE: not thread safe long iq = kq+nv*i; if(xo&&zo) { gr->AddPntQ(iq,p2,c1,q2,-1,3); gr->AddPntQ(iq+1,p2+rr*q1,c1,q2,-1,3); gr->AddPntQ(iq+2,p2,c2,q1,-1,3); gr->AddPntQ(iq+3,p2+rr*q2,c2,q1,-1,3); } else if(xo) { gr->AddPntQ(iq,p2,c1,q2,-1,3); gr->AddPntQ(iq+1,p2+rr*q1,c1,q2,-1,3); } else { gr->AddPntQ(iq,p2,c2,q1,-1,3); gr->AddPntQ(iq+1,p2+rr*q2,c2,q1,-1,3); } } if(wire) { if(xo&&zo) for(long i=1;iline_plot(iq-nv,iq); gr->line_plot(iq-nv+2,iq+2); } else for(long i=1;iline_plot(iq-nv,iq); } } else { if(xo&&zo) for(long i=1;iquad_plot(iq,iq+1,iq-nv,iq-nv+1); gr->quad_plot(iq+2,iq+3,iq-nv+2,iq-nv+3); } else for(long i=1;iquad_plot(iq,iq+1,iq-nv,iq-nv+1); } } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tape_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_tape_xyz(gr,x,y,&z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tape(HMGL gr, HCDT y, const char *pen, const char *opt) { long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,"Plot"); return; } gr->SaveState(opt); mglDataV x(n), z(n); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_tape_xyz(gr,&x,y,&z,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tape_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tape_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tape_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tape_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tape_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tape(_GR_, _DA_(y),s,o); delete []s; delete []o; } //----------------------------------------------------------------------------- // // Pmap series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pmap_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt) { long m,n=y->GetNx(),pal; if(mgl_check_dim0(gr,x,y,z,r,"Mark")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Mark",cgid++); m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m; char mk=gr->SetPenPal(pen,&pal); gr->Reserve(n*m); if(mk==0) mk='.'; for(long j=0;jNeedStop()) break; gr->NextColor(pal); long mx = jGetNy() ? j:0, my = jGetNy() ? j:0; long mz = jGetNy() ? j:0, mr = jGetNy() ? j:0; for(long i=0;iv(i,mr), r2 = r->v(i+1,mr); if(r1==0) gr->mark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz))), mk); if(r1*r2<0) { double d = r1/(r1-r2); mglPoint p(x->v(i,mx)*(1-d)+x->v(i+1,mx)*d, y->v(i,my)*(1-d)+y->v(i+1,my)*d, z->v(i,mz)*(1-d)+d*z->v(i+1,mz)); gr->mark_plot(gr->AddPnt(p), mk); } } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pmap_xy(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_pmap_xyz(gr,x,y,&z,r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pmap(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt) { long n=y->GetNx(); gr->SaveState(opt); mglDataV x(n), z(n); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_pmap_xyz(gr,&x,y,&z,r,pen,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pmap_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pmap_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pmap_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pmap_xy(_GR_, _DA_(x), _DA_(y), _DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_pmap_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_pmap(_GR_,_DA_(y),_DA_(r),s,o); delete []o; delete []s; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/data_io.cpp0000644000175000017500000014364013513030041016050 0ustar alastairalastair/*************************************************************************** * data_io.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #ifndef WIN32 #include #endif #include "mgl2/data.h" #include "mgl2/datac.h" #include "mgl2/eval.h" #include "mgl2/thread.h" #if MGL_HAVE_HDF5 //#define H5_NO_DEPRECATED_SYMBOLS #define H5_USE_16_API #include #endif #if MGL_HAVE_HDF4 #define intf hdf4_intf #include #undef intf #endif inline bool isn(char ch) {return ch=='\n';} HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector &head); //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_create_data() { return new mglData; } HMDT MGL_EXPORT mgl_create_data_size(long nx, long ny, long nz){ return new mglData(nx,ny,nz); } HMDT MGL_EXPORT mgl_create_data_file(const char *fname) { return new mglData(fname); } void MGL_EXPORT mgl_delete_data(HMDT d) { if(d) delete d; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_create_data_() { return uintptr_t(new mglData()); } uintptr_t MGL_EXPORT mgl_create_data_size_(int *nx, int *ny, int *nz) { return uintptr_t(new mglData(*nx,*ny,*nz)); } uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; uintptr_t r = uintptr_t(new mglData(s)); delete []s; return r; } void MGL_EXPORT mgl_delete_data_(uintptr_t *d) { if(_DT_) delete _DT_; } //----------------------------------------------------------------------------- void mglFromStr(HMDT d,char *buf,long NX,long NY,long NZ) { if(NX<1 || NY <1 || NZ<1) return; mgl_data_create(d, NX,NY,NZ); const std::string loc = setlocale(LC_NUMERIC, "C"); std::vector lines; std::vector > numbs; while(*buf && *buf<=' ') buf++; lines.push_back(buf); for(char *s=buf; *s; s++) if(isn(*s)) { lines.push_back(s+1); *s = 0; s++; } numbs.resize(lines.size()); long nl = long(lines.size()); #pragma omp parallel for for(long k=0;k=nb) break; if(b[j]=='#') { std::string id; if(j='a' && b[i]<='z') id.push_back(b[i]); d->SetColumnId(id.c_str()); break; } const char *s=b+j; while(j' ' && b[j]!=',' && b[j]!=';') j++; b[j]=0; numbs[k].push_back(strstr(s,"NAN")?NAN:atof(s)); } } long i=0, n=NX*NY*NZ; for(long k=0;k &vals = numbs[k]; long c = vals.size(); if(c>n-i) c = n-i; memcpy(d->a+i,&(vals[0]),c*sizeof(mreal)); i += c; } setlocale(LC_NUMERIC, loc.c_str()); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set(HMDT d, HCDT a) { if(!a) return; // d->temp = a->temp; d->s = a->s; d->func = a->func; d->o = a->o; mgl_data_create(d, a->GetNx(), a->GetNy(), a->GetNz()); const mglData *dd = dynamic_cast(a); // faster for mglData if(dd) // this one should be much faster memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(mreal)); else // very inefficient!!! #pragma omp parallel for collapse(3) for(long k=0;knz;k++) for(long j=0;jny;j++) for(long i=0;inx;i++) d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k); } void MGL_EXPORT mgl_data_set_(uintptr_t *d, uintptr_t *a) { mgl_data_set(_DT_,_DA_(a)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_values(HMDT d, const char *v,long NX,long NY,long NZ) { if(NX<1 || NY <1 || NZ<1) return; long n=strlen(v)+1; char *buf = new char[n]; memcpy(buf,v,n); mglFromStr(d,buf,NX,NY,NZ); delete []buf; } void MGL_EXPORT mgl_data_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l) { char *s=new char[l+1]; memcpy(s,val,l); s[l]=0; mgl_data_set_values(_DT_,s,*nx,*ny,*nz); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_vector(HMDT d, gsl_vector *v) { #if MGL_HAVE_GSL if(!v || v->size<1) return; mgl_data_create(d, v->size,1,1); #pragma omp parallel for for(long i=0;inx;i++) d->a[i] = v->data[i*v->stride]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_matrix(HMDT d, gsl_matrix *m) { #if MGL_HAVE_GSL if(!m || m->size1<1 || m->size2<1) return; mgl_data_create(d, m->size1,m->size2,1); #pragma omp parallel for collapse(2) for(long j=0;jny;j++) for(long i=0;inx;i++) d->a[i+j*d->nx] = m->data[i * m->tda + j]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_float(HMDT d, const float *A,long NX,long NY,long NZ) { if(NX<=0 || NY<=0 || NZ<=0) return; mgl_data_create(d, NX,NY,NZ); if(!A) return; #if MGL_USE_DOUBLE #pragma omp parallel for for(long i=0;ia[i] = A[i]; #else memcpy(d->a,A,NX*NY*NZ*sizeof(float)); #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_double(HMDT d, const double *A,long NX,long NY,long NZ) { if(NX<=0 || NY<=0 || NZ<=0) return; mgl_data_create(d, NX,NY,NZ); if(!A) return; #if MGL_USE_DOUBLE memcpy(d->a,A,NX*NY*NZ*sizeof(double)); #else #pragma omp parallel for for(long i=0;ia[i] = A[i]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_float2(HMDT d, float const * const *A,long N1,long N2) { if(N1<=0 || N2<=0) return; mgl_data_create(d, N2,N1,1); if(!A) return; #if MGL_USE_DOUBLE #pragma omp parallel for collapse(2) for(long i=0;ia[j+i*N2] = A[i][j]; #else #pragma omp parallel for for(long i=0;ia+i*N2,A[i],N2*sizeof(float)); #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_double2(HMDT d, double const *const *A,long N1,long N2) { if(N1<=0 || N2<=0) return; mgl_data_create(d, N2,N1,1); if(!A) return; #if MGL_USE_DOUBLE #pragma omp parallel for for(long i=0;ia+i*N2,A[i],N2*sizeof(double)); #else #pragma omp parallel for collapse(2) for(long i=0;ia[j+i*N2] = A[i][j]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_float3(HMDT d, float const * const * const *A,long N1,long N2,long N3) { if(N1<=0 || N2<=0 || N3<=0) return; mgl_data_create(d, N3,N2,N1); if(!A) return; #if MGL_USE_DOUBLE #pragma omp parallel for collapse(3) for(long i=0;ia[k+N3*(j+i*N2)] = A[i][j][k]; #else #pragma omp parallel for collapse(2) for(long i=0;ia+N3*(j+i*N2),A[i][j],N3*sizeof(float)); #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_double3(HMDT d, double const * const * const *A,long N1,long N2,long N3) { if(N1<=0 || N2<=0 || N3<=0) return; mgl_data_create(d, N3,N2,N1); if(!A) return; #if MGL_USE_DOUBLE #pragma omp parallel for collapse(2) for(long i=0;ia+N3*(j+i*N2),A[i][j],N3*sizeof(double)); #else #pragma omp parallel for collapse(3) for(long i=0;ia[k+N3*(j+i*N2)] = A[i][j][k]; #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_float1_(uintptr_t *d, const float *A,int *NX) { mgl_data_set_float(_DT_,A,*NX,1,1); } void MGL_EXPORT mgl_data_set_double1_(uintptr_t *d, const double *A,int *NX) { mgl_data_set_double(_DT_,A,*NX,1,1); } void MGL_EXPORT mgl_data_set_float_(uintptr_t *d, const float *A,int *NX,int *NY,int *NZ) { mgl_data_set_float(_DT_,A,*NX,*NY,*NZ); } void MGL_EXPORT mgl_data_set_double_(uintptr_t *d, const double *A,int *NX,int *NY,int *NZ) { mgl_data_set_double(_DT_,A,*NX,*NY,*NZ); } void MGL_EXPORT mgl_data_set_float2_(uintptr_t *d, const float *A,int *N1,int *N2) { mgl_data_set_float(_DT_,A,*N1,*N2,1); } void MGL_EXPORT mgl_data_set_double2_(uintptr_t *d, const double *A,int *N1,int *N2) { mgl_data_set_double(_DT_,A,*N1,*N2,1); } void MGL_EXPORT mgl_data_set_float3_(uintptr_t *d, const float *A,int *N1,int *N2,int *N3) { mgl_data_set_float(_DT_,A,*N1,*N2,*N3); } void MGL_EXPORT mgl_data_set_double3_(uintptr_t *d, const double *A,int *N1,int *N2,int *N3) { mgl_data_set_double(_DT_,A,*N1,*N2,*N3); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_rearrange(HMDT d, long mx,long my,long mz) { if(mx<1) return; // wrong mx if(my<1) { my = d->nx*d->ny*d->nz/mx; mz = 1; } else if(mz<1) mz = (d->nx*d->ny*d->nz)/(mx*my); long m = mx*my*mz; if(m==0 || m>d->nx*d->ny*d->nz) return; // too high desired dimensions d->nx = mx; d->ny = my; d->nz = mz; d->NewId(); } void MGL_EXPORT mgl_data_rearrange_(uintptr_t *d, int *mx, int *my, int *mz) { mgl_data_rearrange(_DT_,*mx,*my,*mz); } //----------------------------------------------------------------------------- MGL_EXPORT_PURE const char *mgl_data_get_id(HCDT d) { return d->id.s; } void MGL_EXPORT mgl_data_set_id(mglDataA *d, const char *ids) { d->id = ids; } void MGL_EXPORT mgl_data_set_id_(uintptr_t *d, const char *eq,int l) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; mgl_data_set_id(_DT_, s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_name_w(mglDataA *dat, const wchar_t *name) { dat->s = name; } MGL_EXPORT_PURE const wchar_t *mgl_data_get_name_w(HCDT dat) { return dat->s.w; } void MGL_EXPORT mgl_data_set_name(mglDataA *dat, const char *name) { MGL_TO_WCS(name,dat->Name(wcs)); } void MGL_EXPORT mgl_data_set_name_(uintptr_t *d, const char *name,int l) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; mgl_data_set_name(_DT_,s); delete []s; } void MGL_EXPORT mgl_data_set_func(mglDataA *dat, void (*func)(void *), void *par) { dat->func = func; dat->o = par; } //----------------------------------------------------------------------------- /// Get section separated by symbol ch. This is analog of QString::section(). std::vector MGL_EXPORT mgl_str_args(const std::string &str, char ch) { std::vector pos; pos.push_back(0); for(size_t p=0; p != std::string::npos;) { p=str.find(ch,p+1); pos.push_back(p?p+1:0); } std::vector res; for(size_t i=0;i pos; pos.push_back(0); for(size_t p=0; p != std::string::npos;) { p=str.find(ch,p+1); pos.push_back(p?p+1:0); } std::string res; if(n2<0) n2=n1; if(n1<0 || n1>=long(pos.size())-1 || n2=long(pos.size())) n2=pos.size()-1; res = str.substr(pos[n1],pos[n2+1]-pos[n1]-1); if(res.size()==1 && res[0]==ch) res.clear(); return res; } //----------------------------------------------------------------------------- /// Get string from number. std::string MGL_EXPORT mgl_str_num(double val) { char buf[32]; snprintf(buf,32,"%g",val); return std::string(buf); } std::string MGL_EXPORT mgl_str_num(dual val) { char buf[64]; double re = real(val), im = imag(val); if(re==0 && im>0) snprintf(buf,64,"i%g",im); else if(re && im<0) snprintf(buf,64,"-i%g",-im); else if(im>0) snprintf(buf,64,"%g+i%g",re,im); else if(im<0) snprintf(buf,64,"%g-i%g",re,-im); else snprintf(buf,64,"%g",re); return std::string(buf); } //----------------------------------------------------------------------------- std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns) { long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz(); const std::string loc = setlocale(LC_NUMERIC, "C"); std::string out; if(ns<0 || (ns>=nz && nz>1)) for(long k=0;kGetColumnId(); if(!id.empty()) out += "## "+id+'\n'; for(long i=0;iv(j,i,k))+'\t'; out += mgl_str_num(d->v(nx-1,i,k))+'\n'; } out += "\n"; } else { // save selected slice if(nz>1) for(long i=0;iv(j,i,ns))+'\t'; out += mgl_str_num(d->v(nx-1,i,ns))+'\n'; } else if(nsv(j,ns))+'\t'; } setlocale(LC_NUMERIC, loc.c_str()); return out; } void MGL_EXPORT mgl_data_save(HCDT d, const char *fname,long ns) { FILE *fp = fopen(fname,"w"); if(fp) { fprintf(fp,"%s",mgl_data_to_string(d,ns).c_str()); fclose(fp); } } void MGL_EXPORT mgl_data_save_(uintptr_t *d, const char *fname,int *ns,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; mgl_data_save(_DT_,s,*ns); delete []s; } //----------------------------------------------------------------------------- MGL_NO_EXPORT char *mgl_read_gz(gzFile fp) { long size=1024,n=0,m; char *buf=(char*)malloc(size); while((m=gzread(fp,buf+size*n,size))>0) { if(ma) mgl_data_create(d, 1,1,1); return 0; } char *buf = mgl_read_gz(fp), *tbuf=buf; while(*buf && *buf<=' ') buf++; // remove leading spaces long nb = strlen(buf); gzclose(fp); bool first=false; for(i=nb-1;i>=0;i--) if(buf[i]>' ') break; buf[i+1]=0; nb = i+1; // remove tailing spaces for(i=0;i' ' && !first) first=true; if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && buf[i+1]>' ') k++; } first = false; for(i=0;i strs; for(size_t i=0;buf[i];i++) { if(buf[i]=='%' && buf[i+1]=='%') i++; else if(buf[i]=='%' && buf[i+1]=='g') { buf[i]=0; strs.push_back(s); s = buf+i+2; } } delete []buf; if(strs.size()<1) return 0; // read proper lines from file std::vector bufs; gzFile fp = gzopen(fname,"r"); if(!fp) { if(!d->a) mgl_data_create(d, 1,1,1); return 0; } s = mgl_read_gz(fp); gzclose(fp); size_t len = strs[0].length(); const char *s0 = strs[0].c_str(); if(!strncmp(s, s0, len)) bufs.push_back(s); for(long i=0;s[i];i++) if(s[i]=='\n') { while(s[i+1]=='\n') i++; s[i]=0; i++; if(!strncmp(s+i, s0, len)) bufs.push_back(s+i); if(!s[i]) break; } // parse lines and collect data size_t nx=strs.size(), ny=bufs.size(); if(ny<1) { if(!d->a) mgl_data_create(d, 1,1,1); return 0; } d->Create(nx,ny); for(size_t j=0;ja[i+nx*j] = atof(p); } } free(s); return 1; } int MGL_EXPORT mgl_data_scan_file_(uintptr_t *d,const char *fname, const char *templ,int l,int m) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *t=new char[m+1]; memcpy(t,templ,m); t[m]=0; int r = mgl_data_scan_file(_DT_, s,t); delete []s; delete []t; return r; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_create(HMDT d,long mx,long my,long mz) { d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1; if(d->a && !d->link) delete [](d->a); d->a = new mreal[d->nx*d->ny*d->nz]; d->NewId(); d->link=false; memset(d->a,0,d->nx*d->ny*d->nz*sizeof(mreal)); } void MGL_EXPORT mgl_data_create_(uintptr_t *d, int *nx,int *ny,int *nz) { mgl_data_create(_DT_,*nx,*ny,*nz); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_link(HMDT d, mreal *A, long mx,long my,long mz) { if(!A) return; if(!d->link && d->a) delete [](d->a); d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1; d->link=true; d->a=A; d->NewId(); } void MGL_EXPORT mgl_data_link_(uintptr_t *d, mreal *A, int *nx,int *ny,int *nz) { mgl_data_link(_DT_,A,*nx,*ny,*nz); } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_data_read_dim(HMDT d, const char *fname,long mx,long my,long mz) { if(mx<=0 || my<=0 || mz<=0) return 0; gzFile fp = gzopen(fname,"r"); if(!fp) return 0; char *buf = mgl_read_gz(fp); gzclose(fp); mglFromStr(d,buf,mx,my,mz); free(buf); return 1; } int MGL_EXPORT mgl_data_read_dim_(uintptr_t *d, const char *fname,int *mx,int *my,int *mz,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; int r = mgl_data_read_dim(_DT_,s,*mx,*my,*mz); delete []s; return r; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_data_read_mat(HMDT d, const char *fname, long dim) { if(dim<=0 || dim>3) return 0; gzFile fp = gzopen(fname,"r"); if(!fp) return 0; long nx=1, ny=1, nz=1; char *buf = mgl_read_gz(fp); long nb = strlen(buf); gzclose(fp); long j=0; if(buf[j]=='#') while(!isn(buf[j])) j++; // skip comment while(j' ') j++; } else if(dim==2) { sscanf(buf+j,"%ld%ld",&nx,&ny); while(j' ' && !first) first=true; if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && b[i+1]>' ') nx++; } } } else if(dim==3) { sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz); while(j' ' && j' ' && j' ' && jGetNN(); #pragma omp parallel { mreal m=-INFINITY; #pragma omp for nowait for(long i=0;ivthr(i); m = mm ? m1:m; } } return m1; } mreal MGL_EXPORT mgl_data_max_(uintptr_t *d) { return mgl_data_max(_DT_); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_min(HCDT d) { mreal m1=INFINITY; long nn=d->GetNN(); #pragma omp parallel { mreal m=INFINITY; #pragma omp for nowait for(long i=0;ivthr(i); m = m>v ? v:m; } #pragma omp critical(min_dat) { m1 = m1GetNN(); #pragma omp parallel { mreal m=0; #pragma omp for nowait for(long i=0;ivthr(i); m = mm ? m1:m; } } return m1; } mreal MGL_EXPORT mgl_data_neg_max_(uintptr_t *d) { return mgl_data_neg_max(_DT_); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_pos_min(HCDT d) { mreal m1=INFINITY; long nn=d->GetNN(); #pragma omp parallel { mreal m=INFINITY; #pragma omp for nowait for(long i=0;ivthr(i); m = m>v && v>0 ? v:m; } #pragma omp critical(pmin_dat) { m1 = m1GetNx(), ny=d->GetNy(), nn=d->GetNN(); #pragma omp parallel { mreal m=-INFINITY; long im=-1,jm=-1,km=-1; #pragma omp for nowait for(long ii=0;iivthr(ii); if(m < v) { m=v; im=ii%nx; jm=(ii/nx)%ny; km=ii/(nx*ny); } } #pragma omp critical(max_int) if(m1 < m) { m1=m; *i=im; *j=jm; *k=km; } } return m1; } mreal MGL_EXPORT mgl_data_max_int_(uintptr_t *d, int *i, int *j, int *k) { long ii,jj,kk; mreal res=mgl_data_max_int(_DT_,&ii,&jj,&kk); *i=ii; *j=jj; *k=kk; return res; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_min_int(HCDT d, long *i, long *j, long *k) { mreal m1=INFINITY; long nx=d->GetNx(), ny=d->GetNy(), nn=d->GetNN(); #pragma omp parallel { mreal m=INFINITY; long im=-1,jm=-1,km=-1; #pragma omp for nowait for(long ii=0;iivthr(ii); if(m > v) { m=v; im=ii%nx; jm=(ii/nx)%ny; km=ii/(nx*ny); } } #pragma omp critical(min_int) if(m1 > m) { m1=m; *i=im; *j=jm; *k=km; } } return m1; } mreal MGL_EXPORT mgl_data_min_int_(uintptr_t *d, int *i, int *j, int *k) { long ii,jj,kk; mreal res=mgl_data_min_int(_DT_,&ii,&jj,&kk); *i=ii; *j=jj; *k=kk; return res; } //----------------------------------------------------------------------------- long MGL_EXPORT mgl_data_max_first(HCDT d, char dir, long from, long *p1, long *p2) { long n=d->GetNx(), n1=d->GetNy(), n2=d->GetNz(), d1=n, d2=n*n1, dd=1; if(dir=='y') { n=n1; n1=dd=d1; d1=1; } if(dir=='z') { n=n2; n2=n1; n1=d1; d1=1; dd=d2; d2=n2; } bool find=false; if(from>=0) { for(long i=from+1;ivthr(ii)>=d->vthr(ii+dd) && d->vthr(ii)>=d->vthr(ii-dd)) { find=true; if(p1) *p1=i1; if(p2) *p2=i2; } } if(find) return i; } } else { for(long i=n+from-1;i>0;i--) { for(long i1=0;i1vthr(ii)>=d->vthr(ii+dd) && d->vthr(ii)>=d->vthr(ii-dd)) { find=true; if(p1) *p1=i1; if(p2) *p2=i2; } } if(find) return i; } } return -1; } long MGL_EXPORT mgl_data_max_first_(uintptr_t *d, const char *dir, long *from, long *p1, long *p2,int) { return mgl_data_max_first(_DT_,*dir,*from,p1,p2); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_max_real(HCDT d, mreal *x, mreal *y, mreal *z) { long im=-1,jm=-1,km=-1; long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz(); mreal m=mgl_data_max_int(d,&im,&jm,&km), v, v1, v2; *x=im; *y=jm; *z=km; v = d->v(im,jm,km); if(nx>2) { if(im==0) im=1; if(im==nx-1)im=nx-2; v1 = d->v(im+1,jm,km); v2 = d->v(im-1,jm,km); *x = (v1+v2-2*v)==0 ? im : im+(v2-v1)/(v1+v2-2*v)/2; } if(ny>2) { if(jm==0) jm=1; if(jm==ny-1)jm=ny-2; v1 = d->v(im,jm+1,km); v2 = d->v(im,jm-1,km); *y = (v1+v2-2*v)==0 ? jm : jm+(v2-v1)/(v1+v2-2*v)/2; } if(nz>2) { if(km==0) km=1; if(km==nz-1)km=nz-2; v1 = d->v(im,jm,km+1); v2 = d->v(im,jm,km-1); *z = (v1+v2-2*v)==0 ? km : km+(v2-v1)/(v1+v2-2*v)/2; } return m; } mreal MGL_EXPORT mgl_data_max_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z) { return mgl_data_max_real(_DT_,x,y,z); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_min_real(HCDT d, mreal *x, mreal *y, mreal *z) { long im=-1,jm=-1,km=-1; long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz(); mreal m=mgl_data_min_int(d,&im,&jm,&km), v, v1, v2; *x=im; *y=jm; *z=km; v = d->v(im,jm,km); if(nx>2) { if(im==0) im=1; if(im==nx-1)im=nx-2; v1 = d->v(im+1,jm,km); v2 = d->v(im-1,jm,km); *x = (v1+v2-2*v)==0 ? im : im+(v2-v1)/(v1+v2-2*v)/2; } if(ny>2) { if(jm==0) jm=1; if(jm==ny-1)jm=ny-2; v1 = d->v(im,jm+1,km); v2 = d->v(im,jm-1,km); *y = (v1+v2-2*v)==0 ? jm : jm+(v2-v1)/(v1+v2-2*v)/2; } if(nz>2) { if(km==0) km=1; if(km==nz-1)km=nz-2; v1 = d->v(im,jm,km+1); v2 = d->v(im,jm,km-1); *z = (v1+v2-2*v)==0 ? km : km+(v2-v1)/(v1+v2-2*v)/2; } return m; } mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z) { return mgl_data_min_real(_DT_,x,y,z); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_fill(HMDT d, mreal x1,mreal x2,char dir) { if(mgl_isnan(x2)) x2=x1; if(dir<'x' || dir>'z') dir='x'; long nx=d->nx,ny=d->ny,nz=d->nz; if(dir=='x') { mreal dx = d->nx>1 ? (x2-x1)/(d->nx-1):0; #pragma omp parallel for collapse(2) for(long j=0;ja[i+nx*j] = x1+dx*i; #pragma omp parallel for for(long j=0;ja[nx*j] = x1; } if(dir=='y') { mreal dx = d->ny>1 ? (x2-x1)/(d->ny-1):0; #pragma omp parallel for collapse(3) for(long k=0;ka[i+nx*(j+ny*k)] = x1+dx*j; #pragma omp parallel for collapse(2) for(long j=0;ja[i+nx*ny*j] = x1; } if(dir=='z') { mreal dx = d->nz>1 ? (x2-x1)/(d->nz-1):0; #pragma omp parallel for collapse(2) for(long j=1;ja[i+nx*ny*j] = x1+dx*j; #pragma omp parallel for for(long j=0;ja[j] = x1; } } void MGL_EXPORT mgl_data_fill_(uintptr_t *d, mreal *x1,mreal *x2,const char *dir,int) { mgl_data_fill(_DT_,*x1,*x2,*dir); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_norm(HMDT d, mreal v1,mreal v2,int sym,long dim) { long s,nn=d->nx*d->ny*d->nz; mreal a1=INFINITY,a2=-INFINITY,v,*a=d->a; s = dim*d->ny*(d->nz>1 ? d->nx : 1); for(long i=s;ia[i] ? a[i]:a1; a2 = a2v2) { v=v1; v1=v2; v2=v; } // swap if uncorrect if(sym) // use symmetric { v2 = -v1>v2 ? -v1:v2; v1 = -v2; a2 = -a1>a2 ? -a1:a2; a1 = -a2; } v2 = (v2-v1)/(a2-a1); v1 = v1-a1*v2; #pragma omp parallel for for(long i=s;inx, ny=d->ny, nz=d->nz; mreal *b; // simple checking if(rx>=nx) rx=nx-1; if(rx<1) rx=1; if(ry>=ny) ry=ny-1; if(ry<1) ry=1; if(rz>=nz) rz=nz-1; if(rz<1) rz=1; // new sizes kx = 1+(nx-1)/rx; ky = 1+(ny-1)/ry; kz = 1+(nz-1)/rz; b = new mreal[kx*ky*kz]; if(!smooth) #pragma omp parallel for collapse(3) for(long k=0;ka[i*rx+nx*(j*ry+ny*rz*k)]; else #pragma omp parallel for collapse(3) for(long k=0;ka[i1+nx*(j1+ny*k1)]; b[i+kx*(j+ky*k)] = s/(dx*dy*dz); } if(!d->link) delete [](d->a); d->a=b; d->nx = kx; d->ny = ky; d->nz = kz; d->NewId(); d->link=false; } void MGL_EXPORT mgl_data_squeeze_(uintptr_t *d, int *rx,int *ry,int *rz,int *smooth) { mgl_data_squeeze(_DT_,*rx,*ry,*rz,*smooth); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_extend(HMDT d, long n1, long n2) { long nx=d->nx, ny=d->ny, nz=d->nz; if(nz>2 || n1==0) return; long mx, my, mz; mreal *b=0; if(n1>0) // extend to higher dimension(s) { n2 = n2>0 ? n2:1; mx = nx; my = ny>1?ny:n1; mz = ny>1 ? n1 : n2; b = new mreal[mx*my*mz]; if(ny>1) #pragma omp parallel for for(long i=0;ia, nx*ny*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ia, nx*sizeof(mreal)); } else { mx = -n1; my = n2<0 ? -n2 : nx; mz = n2<0 ? nx : ny; if(n2>0 && ny==1) mz = n2; b = new mreal[mx*my*mz]; if(n2<0) #pragma omp parallel for collapse(2) for(long j=0;ja[j]; else #pragma omp parallel for collapse(2) for(long j=0;ja[j]; if(n2>0 && ny==1) #pragma omp parallel for for(long i=0;ia, mx*my*sizeof(mreal)); } if(!d->link) delete [](d->a); d->a=b; d->nx=mx; d->ny=my; d->nz=mz; d->NewId(); d->link=false; } void MGL_EXPORT mgl_data_extend_(uintptr_t *d, int *n1, int *n2) { mgl_data_extend(_DT_,*n1,*n2); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_transpose(HMDT d, const char *dim) { long nx=d->nx, ny=d->ny, nz=d->nz, n; mreal *b=new mreal[nx*ny*nz], *a=d->a; if(!strcmp(dim,"xzy") || !strcmp(dim,"zy")) { #pragma omp parallel for collapse(3) for(long j=0;jnx; d->nx=nx; d->ny=ny; d->nz=nz; if(nx!=n) d->NewId(); } void MGL_EXPORT mgl_data_transpose_(uintptr_t *d, const char *dim,int l) { char *s=new char[l+1]; memcpy(s,dim,l); s[l]=0; mgl_data_transpose(_DT_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_modify(void *par) { mglThreadD *t=(mglThreadD *)par; const mglFormula *f = (const mglFormula *)(t->v); long nx=t->p[0],ny=t->p[1],nz=t->p[2]; mreal *b=t->a, dx,dy,dz; const mreal *v=t->b, *w=t->c; dx=nx>1?1/(nx-1.):0; dy=ny>1?1/(ny-1.):0; dz=nz>1?1/(nz-1.):0; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny); b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v[i0]:0, w?w[i0]:0); } return 0; } void MGL_EXPORT mgl_data_modify(HMDT d, const char *eq,long dim) { long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz}; if(dim<=0) mgl_data_modify_vw(d,eq,0,0); // fastes variant for whole array else if(nz>1) // 3D array { mglFormula f(eq); par[2] -= dim; if(par[2]<0) par[2]=0; mglStartThread(mgl_modify,0,nx*ny*par[2],d->a+nx*ny*dim,0,0,par,&f); } else // 2D or 1D array { mglFormula f(eq); par[1] -= dim; if(par[1]<0) par[1]=0; mglStartThread(mgl_modify,0,nx*par[1],d->a+nx*dim,0,0,par,&f); } } void MGL_EXPORT mgl_data_modify_(uintptr_t *d, const char *eq,int *dim,int l) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; mgl_data_modify(_DT_,s,*dim); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_modify_vw(HMDT d, const char *eq,HCDT vdat,HCDT wdat) { std::wstring s=d->Name(); d->Name(L"u"); mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.Name(L"x"); mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.Name(L"y"); mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.Name(L"z"); mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i"); mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j"); mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k"); mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl"); mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w"); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(d); list.push_back(&v); list.push_back(&w); list.push_back(&r); list.push_back(&i); list.push_back(&j); list.push_back(&k); d->Move(mglFormulaCalc(eq,list)); d->Name(s.c_str()); } void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; mgl_data_modify_vw(_DT_,s,_DA_(v),_DA_(w)); delete []s; } //----------------------------------------------------------------------------- #if MGL_HAVE_HDF4 int MGL_EXPORT mgl_data_read_hdf4(HMDT d,const char *fname,const char *data) { int32 sd = SDstart(fname,DFACC_READ), nn, i; if(sd==-1) return 0; // is not a HDF4 file char name[64]; SDfileinfo(sd,&nn,&i); for(i=0;i3) continue; long mm=dims[0]*dims[1]*dims[2]; if(type==DFNT_FLOAT32) { float *b = new float[mm]; SDreaddata(sds,in,0,dims,b); mgl_data_set_float(d,b,dims[2],dims[1],dims[0]); delete []b; } if(type==DFNT_FLOAT64) { double *b = new double[mm]; SDreaddata(sds,in,0,dims,b); mgl_data_set_double(d,b,dims[2],dims[1],dims[0]); delete []b; } } SDendaccess(sds); } SDend(sd); return 1; } #else int MGL_EXPORT mgl_data_read_hdf4(HMDT ,const char *,const char *) { mgl_set_global_warn(_("HDF4 support was disabled. Please, enable it and rebuild MathGL.")); return 0; } #endif //----------------------------------------------------------------------------- #if MGL_HAVE_HDF5 void MGL_EXPORT mgl_data_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite) { const mglData *d = dynamic_cast(dat); // NOTE: slow for non-mglData if(!d) { mglData d(dat); mgl_data_save_hdf(&d,fname,data,rewrite); return; } hid_t hf,hd,hs; hsize_t dims[3]; long rank = 3, res; H5Eset_auto(0,0); res=H5Fis_hdf5(fname); if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT); else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if(hf<0) return; if(d->nz==1 && d->ny == 1) { rank=1; dims[0]=d->nx; } else if(d->nz==1) { rank=2; dims[0]=d->ny; dims[1]=d->nx; } else { rank=3; dims[0]=d->nz; dims[1]=d->ny; dims[2]=d->nx; } hs = H5Screate_simple(rank, dims, 0); #if MGL_USE_DOUBLE hid_t mem_type_id = H5T_NATIVE_DOUBLE; #else hid_t mem_type_id = H5T_NATIVE_FLOAT; #endif hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT); H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, d->a); H5Dclose(hd); H5Sclose(hs); H5Fclose(hf); } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_data_read_hdf(HMDT d,const char *fname,const char *data) { hid_t hf,hd,hs; long rank, res = H5Fis_hdf5(fname); if(res<=0) return mgl_data_read_hdf4(d,fname,data); hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); if(hf<0) return 0; hd = H5Dopen(hf,data); if(hd<0) return 0; hs = H5Dget_space(hd); rank = H5Sget_simple_extent_ndims(hs); if(rank>0 && rank<=3) { hsize_t dims[3]; H5Sget_simple_extent_dims(hs,dims,0); if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; } else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; } // else if(rank>3) continue; mgl_data_create(d,dims[2],dims[1],dims[0]); #if MGL_USE_DOUBLE H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a); #else H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a); #endif } H5Sclose(hs); H5Dclose(hd); H5Fclose(hf); return 1; } //----------------------------------------------------------------------------- MGL_EXPORT const char * const * mgl_datas_hdf_str(const char *fname) { static std::vector names; static const char **res=0; hid_t hf,hg,hd,ht; hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); names.clear(); if(!hf) return 0; hg = H5Gopen(hf,"/"); hsize_t num; char name[256]; H5Gget_num_objs(hg, &num); // replace by H5G_info_t t; H5Gget_info(hg,&t); num=t.nlinks; for(hsize_t i=0;isize) return -long(len); strcpy(buf,res[0]); for(long i=1;inz==1) { if(kx==d->nx && d->ny==1) { b = (mreal *)realloc(b,kx*(ky+1)*sizeof(mreal)); memcpy(b+kx*ky,d->a,kx*sizeof(mreal)); ky++; } else if(kx==d->nx && ky==d->ny) { b = (mreal *)realloc(b,kx*ky*(kz+1)*sizeof(mreal)); memcpy(b+kx*ky*kz,d->a,kx*ky*sizeof(mreal)); kz++; } else return false; } else { if(d->ny*d->nz==1 && ky*kz==1) { b = (mreal *)realloc(b,(kx+d->nx)*sizeof(mreal)); memcpy(b+kx,d->a,d->nx*sizeof(mreal)); kx+=d->nx; } else if(kx==d->nx && kz==1 && d->nz==1) { b = (mreal *)realloc(b,kx*(ky+d->ny)*sizeof(mreal)); memcpy(b+kx*ky,d->a,kx*d->ny*sizeof(mreal)); ky+=d->ny; } else if(kx==d->nx && ky==d->ny) { b = (mreal *)realloc(b,kx*kx*(kz+d->nz)*sizeof(mreal)); memcpy(b+kx*ky*kz,d->a,kx*ky*d->nz*sizeof(mreal)); kz+=d->nz; } else return false; } return true; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_data_read_range(HMDT dat, const char *templ, double from, double to, double step, int as_slice) { mglData d; mreal t = from, *b; long kx,ky,kz,n=strlen(templ)+20; char *fname = new char[n]; //read first file do{ snprintf(fname,n,templ,t); fname[n-1]=0; t+= step; } while(!mgl_data_read(&d,fname) && t<=to); if(t>to) { delete []fname; return 0; } kx = d.nx; ky = d.ny; kz = d.nz; b = (mreal *)malloc(kx*ky*kz*sizeof(mreal)); memcpy(b,d.a,kx*ky*kz*sizeof(mreal)); // read other files for(;t<=to;t+=step) { snprintf(fname,n,templ,t); fname[n-1]=0; if(mgl_data_read(&d,fname)) if(!mgl_add_file(kx,ky,kz,b,&d,as_slice)) { delete []fname; free(b); return 0; } } dat->Set(b,kx,ky,kz); delete []fname; free(b); return 1; } int MGL_EXPORT mgl_data_read_range_(uintptr_t *d, const char *fname, mreal *from, mreal *to, mreal *step, int *as_slice,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; int r = mgl_data_read_range(_DT_,s,*from,*to,*step,*as_slice); delete []s; return r; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_data_read_all(HMDT dat, const char *templ, int as_slice) { #ifndef WIN32 mglData d; glob_t res; size_t i; mreal *b; long kx,ky,kz; glob (templ, GLOB_TILDE, NULL, &res); //read first file for(i=0;i=res.gl_pathc) { globfree (&res); return 0; } kx = d.nx; ky = d.ny; kz = d.nz; b = (mreal *)malloc(kx*ky*kz*sizeof(mreal)); memcpy(b,d.a,kx*ky*kz*sizeof(mreal)); for(;iSet(b,kx,ky,kz); globfree (&res); free(b); return 1; #else return 0; #endif } int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; int r = mgl_data_read_all(_DT_,s,*as_slice); delete []s; return r; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq) { std::vector list; const char *id = dat->GetColumnId(); size_t len = strlen(id); for(size_t i=0;iSetInd(i,id[i]); list.push_back(col); } if(list.size()==0) return 0; // no named columns mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz()); t->Name(L"#$mgl"); list.push_back(t); HMDT r = mglFormulaCalc(eq,list); for(size_t i=0;iGetNN(); mreal *a = d->a; #pragma omp parallel for for(long i=0;iv) a[i] *= v/b; } } void MGL_EXPORT mgl_data_limit_(uintptr_t *d, mreal *v) { mgl_data_limit(_DT_, *v); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_coil(HMDT d, mreal v1, mreal v2, int sep) { long n = d->GetNN(); if(mgl_isnan(v2)) v2=-v1; if(v2a, dv = v2-v1; if(dv==0) return; long *kk=new long[n]; #pragma omp parallel for for(long i=0;i * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/canvas.h" #include "mgl2/thread.h" #if MGL_HAVE_OMP #include #endif //----------------------------------------------------------------------------- void mglCanvas::pxl_primpx(long id, long n, const void *) // NOTE this variant is too slow ... may be later in CUDA??? { mglDrawReg d; d.set(this,1,1,id); #if !MGL_HAVE_PTHREAD #pragma omp parallel for firstprivate(d) #endif for(long ii=0;iim, d->PenWidth,d->angle)) return; mglPnt d1(p2-p1), d2(p3-p1), d3(p4+p1-p2-p3); float dd = d1.x*d2.y-d1.y*d2.x; float dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y; float dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x; float xx = (i-p1.x), yy = (j-p1.y), s; s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy); if(s<0) return; // no solution s = sqrt(s); float qu = d3.x*yy - d3.y*xx + dd + s, u=-1; float qv = d3.y*xx - d3.x*yy + dd + s, v=-1; if(qu && qv) { u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv; } if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad { qu = d3.x*yy - d3.y*xx + dd - s; qv = d3.y*xx - d3.x*yy + dd - s; u = v = -1.f; if(qu && qv) { u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv; } if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) return; // second root bad } mglPnt p(p1+d1*u+d2*v+d3*(u*v)); if(mgl_isnan(p.u) && mgl_isnum(p.v)) { mglPoint n1(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z)); mglPoint n2(mglPoint(p2.x-p4.x,p2.y-p4.y,p2.z-p4.z)^mglPoint(p3.x-p4.x,p3.y-p4.y,p3.z-p4.z)); p.u = (n1.x+n2.x)*0.5; p.v = (n1.y+n2.y)*0.5; p.w = (n1.z+n2.z)*0.5; } unsigned char r[4]; col2int(p,r,d->ObjId); if(r[3]) pnt_plot(i,j,p.z,r,d->ObjId); } //----------------------------------------------------------------------------- void mglCanvas::trig_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d) { if(!visible(i,j,d->m, d->PenWidth,d->angle)) return; mglPnt d1(p2-p1), d2(p3-p1); float dd = d2.x*d1.y - d1.x*d2.y; if(fabs(dd)<1e-5) return; // points lies on the same line float dyv =-d1.x/dd, dxv = d1.y/dd, dyu = d2.x/dd, dxu =-d2.y/dd; float xx = (i-p1.x), yy = (j-p1.y); float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; if(u<0 || v<0 || u+v>1) return; mglPnt p(p1+d1*u+d2*v); if(mgl_isnan(p.u) && mgl_isnum(p.v) && anorm) { mglPoint nr(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z)); p.u = nr.x; p.v = nr.y; p.w = nr.z; } unsigned char r[4]; col2int(p,r,d->ObjId); if(r[3]) pnt_plot(i,j,p.z,r,d->ObjId); } //----------------------------------------------------------------------------- void mglCanvas::line_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr) { float xx = (i-p1.x), yy = (j-p1.y); mglPnt d(p2-p1); float dd = hypot(d.x, d.y); float dxv = d.y/dd, dyv =-d.x/dd, dxu = d.x/dd, dyu = d.y/dd; float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; v = v*v; if(u<0) v += u*u; else if(u>dd) v += (u-dd)*(u-dd); float pw=dr->PenWidth, dpw=3*pen_delta; if(dr->ObjId==HighId) { pw *= 2; dpw=2*pen_delta; } if(v>pw*pw || !(dr->PDef & ( (uint64_t)1<pPos+u/pw, 16)) ) )) return; mglPnt p(p1+d*(u/dd)); unsigned char r[4]; col2int(p,r,dr->ObjId); r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2)); float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces if(r[3]) pnt_plot(i,j,p.z+dz,r,dr->ObjId); } //----------------------------------------------------------------------------- void mglCanvas::pnt_pix(long i, long j, const mglPnt &p, const mglDrawReg *dr) { float pw=3*dr->PenWidth,dpw=3*pen_delta; if(dr->ObjId==HighId) { pw *= 2; dpw=2*pen_delta; } unsigned char cs[4]; col2int(p,cs,dr->ObjId); float xx = (i-p.x), yy = (j-p.y), v = xx*xx+yy*yy; if(cs[3]==0 || v>(10/dpw+pw)*(10/dpw+pw)) return; if(v<(pw-1)*(pw-1)/4) cs[3] = mgl_sline(cs[3],dpw*(sqrt(v)+(1-pw)/2)); if(cs[3]) pnt_plot(i,j,p.z,cs,dr->ObjId); } //----------------------------------------------------------------------------- void mglCanvas::mark_pix(long i, long j, const mglPnt &q, char type, mreal size, mglDrawReg *d) { unsigned char cs[4]; col2int(q,cs,d->ObjId); cs[3] = size>0 ? 255 : 255*q.t; mglPnt p0=q,p1=q,p2=q,p3=q; mreal ss=fabs(size); if(type=='.' || ss==0) { if(d) d->PenWidth = ss?ss:sqrt(font_factor/400); pnt_pix(i,j,q,d); } else { if(d) { d->PDef = MGL_SOLID_MASK; d->angle = 0; d->PenWidth*=fabs(50*size); if(d->PenWidth<1) d->PenWidth=1; } if(!strchr("xsSoO",type)) ss *= 1.1; switch(type) { case 'P': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y-ss; p2.x = q.x+ss; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y+ss; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p3,d); line_pix(i,j,p3,p0,d); case '+': p0.x = q.x-ss; p0.y = q.y; p1.x = q.x+ss; p1.y = q.y; line_pix(i,j,p0,p1,d); p2.x = q.x; p2.y = q.y-ss; p3.x = q.x; p3.y = q.y+ss; line_pix(i,j,p2,p3,d); break; case 'X': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y-ss; p2.x = q.x+ss; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y+ss; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p3,d); line_pix(i,j,p3,p0,d); case 'x': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y+ss; line_pix(i,j,p0,p1,d); p2.x = q.x+ss; p2.y = q.y-ss; p3.x = q.x-ss; p3.y = q.y+ss; line_pix(i,j,p2,p3,d); break; case 'S': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x-ss; p1.y = q.y+ss; p2.x= q.x+ss; p2.y= q.y+ss; p3.x = q.x+ss; p3.y = q.y-ss; quad_pix(i,j,p0,p1,p3,p2,d); case 's': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y-ss; p2.x = q.x+ss; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y+ss; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p3,d); line_pix(i,j,p3,p0,d); break; case 'D': p0.x = q.x; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y; p2.x= q.x; p2.y= q.y+ss; p3.x = q.x-ss; p3.y = q.y; quad_pix(i,j,p0,p1,p3,p2,d); case 'd': p0.x = q.x; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y; p2.x = q.x; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p3,d); line_pix(i,j,p3,p0,d); break; case 'Y': p1.x = q.x; p1.y = q.y-ss; line_pix(i,j,q,p1,d); p2.x = q.x-0.8*ss; p2.y = q.y+0.6*ss; line_pix(i,j,q,p2,d); p3.x = q.x+0.8*ss; p3.y = q.y+0.6*ss; line_pix(i,j,q,p3,d); break; case '*': p0.x = q.x-ss; p0.y = q.y; p1.x = q.x+ss; p1.y = q.y; line_pix(i,j,p0,p1,d); p0.x = q.x-0.6*ss; p0.y = q.y-0.8*ss; p1.x = q.x+0.6*ss; p1.y = q.y+0.8*ss; line_pix(i,j,p0,p1,d); p0.x = q.x-0.6*ss; p0.y = q.y+0.8*ss; p1.x = q.x+0.6*ss; p1.y = q.y-0.8*ss; line_pix(i,j,p0,p1,d); break; case 'T': p0.x = q.x-ss; p0.y = q.y-ss/2; p1.x = q.x+ss; p1.y = q.y-ss/2; p2.x= q.x; p2.y= q.y+ss; trig_pix(i,j,p0,p1,p2,false,d); case '^': p0.x = q.x-ss; p0.y = q.y-ss/2; p1.x = q.x+ss; p1.y = q.y-ss/2; p2.x= q.x; p2.y= q.y+ss; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p0,d); break; case 'V': p0.x = q.x-ss; p0.y = q.y+ss/2; p1.x = q.x+ss; p1.y = q.y+ss/2; p2.x= q.x; p2.y= q.y-ss; trig_pix(i,j,p0,p1,p2,false,d); case 'v': p0.x = q.x-ss; p0.y = q.y+ss/2; p1.x = q.x+ss; p1.y = q.y+ss/2; p2.x= q.x; p2.y= q.y-ss; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p0,d); break; case 'L': p0.x = q.x+ss/2; p0.y = q.y+ss; p1.x = q.x+ss/2; p1.y = q.y-ss; p2.x= q.x-ss; p2.y= q.y; trig_pix(i,j,p0,p1,p2,false,d); case '<': p0.x = q.x+ss/2; p0.y = q.y+ss; p1.x = q.x+ss/2; p1.y = q.y-ss; p2.x= q.x-ss; p2.y= q.y; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p0,d); break; case 'R': p0.x = q.x-ss/2; p0.y = q.y+ss; p1.x = q.x-ss/2; p1.y = q.y-ss; p2.x= q.x+ss; p2.y= q.y; trig_pix(i,j,p0,p1,p2,false,d); case '>': p0.x = q.x-ss/2; p0.y = q.y+ss; p1.x = q.x-ss/2; p1.y = q.y-ss; p2.x= q.x+ss; p2.y= q.y; line_pix(i,j,p0,p1,d); line_pix(i,j,p1,p2,d); line_pix(i,j,p2,p0,d); break; case 'O': { float xx = (i-q.x), yy = (j-q.y); float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces if(xx*xx+yy*yyObjId); } case 'o': { float pw=d->PenWidth; float xx = (i-q.x), yy = (j-q.y), v = hypot(xx,yy); v = (v-ss)*(v-ss); // if(v>pw*pw) return; if(v>(pw-1)*(pw-1)/4) cs[3] = mgl_sline(cs[3],2*(sqrt(v)+(1-pw)/2)); float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces if(cs[3]) pnt_plot(i,j,q.z+dz,cs,d->ObjId); } break; case 'C': pnt_pix(i,j,q,d); { float pw=d->PenWidth; float xx = (i-q.x), yy = (j-q.y), v = hypot(xx,yy); v = (v-ss)*(v-ss); // if(v>pw*pw) return; if(v>(pw-1)*(pw-1)/4) cs[3] = mgl_sline(cs[3],2*(sqrt(v)+(1-pw)/2)); float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces if(cs[3]) pnt_plot(i,j,q.z+dz,cs,d->ObjId); } break; } } } //----------------------------------------------------------------------------- void mglCanvas::glyph_pix(long i, long j, const mglPrim &P, mglDrawReg *d) { float phi = GetGlyphPhi(Pnt[P.n2],P.w); if(mgl_isnan(phi)) return; if(d) { d->PDef = MGL_SOLID_MASK; d->angle = 0; d->PenWidth=1; } mglPnt p=Pnt[P.n1]; mreal pf=sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2), f = P.p*pf; mglMatrix M; M.b[0] = M.b[4] = M.b[8] = P.s; M.RotateN(phi,0,0,1); M.x=p.x; M.y=p.y; M.z=p.z; M.pf = 1; p.u *= pf; p.v *= pf; const mglGlyph &g = Glf[P.n4]; if(P.n3&8) { if(!(P.n3&4)) glyph_lpix(i,j,&M,p,f,true, d); glyph_lpix(i,j,&M,p,f,false, d); } else { if(!(P.n3&4)) glyph_fpix(i,j,&M,p,f,g, d); glyph_wpix(i,j,&M,p,f,g, d); } } //----------------------------------------------------------------------------- void mglCanvas::glyph_fpix(long i, long j, const mglMatrix *M, const mglPnt &pp, mreal f, const mglGlyph &g, const mglDrawReg *d) { if(!g.trig || g.nt<=0) return; mglPnt q0=pp, q1=pp, q2=pp; q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=NAN; for(long ik=0;ik * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/define.h" #include "mgl2/volume.h" #include "mgl2/data.h" #include "mgl2/eval.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- // // CloudQ series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cloud_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { if(!(gr->GetQuality()&3)) return; // do nothing in fast_draw long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); bool nboth = mgl_isnboth(x,y,z,a); if(mgl_check_dim3(gr,!nboth,x,y,z,a,0,"Cloud")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Cloud",cgid++); long tx=1,ty=1,tz=1; if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); if(tx<1) tx=1; ty=(m-1)/(gr->MeshNum-1); if(ty<1) ty=1; tz=(l-1)/(gr->MeshNum-1); if(tz<1) tz=1; } mreal alpha = gr->AlphaDef; bool inv = mglchr(sch,'i'); bool dot = mglchr(sch,'.'); alpha /= pow((n/tx)*(m/ty)*(l/tz),1./3)/20; if(alpha>1) alpha = 1; long ss = gr->AddTexture(sch); // x, y, z -- have the same size as a n /= tx; m /= ty; l /= tz; gr->Reserve(n*m*l); mglPoint q(NAN); const long kq = gr->AllocPnts(n*m*l),nm=n*m; #pragma omp parallel for for(long k=0;kv(i*tx),y->v(j*ty),z->v(k*tz)) : mglPoint(x->v(i*tx,j*ty,k*tz),y->v(i*tx,j*ty,k*tz),z->v(i*tx,j*ty,k*tz)); mreal aa = gr->GetA(a->v(i*tx,j*ty,k*tz)); mreal bb = inv ? (1-aa)*(1-aa)*alpha : aa*aa*alpha; gr->AddPntQ(kq+i+n*(j+m*k), p,gr->GetC(ss,aa,false),q,bb); } if(dot) for(long i=0;imark_plot(kq+i,'.'); else for(long k=0;kNeedStop()) break; for(long j=0;jquad_plot(i0,i0+1,i0+n, i0+n+1); if(iquad_plot(i0,i0+1,i0+nm,i0+nm+1); if(kquad_plot(i0,i0+n,i0+nm,i0+n+nm); } } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cloud(HMGL gr, HCDT a, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_cloud_xyz(gr,&x,&y,&z,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cloud_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cloud_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cloud_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cloud(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Surf3 series // //----------------------------------------------------------------------------- mreal static mgl_get_norm(mreal x, mreal d1, mreal d2, mreal d3) { mreal nx = d1*(1-x) + d2*x; if(mgl_isbad(nx)) { nx = d1*(1+x) - d3*x; if(mgl_isbad(nx)) { if(mgl_isfin(d1)) nx = d1; if(mgl_isfin(d2)) nx = d2; if(mgl_isfin(d3)) nx = d3; } } return nx; } mglPoint static mgl_normal_3d(HCDT a, mglPoint p, bool inv, long n,long m,long l) { mreal x=p.x, y=p.y, z=p.z; mreal nx=0, ny=0, nz=0; long i=long(x), j=long(y), k=long(z); i = idvx(i,j,k), a->dvx(i+1,j,k), i>0?a->dvx(i-1,j,k):NAN); ny = mgl_get_norm(y, a->dvy(i,j,k), a->dvy(i,j+1,k), j>0?a->dvy(i,j-1,k):NAN); nz = mgl_get_norm(z, a->dvz(i,j,k), a->dvz(i,j,k+1), k>0?a->dvz(i,j,k-1):NAN); return inv ? mglPoint(nx,ny,nz) : mglPoint(-nx,-ny,-nz); } //----------------------------------------------------------------------------- mreal static mgl_normal_1d(HCDT a, mreal x, long n) { long i=long(x); i = idvx(i), a->dvx(i+1), i>0?a->dvx(i-1):NAN); } //----------------------------------------------------------------------------- mglPoint static mgl_find_norm(bool nboth, HCDT x, HCDT y, HCDT z, HCDT a, mglPoint u, bool inv, long n,long m,long l) { mglPoint s = mgl_normal_3d(a,u,inv,n,m,l), t, q; if(nboth) { q.x = s.x/mgl_normal_1d(x,u.x,n); q.y = s.y/mgl_normal_1d(y,u.y,m); q.z = s.z/mgl_normal_1d(z,u.z,l); } else { t = mgl_normal_3d(x,u,true,n,m,l); q.x = (s*t)/(t*t); t = mgl_normal_3d(y,u,true,n,m,l); q.y = (s*t)/(t*t); t = mgl_normal_3d(z,u,true,n,m,l); q.z = (s*t)/(t*t); } return q; } //----------------------------------------------------------------------------- inline mreal static mgl_cos_pp(const mglPoint *kk,long i0,long i1,long i2) { mglPoint dp1 = kk[i1]-kk[i0], dp2 = kk[i2]-kk[i0]; mreal p1=dp1*dp1,p2=dp2*dp2,pc=dp1*dp2; return p1*p2>1e-10 ? pc/sqrt(p1*p2) : NAN; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_plot(HMGL gr, long n,long m,long *kx1,long *kx2,long *ky1,long *ky2, long *kz, std::vector kk, int wire) { long id[12],us[12],pd[12]; mglPoint pp[12]; #pragma omp parallel for private(id,us,pd,pp) collapse(2) for(long j=0;j=0) id[ni++] = kx1[i0]; if(ky1[i0]>=0) id[ni++] = ky1[i0]; if(kx1[i0+n]>=0) id[ni++] = kx1[i0+n]; if(ky1[i0+1]>=0) id[ni++] = ky1[i0+1]; if(kz[i0]>=0) id[ni++] = kz[i0]; if(kz[i0+1]>=0) id[ni++] = kz[i0+1]; if(kz[i0+n+1]>=0) id[ni++] = kz[i0+n+1]; if(kz[i0+n]>=0) id[ni++] = kz[i0+n]; if(kx2[i0]>=0) id[ni++] = kx2[i0]; if(ky2[i0]>=0) id[ni++] = ky2[i0]; if(kx2[i0+n]>=0) id[ni++] = kx2[i0+n]; if(ky2[i0+1]>=0) id[ni++] = ky2[i0+1]; if(ni<3) continue; for(jj=0;jj1e-5) jj++; else { ni--; for(ii=jj;iid0) { d0=d; i0=ii; } } if(i0<0) break; // no more triangles. NOTE: should be never here jj = i0; us[jj]=1; p3 = pd[jj]; if(wire==1) { gr->line_plot(p1, p2); gr->line_plot(p1, p3); gr->line_plot(p2, p3); } else if(wire==2) { gr->mark_plot(p1, '.'); gr->mark_plot(p2, '.'); gr->mark_plot(p3, '.'); } else gr->trig_plot(p1, p2, p3); p2 = p3; } } } //----------------------------------------------------------------------------- void static mgl_surf3ca_gen(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *sch) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); bool nboth = mgl_isnboth(x,y,z,a); int wire = mglchr(sch,'#')?1:0; if(mglchr(sch,'.')) wire = 2; bool inv = (mglchr(sch,'-')); long ss = gr->AddTexture(sch); long *kx1 = new long[n*m], *kx2 = new long[n*m]; long *ky1 = new long[n*m], *ky2 = new long[n*m]; long *kz = new long[n*m]; std::vector kk; kk.reserve(n*m*l); for(long k=0;kNeedStop()) break; memcpy(kx1,kx2,n*m*sizeof(long)); memset(kx2,-1,n*m*sizeof(long)); memcpy(ky1,ky2,n*m*sizeof(long)); memset(ky2,-1,n*m*sizeof(long)); memset(kz ,-1,n*m*sizeof(long)); gr->Reserve(n*m); gr->Reserve(n*m); size_t kk1 = kk.size(); for(long j=0;jv(i,j,k); if(mgl_isnan(a0)) continue; if(iv(i+1,j,k)); if(d>=0 && d<1) { kx2[i1] = kk.size(); kk.push_back(mglPoint(i+d,j,k)); } } if(jv(i,j+1,k)); if(d>=0 && d<1) { ky2[i1] = kk.size(); kk.push_back(mglPoint(i,j+d,k)); } } if(k>0) { mreal d = mgl_d(val,a->v(i,j,k-1),a0); if(d>=0 && d<1) { kz[i1] = kk.size(); kk.push_back(mglPoint(i,j,k+d-1)); } } } mreal cv=gr->GetC(ss,val); if(b && c) { const long kq = gr->AllocPnts(kk.size()); #pragma omp parallel for for(msize i=kk1;ilinear(u.x,u.y,u.z), bb = b->linear(u.x,u.y,u.z); gr->AddPntQ(kq+i,nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)), gr->GetC(ss,cc), mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l), gr->GetA(bb)); u.c = kq+i; } } else if(c) { const long kq = gr->AllocPnts(kk.size()); #pragma omp parallel for for(msize i=kk1;ilinear(u.x,u.y,u.z); gr->AddPntQ(kq+i,nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)), gr->GetC(ss,cc), mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l)); u.c = kq+i; } } else if(b) { const long kq = gr->AllocPnts(kk.size()); #pragma omp parallel for for(msize i=kk1;ilinear(u.x,u.y,u.z); gr->AddPntQ(kq+i,nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)), cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l), gr->GetA(bb)); u.c = kq+i; } } else { const long kq = gr->AllocPnts(kk.size()); #pragma omp parallel for for(msize i=kk1;iAddPntQ(kq+i,nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)), cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l)); u.c = kq+i; } } if(k>0) mgl_surf3_plot(gr,n,m,kx1,kx2,ky1,ky2,kz,kk,wire); } delete []kx1; delete []kx2; delete []ky1; delete []ky2; delete []kz; gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { if(mgl_check_dim3(gr,mgl_isboth(x,y,z,a),x,y,z,a,0,"Surf3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Surf3",cgid++); mgl_surf3ca_gen(gr, val, x, y, z, a, 0, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_val(HMGL gr, double val, HCDT a, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3_xyz_val(gr,val,&x,&y,&z,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?3:long(r+0.5); for(long i=0;iMax.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1); mgl_surf3_xyz_val(gr,v,x,y,z,a,sch,0); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3(HMGL gr, HCDT a, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3_xyz(gr,&x,&y,&z,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3_val(_GR_, *Val, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Surf3A series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *sch, const char *opt) { if(mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,b,"Surf3A")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Surf3A",cgid++); mgl_surf3ca_gen(gr, val, x, y, z, a, 0, b, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_val(HMGL gr, double val, HCDT a, HCDT b, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3a_xyz_val(gr,val,&x,&y,&z,a,b,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?3:long(r+0.5); if(b->GetNx()==num && b->GetNy()==1 && b->GetNz()==1) { mreal a0=gr->AlphaDef; for(long i=0;iMax.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1); gr->AlphaDef = gr->GetA(b->v(i)); mgl_surf3_xyz_val(gr,v,x,y,z,a,sch,0); } gr->AlphaDef = a0; } else for(long i=0;iMax.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1); mgl_surf3a_xyz_val(gr,v,x,y,z,a,b,sch,0); } gr->LoadState(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a(HMGL gr, HCDT a, HCDT b, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3a_xyz(gr,&x,&y,&z,a,b,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3a_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3a_val(_GR_, *Val, _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3a_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3a_(uintptr_t *gr, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3a(_GR_, _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Surf3C series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, const char *sch, const char *opt) { if(mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,c,"Surf3C")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Surf3C",cgid++); mgl_surf3ca_gen(gr, val, x, y, z, a, c, 0, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_val(HMGL gr, double val, HCDT a, HCDT b, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3c_xyz_val(gr,val,&x,&y,&z,a,b,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?3:long(r+0.5); for(long i=0;iMax.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1); mgl_surf3c_xyz_val(gr,v,x,y,z,a,b,sch,0); } gr->LoadState(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c(HMGL gr, HCDT a, HCDT b, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3c_xyz(gr,&x,&y,&z,a,b,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3c_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3c_val(_GR_, *Val, _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3c_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3c_(uintptr_t *gr, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3c(_GR_, _DA_(a), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Surf3C series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt) { if(mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,c,"Surf3C") || mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,b,"Surf3C")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Surf3C",cgid++); mgl_surf3ca_gen(gr, val, x, y, z, a, c, b, sch); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_val(HMGL gr, double val, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3ca_xyz_val(gr,val,&x,&y,&z,a,c,b,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long num = mgl_isnan(r)?3:long(r+0.5); for(long i=0;iMax.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1); mgl_surf3ca_xyz_val(gr,v,x,y,z,a,c,b,sch,0); } gr->LoadState(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca(HMGL gr, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_surf3ca_xyz(gr,&x,&y,&z,a,c,b,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3ca_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(c), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3ca_val(_GR_, *Val, _DA_(a), _DA_(c), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3ca_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(c), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_surf3ca_(uintptr_t *gr, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_surf3ca(_GR_, _DA_(a), _DA_(c), _DA_(b), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Beam series // //----------------------------------------------------------------------------- // flag & 0x1 -- accompanied coordinates // flag & 0x2 -- project to r*z // flag & 0x4 -- normalize field void MGL_EXPORT mgl_beam_val(HMGL gr, double val, HCDT tr, HCDT g1, HCDT g2, HCDT a, double r, const char *stl, int flag) { long n = a->GetNz(),m=a->GetNx(),l=a->GetNy(); if(n<2 || m<2 || l<2) { gr->SetWarn(mglWarnLow,"Beam"); return; } if(a->Minimal()<0) { gr->SetWarn(mglWarnNeg,"Beam"); return; } if(tr->GetNx()<3 || tr->GetNy()GetNx()<3 || g1->GetNy()GetNx()<3 || g2->GetNy()SetWarn(mglWarnDim,"Beam"); return; } mglData x(a),y(a),z(a),b(a); mreal asum0=1; r = fabs(r); if(flag & 4) for(long j=0;jvthr(j)*a->vthr(j); if(asum0==0) { gr->SetWarn(mglWarnZero,"Beam"); return; } #pragma omp parallel for for(long i=0;iNeedStop()) continue; if(flag & 4) { mreal asum=0, amax=0; for(long j=0;jvthr(j+m*l*i); asum += aa*aa; amax = amax>aa ? amax : aa; } amax = amax?sqrt(asum/asum0)/amax:0; for(long j=0;jMax.z*i/(n-1.); } else for(long k=0;kv(0,i) + g1->v(0,i)*(2*j/(m-1.)-1)*r + g2->v(0,i)*(2*k/(l-1.)-1)*r; y.a[i0] = tr->v(1,i) + g1->v(1,i)*(2*j/(m-1.)-1)*r + g2->v(1,i)*(2*k/(l-1.)-1)*r; z.a[i0] = tr->v(2,i) + g1->v(2,i)*(2*j/(m-1.)-1)*r + g2->v(2,i)*(2*k/(l-1.)-1)*r; } if(flag & 2) for(long j=0;jMax.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1); mgl_beam_val(gr,v,tr,g1,g2,a,r,stl,flag); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_beam_val_(uintptr_t *gr, mreal *val, uintptr_t *tr, uintptr_t *g1, uintptr_t *g2, uintptr_t *a, mreal *r, const char *sch, int *norm,int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; mgl_beam_val(_GR_, *val,_DA_(tr),_DA_(g1),_DA_(g2),_DA_(a),*r,s,*norm); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_beam_(uintptr_t *gr, uintptr_t *tr, uintptr_t *g1, uintptr_t *g2, uintptr_t *a, mreal *r, const char *sch, int *norm, int *num,int l) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; mgl_beam(_GR_, _DA_(tr), _DA_(g1), _DA_(g2), _DA_(a), *r,s,*norm,*num); delete []s; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/window.cpp0000644000175000017500000004636413513030041015764 0ustar alastairalastair/*************************************************************************** * window.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/canvas_wnd.h" //----------------------------------------------------------------------------- mglCanvasWnd::mglCanvasWnd() : mglCanvas() { Setup(); LoadFunc=0; FuncPar=0; DrawFunc=0; ClickFunc=0; GG = 0; NumFig = 0; CurFig=-1; PropFunc=0; PropPar=0; #if MGL_HAVE_PTHR_WIDGET mutex=0; #endif } //----------------------------------------------------------------------------- mglCanvasWnd::~mglCanvasWnd() { if(GG) free(GG); } //----------------------------------------------------------------------------- void mglCanvasWnd::SetCurFig(int c) { CurFig=c; if(get(MGL_VECT_FRAME) && c>=0 && c<(long)DrwDat.size() && DrawFunc) GetFrame(c); } //----------------------------------------------------------------------------- void mglCanvasWnd::ResetFrames() { if(GG) free(GG); GG = 0; NumFig = CurFig = 0; mglCanvas::ResetFrames(); } //----------------------------------------------------------------------------- void mglCanvasWnd::SetSize(int w,int h,bool) { if(DrawFunc) ResetFrames(); mglCanvas::SetSize(w,h,false); // if(Wnd) Wnd->size(w,h); } //----------------------------------------------------------------------------- void mglCanvasWnd::EndFrame() { CurFig = CurFrameId-1; if(!GG) { GG = (unsigned char *)malloc(3*Width*Height); NumFig = 1; CurFig = 0; } else if(CurFig>NumFig-1) { GG = (unsigned char *)realloc(GG,3*(CurFig+1)*Width*Height); NumFig = CurFig+1; } mglCanvas::EndFrame(); memcpy(GG + CurFig*Width*Height*3,G,3*Width*Height); CurFig++; } //----------------------------------------------------------------------------- void mglCanvasWnd::SetFrame(long i) { mglCanvas::SetFrame(i); if(i>=0 && i=CurFrameId) return; if(CurFig>=i) CurFig--; long n = Width*Height*3; if(CurFrameId-i>1) memmove(GG+i*n, GG+i*n+n, n*(CurFrameId-i-1)); mglCanvas::DelFrame(i); } //----------------------------------------------------------------------------- void mglCanvasWnd::SetDrawFunc(int (*draw)(mglBase *gr, void *p), void *par, void (*reload)(void *p)) { if(draw) { ResetFrames(); if(get(MGL_CLF_ON_UPD)) DefaultPlotParam(); const std::string loc = setlocale(LC_NUMERIC, "C"); // use frames for quickly redrawing while adding/changing primitives if(mgl_is_frames(this)) NewFrame(); int n = draw(this,par); if(n=0) NumFig = n; DrawFunc = draw; FuncPar = par; LoadFunc = reload; if(mgl_is_frames(this)) EndFrame(); if(n>=0) SetCurFig(0); setlocale(LC_NUMERIC, loc.c_str()); } else LoadFunc = 0; } //----------------------------------------------------------------------------- const unsigned char *mglCanvasWnd::GetBits() { const unsigned char *g = mglCanvas::GetBits(); if(GG && NumFig>0 && CurFig=0 && !get(MGL_VECT_FRAME)) g = GG + CurFig*Width*Height*3; return g; } //----------------------------------------------------------------------------- void mglCanvasWnd::ReLoad() { if(LoadFunc) { LoadFunc(FuncPar); // update number of slides ResetFrames(); const std::string loc = setlocale(LC_NUMERIC, "C"); // use frames for quickly redrawing while adding/changing primitives if(mgl_is_frames(this)) NewFrame(); int n = DrawFunc ? DrawFunc(this,FuncPar) : 0; if(n=0) NumFig = n; if(mgl_is_frames(this)) EndFrame(); setlocale(LC_NUMERIC, loc.c_str()); Update(); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_prop_func(char id, const char *val, void *p) { mglCanvasWnd *g = (mglCanvasWnd *)(p); if(g) g->SetParam(id, val); } void MGL_EXPORT mgl_wnd_make_dialog(HMGL gr, const char *ids, char const * const *args, const char *title) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->MakeDialog(ids, args, title); } void MGL_EXPORT mgl_wnd_set_func(HMGL gr, int (*draw)(HMGL gr, void *p), void *par, void (*reload)(void *p)) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->SetDrawFunc(draw, par, reload); } void MGL_EXPORT mgl_wnd_set_prop(HMGL gr, void (*prop)(char id, const char *val, void *p), void *par) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->SetPropFunc(prop, par); } void MGL_EXPORT mgl_wnd_toggle_alpha(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ToggleAlpha(); } void MGL_EXPORT mgl_wnd_toggle_light(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ToggleLight(); } void MGL_EXPORT mgl_wnd_toggle_zoom(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ToggleZoom(); } void MGL_EXPORT mgl_wnd_toggle_rotate(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ToggleRotate(); } void MGL_EXPORT mgl_wnd_toggle_no(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ToggleNo(); } void MGL_EXPORT mgl_wnd_update(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->Update(); } void MGL_EXPORT mgl_wnd_reload(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ReLoad(); } void MGL_EXPORT mgl_wnd_adjust(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->Adjust(); } void MGL_EXPORT mgl_wnd_next_frame(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->NextFrame(); } void MGL_EXPORT mgl_wnd_prev_frame(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->PrevFrame(); } void MGL_EXPORT mgl_wnd_animation(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->Animation(); } void MGL_EXPORT mgl_setup_window(HMGL gr, int clf_upd, int showpos) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->Setup(clf_upd, showpos); } void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p)) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->ClickFunc = func; } void MGL_EXPORT mgl_get_last_mouse_pos(HMGL gr, mreal *x, mreal *y, mreal *z) { mglCanvasWnd *g = dynamic_cast(gr); mglPoint p; if(g) p=g->GetMousePos(); *x=p.x; *y=p.y; *z=p.z; } MGL_EXPORT void *mgl_wnd_window(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); return g?g->Window():NULL; } MGL_EXPORT void *mgl_wnd_widget(HMGL gr) { mglCanvasWnd *g = dynamic_cast(gr); return g?g->Widget():NULL; } /// Move window to given position void MGL_EXPORT mgl_wnd_move(HMGL gr, int x, int y) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->WndMove(x,y); } void MGL_EXPORT mgl_wnd_move_(uintptr_t *gr, int *x, int *y) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->WndMove(*x,*y); } /// Change window sizes void MGL_EXPORT mgl_wnd_size(HMGL gr, int w, int h) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->WndSize(w,h); } void MGL_EXPORT mgl_wnd_size_(uintptr_t *gr, int *w, int *h) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->WndSize(*w,*h); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_wnd_toggle_alpha_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->ToggleAlpha(); } void MGL_EXPORT mgl_wnd_toggle_light_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->ToggleLight(); } void MGL_EXPORT mgl_wnd_toggle_zoom_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->ToggleZoom(); } void MGL_EXPORT mgl_wnd_toggle_rotate_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->ToggleRotate(); } void MGL_EXPORT mgl_wnd_toggle_no_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->ToggleNo(); } void MGL_EXPORT mgl_wnd_update_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->Update(); } void MGL_EXPORT mgl_wnd_reload_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->ReLoad(); } void MGL_EXPORT mgl_wnd_adjust_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->Adjust(); } void MGL_EXPORT mgl_wnd_next_frame_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->NextFrame(); } void MGL_EXPORT mgl_wnd_prev_frame_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->PrevFrame(); } void MGL_EXPORT mgl_wnd_animation_(uintptr_t *gr) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->Animation(); } void MGL_EXPORT mgl_setup_window_(uintptr_t *gr, int *clf_upd, int *showpos) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); if(g) g->Setup(*clf_upd, *showpos); } void MGL_EXPORT mgl_get_last_mouse_pos_(uintptr_t *gr, mreal *x, mreal *y, mreal *z) { mglCanvasWnd *g = dynamic_cast((HMGL)(*gr)); mglPoint p; if(g) p=g->GetMousePos(); *x=p.x; *y=p.y; *z=p.z; } //----------------------------------------------------------------------------- #if MGL_HAVE_PTHR_WIDGET void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex) { mglCanvasWnd *g = dynamic_cast(gr); if(g) g->mutex = mutex; } #endif //----------------------------------------------------------------------------- // // mglDraw class handling // //----------------------------------------------------------------------------- /*int mgl_draw_class(HMGL gr, void *p) // so stupid way to save mglDraw class inheritance :( { mglGraph g(gr); mglWindow *w = (mglWindow *)p; return (w && w->dr) ? w->dr->Draw(&g) : 0; } void MGL_EXPORT mgl_reload_class(void *p) // so stupid way to save mglDraw class inheritance :( { mglWindow *w = (mglWindow *)p; if(w && w->dr) w->dr->Reload();} void MGL_EXPORT mgl_click_class(void *p) // so stupid way to save mglDraw class inheritance :( { mglWindow *w = (mglWindow *)p; if(w && w->dr) w->dr->Click(); }*/ int MGL_EXPORT mgl_draw_class(HMGL gr, void *p) { mglGraph g(gr); mglDraw *dr = (mglDraw *)p; return dr?dr->Draw(&g):0; } void MGL_EXPORT mgl_reload_class(void *p) { mglDraw *dr = (mglDraw *)p; if(dr) dr->Reload(); } void MGL_EXPORT mgl_click_class(void *p) { mglDraw *dr = (mglDraw *)p; if(dr) dr->Click(); } void MGL_EXPORT mgl_prop_class(char id, const char *val, void *p) { mglDraw *dr = (mglDraw *)p; if(dr) dr->Param(id,val); } //----------------------------------------------------------------------------- typedef int (*draw_func)(mglGraph *gr); int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p) { mglGraph g(gr); draw_func func = (draw_func)(p); return func ? func(&g) : 0; } //----------------------------------------------------------------------------- MGL_EXPORT void *mgl_draw_calc(void *p) { #if MGL_HAVE_PTHR_WIDGET mglDraw *d = (mglDraw *)p; d->Calc(); d->running = false; #endif return 0; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_parse_comments(const wchar_t *text, double &a1, double &a2, double &da, std::vector &anim, std::string &ids, std::vector &par) { a1=0; a2=0; da=1; const wchar_t *str = wcsstr(text, L"##c"); if(str) // this is animation loop { int res=wscanf(str+3, "%lg%lg%lg", &a1, &a2, &da); da = res<3?1:da; if(res>2 && da*(a2-a1)>0) { for(double a=a1;da*(a2-a)>=0;a+=da) { wchar_t buf[128]; swprintf(buf,128,L"%g",a); anim.push_back(buf); } return; } } str = wcsstr(text, L"##a"); while(str) { str += 3; while(*str>0 && *str<=' ' && *str!='\n') str++; if(*str>' ') { size_t j=0; while(str[j]>' ') j++; std::wstring val(str,j); anim.push_back(val); } str = wcsstr(str, L"##a"); } str = wcsstr(text, L"##d"); // custom dialog while(str) { str = wcschr(str,'$'); if(str) { char id = str[1]; str += 2; while(*str>0 && *str<=' ' && *str!='\n') str++; if(*str>' ') { long j=0; while(str[j]!='\n') j++; while(str[j-1]<=' ') j--; ids.push_back(id); std::wstring val(str,j); par.push_back(val); } } str = wcsstr(str, L"##d"); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_parse_comments(const char *text, double &a1, double &a2, double &da, std::vector &anim, std::string &ids, std::vector &par) { a1=0; a2=0; da=1; const char *str = strstr(text, "##c"); if(str) // this is animation loop { int res=sscanf(str+3, "%lg%lg%lg", &a1, &a2, &da); da = res<3?1:da; if(res>2 && da*(a2-a1)>0) { for(double a=a1;da*(a2-a)>=0;a+=da) { char buf[128]; snprintf(buf,128,"%g",a); anim.push_back(buf); } return; } } str = strstr(text, "##a"); while(str) { str += 3; while(*str>0 && *str<=' ' && *str!='\n') str++; if(*str>' ') { size_t j=0; while(str[j]>' ') j++; std::string val(str,j); anim.push_back(val); } str = strstr(str, "##a"); } str = strstr(text, "##d"); // custom dialog while(str) { str = strchr(str,'$'); if(str) { char id = str[1]; str += 2; while(*str>0 && *str<=' ' && *str!='\n') str++; if(*str>' ') { long j=0; while(str[j]!='\n') j++; while(str[j-1]<=' ') j--; ids.push_back(id); std::string val(str,j); par.push_back(val); } } str = strstr(str, "##d"); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_parse_animation(const char *text, std::vector &anim) { std::string ids; std::vector par; double a1, a2, da; mgl_parse_comments(text, a1, a2, da, anim, ids, par); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_parse_animation(const wchar_t *text, std::vector &anim) { std::string ids; std::vector par; double a1, a2, da; mgl_parse_comments(text, a1, a2, da, anim, ids, par); } //----------------------------------------------------------------------------- #undef _GR_ #define _GR_ ((mglCanvas *)(*gr)) void MGL_EXPORT mgl_wnd_set_delay(HMGL gr, double dt) { mglCanvas *g = dynamic_cast(gr); if(g) g->SetDelay(dt); } double MGL_EXPORT_PURE mgl_wnd_get_delay(HMGL gr) { mglCanvas *g = dynamic_cast(gr); return g?g->GetDelay():0; } void MGL_EXPORT mgl_wnd_set_delay_(uintptr_t *gr, mreal *dt) { _GR_->SetDelay(*dt); } double MGL_EXPORT_PURE mgl_wnd_get_delay_(uintptr_t *gr) { return _GR_->GetDelay(); } //----------------------------------------------------------------------------- MGL_EXPORT const char *mgl_hints[] = { _("You can shift axis range by pressing middle button and moving mouse. Also, you can zoom in/out axis range by using mouse wheel."), _("You can rotate/shift/zoom whole plot by mouse. Just press 'Rotate' toolbutton, click image and hold a mouse button: left button for rotation, right button for zoom/perspective, middle button for shift."), _("You may quickly draw the data from file. Just use: mgllab 'filename.dat' in command line."), _("You can copy the current image to clipboard by pressing Ctrl-Shift-C. Later you can paste it directly into yours document or presentation."), _("You can export image into a set of format (EPS, SVG, PNG, JPEG) by pressing right mouse button inside image and selecting 'Export as ...'."), _("You can setup colors for script highlighting in Property dialog. Just select menu item 'Settings/Properties'."), _("You can save the parameter of animation inside MGL script by using comment started from '##a ' or '##c ' for loops."), _("New drawing never clears things drawn already. For example, you can make a surface with contour lines by calling commands 'surf' and 'cont' one after another (in any order). "), _("You can put several plots in the same image by help of commands 'subplot' or 'inplot'."), _("All indexes (of data arrays, subplots and so on) are always start from 0."), _("You can edit MGL file in any text editor. Also you can run it in console by help of commands: mglconv, mglview."), _("You can use command 'once on|off' for marking the block which should be executed only once. For example, this can be the block of large data reading/creating/handling. Press F9 (or menu item 'Graphics/Reload') to re-execute this block."), _("You can use command 'stop' for terminating script parsing. It is useful if you don't want to execute a part of script."), _("You can type arbitrary expression as input argument for data or number. In last case (for numbers), the first value of data array is used."), _("There is powerful calculator with a lot of special functions. You can use buttons or keyboard to type the expression. Also you can use existed variables in the expression."), _("The calculator can help you to put complex expression in the script. Just type the expression (which may depend on coordinates x,y,z and so on) and put it into the script."), _("You can easily insert file or folder names, last fitted formula or numerical value of selection by using menu Edit|Insert."), _("The special dialog (Edit|Insert|New Command) help you select the command, fill its arguments and put it into the script."), _("You can put several plotting commands in the same line or in separate function, for highlighting all of them simultaneously."), _("You can concatenation of strings and numbers using `,` with out spaces (for example, `'max(u)=',u.max,' a.u.'` or `'u=',!(1+i2)` for complex numbers). Also you can get n-th symbol of the string using `[]` (for example, `'abc'[1]` will give 'b'), or add a value to the last character of the string using `+` (for example, `'abc'+3` will give 'abf'), or use it all together."), NULL }; //----------------------------------------------------------------------------- mathgl-2.4.4/src/exec_prm.cpp0000644000175000017500000010067413513030041016252 0ustar alastairalastair/*************************************************************************** * exec_2d.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef WIN32 #include #include #else #include #endif #include "mgl2/base.h" #include "mgl2/parser.h" wchar_t *mgl_str_copy(const char *s); //----------------------------------------------------------------------------- int static mgls_arc(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->Arc(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v); else if(!strcmp(k,"nnnnns")) gr->Arc(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnn")) gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v), a[5].v); else if(!strcmp(k,"nnnnnns")) gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v), a[5].v, a[6].s.s); else if(!strcmp(k,"nnnnnnnnnn")) gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v, a[5].v), mglPoint(a[6].v,a[7].v, a[8].v), a[9].v); else if(!strcmp(k,"nnnnnnnnnns")) gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v, a[5].v), mglPoint(a[6].v,a[7].v, a[8].v), a[9].v, a[10].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_axis(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]==0) gr->Axis("xyz","",opt); else if(!strcmp(k,"s")) gr->Axis(a[0].s.s, "",opt); else if(!strcmp(k,"ss")) gr->Axis(a[0].s.s, a[1].s.s,opt); else if(!strcmp(k,"sss")) gr->SetFunc(a[0].s.s,a[1].s.s,a[2].s.s,""); else if(!strcmp(k,"ssss")) gr->SetFunc(a[0].s.s,a[1].s.s,a[2].s.s,a[3].s.s); else if(!strcmp(k,"n")) gr->SetCoor(mgl_int(a[0].v)); else if(!strcmp(k,"nnnn")) gr->SetRanges(a[0].v,a[2].v, a[1].v,a[3].v); else if(!strcmp(k,"nnnnnn"))gr->SetRanges(a[0].v,a[3].v, a[1].v,a[4].v, a[2].v,a[5].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_background(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) gr->LoadBackground(a[0].s.s); else if(!strcmp(k,"sn")) gr->LoadBackground(a[0].s.s,a[1].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ball(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nn")) gr->Mark(mglPoint(a[0].v,a[1].v,NAN),"r."); else if(!strcmp(k,"nns")) gr->Mark(mglPoint(a[0].v,a[1].v,NAN),a[2].s.s); else if(!strcmp(k,"nnn")) gr->Mark(mglPoint(a[0].v,a[1].v,a[2].v),"r."); else if(!strcmp(k,"nnns")) gr->Mark(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_box(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(k[0]==0) gr->Box(); else if(!strcmp(k,"s")) gr->Box(a[0].s.s); else if(!strcmp(k,"sn")) gr->Box(a[0].s.s, a[1].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_circle(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnn")) gr->Circle(mglPoint(a[0].v,a[1].v, NAN), a[2].v); else if(!strcmp(k,"nnns")) gr->Circle(mglPoint(a[0].v,a[1].v, NAN), a[2].v, a[3].s.s); else if(!strcmp(k,"nnnn")) gr->Circle(mglPoint(a[0].v,a[1].v,a[2].v), a[3].v); else if(!strcmp(k,"nnnns")) gr->Circle(mglPoint(a[0].v,a[1].v,a[2].v), a[3].v, a[4].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_colorbar(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(k[0]==0) gr->Colorbar(); else if(!strcmp(k,"s")) gr->Colorbar(a[0].s.s); else if(!strcmp(k,"d")) gr->Colorbar(*(a[0].d)); else if(!strcmp(k,"ds")) gr->Colorbar(*(a[0].d), a[1].s.s); else if(!strcmp(k,"snn")) gr->Colorbar(a[0].s.s, a[1].v, a[2].v); else if(!strcmp(k,"snnn")) gr->Colorbar(a[0].s.s, a[1].v, a[2].v, a[3].v,1); else if(!strcmp(k,"snnnn")) gr->Colorbar(a[0].s.s, a[1].v, a[2].v, a[3].v,a[4].v); else if(!strcmp(k,"dsnn")) gr->Colorbar(*(a[0].d), a[1].s.s, a[2].v, a[3].v); else if(!strcmp(k,"dsnnn")) gr->Colorbar(*(a[0].d), a[1].s.s, a[2].v, a[3].v, a[4].v,1); else if(!strcmp(k,"dsnnnn")) gr->Colorbar(*(a[0].d), a[1].s.s, a[2].v, a[3].v, a[4].v,a[5].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_cone(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnnnn")) gr->Cone(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v); else if(!strcmp(k,"nnnnnnns")) gr->Cone(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v,-1, a[7].s.s); else if(!strcmp(k,"nnnnnnnn")) gr->Cone(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].v); else if(!strcmp(k,"nnnnnnnns")) gr->Cone(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].v, a[8].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_curve(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnnnnnn")) gr->Curve(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), mglPoint(a[4].v,a[5].v,NAN), mglPoint(a[6].v,a[7].v)); else if(!strcmp(k,"nnnnnnnns")) gr->Curve(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), mglPoint(a[4].v,a[5].v,NAN), mglPoint(a[6].v,a[7].v), a[8].s.s); else if(!strcmp(k,"nnnnnnnnnnnn")) gr->Curve(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), mglPoint(a[6].v,a[7].v,a[8].v), mglPoint(a[9].v,a[10].v,a[11].v)); else if(!strcmp(k,"nnnnnnnnnnnns")) gr->Curve(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), mglPoint(a[6].v,a[7].v,a[8].v), mglPoint(a[9].v,a[10].v,a[11].v), a[12].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_drop(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->Drop(mglPoint(a[0].v,a[1].v), mglPoint(a[2].v,a[3].v), a[4].v); else if(!strcmp(k,"nnnnns")) gr->Drop(mglPoint(a[0].v,a[1].v), mglPoint(a[2].v,a[3].v), a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnsn")) gr->Drop(mglPoint(a[0].v,a[1].v), mglPoint(a[2].v,a[3].v), a[4].v, a[5].s.s, a[6].v); else if(!strcmp(k,"nnnnnsnn")) gr->Drop(mglPoint(a[0].v,a[1].v), mglPoint(a[2].v,a[3].v), a[4].v, a[5].s.s, a[6].v, a[7].v); else if(!strcmp(k,"nnnnnnn")) gr->Drop(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v); else if(!strcmp(k,"nnnnnnns")) gr->Drop(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].s.s); else if(!strcmp(k,"nnnnnnnsn")) gr->Drop(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].s.s, a[8].v); else if(!strcmp(k,"nnnnnnnsnn")) gr->Drop(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].s.s, a[8].v, a[9].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_ellipse(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->Ellipse(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v); else if(!strcmp(k,"nnnnns")) gr->Ellipse(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnnn")) gr->Ellipse(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v); else if(!strcmp(k,"nnnnnnns")) gr->Ellipse(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_errbox(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnn")) gr->Error(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN)); else if(!strcmp(k,"nnnns")) gr->Error(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].s.s); else if(!strcmp(k,"nnnnnn")) gr->Error(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v)); else if(!strcmp(k,"nnnnnns")) gr->Error(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_face(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnnnnn")) gr->Face(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), mglPoint(a[4].v,a[5].v,NAN), mglPoint(a[6].v,a[7].v,NAN)); else if(!strcmp(k,"nnnnnnnns")) gr->Face(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), mglPoint(a[4].v,a[5].v,NAN), mglPoint(a[6].v,a[7].v,NAN), a[8].s.s); else if(!strcmp(k,"nnnnnnnnnnnn")) gr->Face(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), mglPoint(a[6].v,a[7].v,a[8].v), mglPoint(a[9].v,a[10].v,a[11].v)); else if(!strcmp(k,"nnnnnnnnnnnns")) gr->Face(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), mglPoint(a[6].v,a[7].v,a[8].v), mglPoint(a[9].v,a[10].v,a[11].v), a[12].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_facex(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->FaceX(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v); else if(!strcmp(k,"nnnnns")) gr->FaceX(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnsnn")) gr->FaceX(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v, a[5].s.s,a[6].v,a[7].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_facey(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->FaceY(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v); else if(!strcmp(k,"nnnnns")) gr->FaceY(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnsnn")) gr->FaceY(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v, a[5].s.s,a[6].v,a[7].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_facez(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->FaceZ(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v); else if(!strcmp(k,"nnnnns")) gr->FaceZ(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnsnn")) gr->FaceZ(mglPoint(a[0].v, a[1].v, a[2].v), a[3].v, a[4].v, a[5].s.s,a[6].v,a[7].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); char *buf; buf = new char[4096]; FILE *fp; if(!strncmp(k,"nns",3)) { int i, n = (k[3]=='n'?mgl_int(a[3].v):0); fp = fopen(a[2].s.s,"rt"); if(!fp) { gr->SetWarn(mglWarnOpen,a[2].s.s); delete []buf; return res; } for(i=0;iSetWarn(mglWarnOpen,(std::string(a[2].s.s)+" - line "+mgl_str_num(n)).c_str()); fclose(fp); delete []buf; return res; } fclose(fp); gr->Puts(mglPoint(a[0].v,a[1].v,NAN),buf, (k[4]=='s')?a[4].s.s:"", k[5]=='n'?a[5].v:-1); } else if(!strncmp(k,"nnns",4)) { int i, n = (k[4]=='n'?mgl_int(a[4].v):0); fp = fopen(a[3].s.s,"rt"); if(!fp) { gr->SetWarn(mglWarnOpen,a[3].s.s); delete []buf; return res; } for(i=0;iSetWarn(mglWarnOpen,(std::string(a[3].s.s)+" - line "+mgl_str_num(n)).c_str()); fclose(fp); delete []buf; return res; } fclose(fp); gr->Puts(mglPoint(a[0].v,a[1].v,a[2].v),buf, (k[5]=='s')?a[5].s.s:"", k[6]=='n'?a[6].v:-1); } else res = 1; gr->Self()->LoadState(); delete []buf; return res; } //----------------------------------------------------------------------------- int static mgls_flame2d(mglGraph *, long, mglArg *a, const char *k, const char *) { mglData *fx = dynamic_cast(a[0].d); mglData *fy = dynamic_cast(a[1].d); if(!fx) return 1; int res = 0; if (!strcmp(k, "dddn")) fx->Set(mglFlame2d(*(a[1].d), *(a[2].d), mgl_int(a[3].v))); else if (!strcmp(k, "ddddn") && fy) { mglData f(mglFlame2d(*(a[2].d), *(a[3].d), mgl_int(a[4].v))); fx->Set(f.SubData(0)); fy->Set(f.SubData(1)); } else if (!strcmp(k, "dddnn")) fx->Set(mglFlame2d(*(a[1].d), *(a[2].d), mgl_int(a[3].v), mgl_int(a[4].v))); else if (!strcmp(k, "ddddnn") && fy) { mglData f(mglFlame2d(*(a[2].d), *(a[3].d), mgl_int(a[4].v), mgl_int(a[5].v))); fx->Set(f.SubData(0)); fy->Set(f.SubData(1)); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fplot(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->FPlot(a[0].s.s, "",opt); else if(!strcmp(k,"ss")) gr->FPlot(a[0].s.s, a[1].s.s,opt); else if(!strcmp(k,"sss")) gr->FPlot(a[0].s.s, a[1].s.s, a[2].s.s, "",opt); else if(!strcmp(k,"ssss")) gr->FPlot(a[0].s.s, a[1].s.s, a[2].s.s, a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fsurf(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->FSurf(a[0].s.s, "",opt); else if(!strcmp(k,"ss")) gr->FSurf(a[0].s.s, a[1].s.s,opt); else if(!strcmp(k,"sss")) gr->FSurf(a[0].s.s, a[1].s.s, a[2].s.s, "",opt); else if(!strcmp(k,"ssss")) gr->FSurf(a[0].s.s, a[1].s.s, a[2].s.s, a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_grid(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]==0) gr->Grid("xyzt", "B",opt); else if(!strcmp(k,"s")) gr->Grid(a[0].s.s, "B",opt); else if(!strcmp(k,"ss"))gr->Grid(a[0].s.s, a[1].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ifs2d(mglGraph *, long, mglArg *a, const char *k, const char *) { mglData *fx = dynamic_cast(a[0].d); mglData *fy = dynamic_cast(a[1].d); if(!fx) return 1; int res = 0; if (!strcmp(k, "ddn")) fx->Set(mglIFS2d(*(a[1].d), mgl_int(a[2].v))); else if (!strcmp(k, "dddn") && fy) { mglData f(mglIFS2d(*(a[2].d), mgl_int(a[3].v))); fx->Set(f.SubData(0)); fy->Set(f.SubData(1)); } else if (!strcmp(k, "ddnn")) fx->Set(mglIFS2d(*(a[1].d), mgl_int(a[2].v), mgl_int(a[3].v))); else if (!strcmp(k, "dddnn") && fy) { mglData f(mglIFS2d(*(a[2].d), mgl_int(a[3].v), mgl_int(a[4].v))); fx->Set(f.SubData(0)); fy->Set(f.SubData(1)); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ifs3d(mglGraph *, long, mglArg *a, const char *k, const char *) { mglData *f = dynamic_cast(a[0].d); if(!f) return 1; int res = 0; if (!strcmp(k, "ddn")) f->Set(mglIFS3d(*(a[1].d), mgl_int(a[2].v))); else if (!strcmp(k, "ddnn")) f->Set(mglIFS3d(*(a[1].d), mgl_int(a[2].v), mgl_int(a[3].v))); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ifsfile(mglGraph *, long, mglArg *a, const char *k, const char *) { mglData *f = dynamic_cast(a[0].d); if(!f) return 1; int res = 0; if (!strcmp(k, "dssn")) f->Set(mglIFSfile(a[1].s.s, a[2].s.s, mgl_int(a[3].v))); else if (!strcmp(k, "dssnn")) f->Set(mglIFSfile(a[1].s.s, a[2].s.s, mgl_int(a[3].v), mgl_int(a[4].v))); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_legend(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]==0) gr->Legend(3, "#", opt); else if(!strcmp(k,"n")) gr->Legend(mgl_int(a[0].v), "#", opt); else if(!strcmp(k,"ns")) gr->Legend(mgl_int(a[0].v), a[1].s.s, opt); else if(!strcmp(k,"nn")) gr->Legend(a[0].v, a[1].v, "#", opt); else if(!strcmp(k,"nns")) gr->Legend(a[0].v, a[1].v, a[2].s.s, opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_line(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnn")) gr->Line(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN)); else if(!strcmp(k,"nnnns")) gr->Line(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].s.s); else if(!strcmp(k,"nnnnnn")) gr->Line(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v)); else if(!strcmp(k,"nnnnnns")) gr->Line(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_logo(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->Logo(a[0].s.s,false,opt); else if(!strcmp(k,"sn")) gr->Logo(a[0].s.s,mgl_int(a[1].v),opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_polygon(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->Polygon(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), mgl_int(a[4].v)); else if(!strcmp(k,"nnnnns")) gr->Polygon(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), mgl_int(a[4].v), a[5].s.s); else if(!strcmp(k,"nnnnnnn")) gr->Polygon(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), mgl_int(a[6].v)); else if(!strcmp(k,"nnnnnnns")) gr->Polygon(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), mgl_int(a[6].v), a[7].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_rect(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnn")) gr->Face(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[0].v,a[3].v,NAN), mglPoint(a[2].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN)); else if(!strcmp(k,"nnnns")) gr->Face(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[0].v,a[3].v,NAN), mglPoint(a[2].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN),a[4].s.s); else if(!strncmp(k,"nnnnnn",6)) { if(a[0].v==a[3].v) gr->Face(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[0].v,a[4].v,a[2].v), mglPoint(a[3].v,a[1].v,a[5].v), mglPoint(a[3].v,a[4].v,a[5].v), k[6]=='s' ? a[6].s.s : 0); else gr->Face(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[0].v,a[4].v,a[5].v), mglPoint(a[3].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), k[6]=='s' ? a[6].s.s : 0); } else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_rhomb(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnnnn")) gr->Rhomb(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v); else if(!strcmp(k,"nnnnns")) gr->Rhomb(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v, a[5].s.s); else if(!strcmp(k,"nnnnnnn")) gr->Rhomb(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v); else if(!strcmp(k,"nnnnnnns")) gr->Rhomb(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].v, a[7].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_sphere(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nnn")) gr->Sphere(mglPoint(a[0].v,a[1].v), a[2].v); else if(!strcmp(k,"nnns")) gr->Sphere(mglPoint(a[0].v,a[1].v), a[2].v, a[3].s.s); else if(!strcmp(k,"nnnn")) gr->Sphere(mglPoint(a[0].v,a[1].v,a[2].v), a[3].v); else if(!strcmp(k,"nnnns")) gr->Sphere(mglPoint(a[0].v,a[1].v,a[2].v), a[3].v, a[4].s.s); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_symbol(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) // NOTE don't use options -- Puts can be part of group { int res=0; if(k[0]=='n') { gr->Self()->SaveState(opt); if(!strcmp(k,"nns")) gr->Symbol(mglPoint(a[0].v,a[1].v,NAN),a[2].s[0]); else if(!strcmp(k,"nnss")) gr->Symbol(mglPoint(a[0].v,a[1].v,NAN),a[2].s[0], a[3].s.s); else if(!strcmp(k,"nnssn")) gr->Symbol(mglPoint(a[0].v,a[1].v,NAN),a[2].s[0], a[3].s.s,a[4].v); else if(!strcmp(k,"nnns")) gr->Symbol(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s[0]); else if(!strcmp(k,"nnnss")) gr->Symbol(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s[0], a[4].s.s); else if(!strcmp(k,"nnnssn"))gr->Symbol(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s[0], a[4].s.s,a[5].v); else if(!strcmp(k,"nnnns")) gr->Symbol(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), a[4].s[0]); else if(!strcmp(k,"nnnnss")) gr->Symbol(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), a[4].s[0], a[5].s.s); else if(!strcmp(k,"nnnnssn")) gr->Symbol(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), a[4].s[0], a[5].s.s,a[6].v); else if(!strcmp(k,"nnnnnns")) gr->Symbol(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s[0]); else if(!strcmp(k,"nnnnnnss")) gr->Symbol(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s[0], a[7].s.s); else if(!strcmp(k,"nnnnnnssn")) gr->Symbol(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s[0], a[7].s.s,a[8].v); else res=1; gr->Self()->LoadState(); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_text(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) // NOTE don't use options -- Puts can be part of group { int res=0; if(k[0]=='n') { gr->Self()->SaveState(opt); if(!strcmp(k,"nns")) gr->Putsw(mglPoint(a[0].v,a[1].v,NAN),a[2].s.w); else if(!strcmp(k,"nnss")) gr->Putsw(mglPoint(a[0].v,a[1].v,NAN),a[2].s.w, a[3].s.s); else if(!strcmp(k,"nnssn")) gr->Putsw(mglPoint(a[0].v,a[1].v,NAN),a[2].s.w, a[3].s.s,a[4].v); else if(!strcmp(k,"nnns")) gr->Putsw(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s.w); else if(!strcmp(k,"nnnss")) gr->Putsw(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s.w, a[4].s.s); else if(!strcmp(k,"nnnssn")) gr->Putsw(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s.w, a[4].s.s,a[5].v); else if(!strcmp(k,"nnnns")) gr->Putsw(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), a[4].s.w); else if(!strcmp(k,"nnnnss")) gr->Putsw(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), a[4].s.w, a[5].s.s); else if(!strcmp(k,"nnnnssn")) gr->Putsw(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v), a[4].s.w, a[5].s.s,a[6].v); else if(!strcmp(k,"nnnnnns")) gr->Putsw(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s.w); else if(!strcmp(k,"nnnnnnss")) gr->Putsw(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s.w, a[7].s.s); else if(!strcmp(k,"nnnnnnssn")) gr->Putsw(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), a[6].s.w, a[7].s.s,a[8].v); else res=1; gr->Self()->LoadState(); } else if(!strcmp(k,"ds")) gr->Text(*(a[0].d),a[1].s.w,"",opt); else if(!strcmp(k,"dss")) gr->Text(*(a[0].d),a[1].s.w,a[2].s.s,opt); else if(!strcmp(k,"dds")) gr->Text(*(a[0].d),*(a[1].d),a[2].s.w,"",opt); else if(!strcmp(k,"ddss")) gr->Text(*(a[0].d),*(a[1].d),a[2].s.w,a[3].s.s,opt); else if(!strcmp(k,"ddds")) gr->Text(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.w,"",opt); else if(!strcmp(k,"dddss")) gr->Text(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.w,a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_title(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"s")) gr->Title(a[0].s.w); else if(!strcmp(k,"ss")) gr->Title(a[0].s.w, a[1].s.s); else if(!strcmp(k,"ssn")) gr->Title(a[0].s.w, a[1].s.s,a[2].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_clabel(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->Label('c', a[0].s.w, 1, opt); else if(!strcmp(k,"sn")) gr->Label('c', a[0].s.w, a[1].v, opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tlabel(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->Label('t', a[0].s.w, 1, opt); else if(!strcmp(k,"sn")) gr->Label('t', a[0].s.w, a[1].v, opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_xlabel(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->Label('x', a[0].s.w, 1, opt); else if(!strcmp(k,"sn")) gr->Label('x', a[0].s.w, a[1].v, opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ylabel(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->Label('y', a[0].s.w, 1, opt); else if(!strcmp(k,"sn")) gr->Label('y', a[0].s.w, a[1].v, opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_zlabel(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"s")) gr->Label('z', a[0].s.w, 1, opt); else if(!strcmp(k,"sn")) gr->Label('z', a[0].s.w, a[1].v, opt); else res = 1; return res; } //----------------------------------------------------------------------------- mglCommand mgls_prm_cmd[] = { {"arc",_("Draw angle arc"),"arc x0 y0 x1 y1 a ['fmt']|x0 y0 z0 x1 y1 a ['fmt']|x0 y0 z0 xr yr zr x1 y1 z1 a ['fmt']", mgls_arc ,13}, {"axis",_("Setup or draw axis"),"axis ['dir' 'fmt']|'fx' 'fy' 'fz' ['fc']|how", mgls_axis ,12}, {"background",_("Load image for background"),"background 'fname' [alpha]", mgls_background ,12}, {"ball",_("Draw point (ball)"),"ball posx posy ['fmt']|posx posy posz ['fmt']", mgls_ball ,13}, {"box",_("Draw bounding box"),"box ['fmt' ticks]", mgls_box ,12}, {"circle",_("Draw circle"),"circle x y r ['fmt']|x y z r ['fmt']", mgls_circle ,13}, {"clabel",_("Draw label for colorbar"),"clabel 'txt' [pos]", mgls_clabel ,12}, {"colorbar",_("Draw colorbar"),"colorbar ['fmt']|Vdat ['fmt']|'sch' x y [w h]|Vdat 'sch' x y [w h]", mgls_colorbar ,12}, {"cone",_("Draw cone"),"cone x1 y1 z1 x2 y2 z2 r1 [r2 'fmt' edge]", mgls_cone ,13}, {"curve",_("Draw curve"),"curve x1 y1 dx1 dy1 x2 y2 dx2 dy2 ['fmt']|x1 y1 z1 dx1 dy1 dz1 x2 y2 z2 dx2 dy2 dz2 ['fmt']", mgls_curve ,13}, {"drop",_("Draw drop"),"drop x0 y0 dx dy r ['col' sh asp]|x0 y0 z0 dx dy dz r ['col' sh asp]", mgls_drop ,13}, {"ellipse",_("Draw ellipse"),"ellipse x1 y1 x2 y2 r ['fmt']|x1 y1 z1 x2 y2 z2 r ['fmt']", mgls_ellipse ,13}, {"errbox",_("Draw error box"),"errbox x y ex ey ['fmt']|x y z ex ey ez ['fmt']", mgls_errbox ,13}, {"face",_("Draw face (quadrangle)"),"face x1 y1 x2 y2 x3 y3 x4 y4 ['fmt']|x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 ['fmt']", mgls_face ,13}, {"facex",_("Draw face perpendicular to x-axis"),"facex x0 y0 z0 wy wz ['fmt' d1 d2]", mgls_facex ,13}, {"facey",_("Draw face perpendicular to y-axis"),"facex x0 y0 z0 wx wz ['fmt' d1 d2]", mgls_facey ,13}, {"facez",_("Draw face perpendicular to z-axis"),"facex x0 y0 z0 wy wz ['fmt' d1 d2]", mgls_facez ,13}, {"fgets",_("Print string from file"),"fgets x y z 'fname' [pos 'fmt' size]|x y z 'fname' [pos 'fmt' size]", mgls_fgets ,15}, {"flame2d",_("Computes the flame fractal"), "flame2d F A B n [skip]|Fx Fy A B n [skip]", mgls_flame2d, 4}, {"fplot",_("Plot curve by formula"),"fplot 'y(x)' ['fmt']|'x(t)' 'y(t)' 'z(t)' ['fmt']", mgls_fplot ,1}, {"fsurf",_("Plot surface by formula"),"fsurf 'z(x,y)' ['fmt']|'x(u,v)' 'y(u,v)' 'z(u,v)' ['fmt']", mgls_fsurf ,1}, {"grid",_("Draw grid"),"grid ['dir' 'fmt']", mgls_grid ,12}, {"ifs2d",_("Computes the attractor of an IFS"), "ifs2d F A n [skip]|Fx Fy A n [skip]", mgls_ifs2d, 4}, {"ifs3d",_("Computes the attractor of an IFS for 3d case"), "ifs3d F A n [skip]", mgls_ifs3d, 4}, {"ifsfile",_("Computes the attractor of an IFS with parameters from *.ifs file"), "ifsfile F 'fname' 'name' n [skip]", mgls_ifsfile, 4}, {"legend",_("Draw legend"),"legend [pos 'fmt']|x y ['fmt']", mgls_legend ,15}, {"line",_("Draw line"),"line x1 y1 x2 y2 ['fmt']|x1 y1 z1 x2 y2 z2 ['fmt']", mgls_line ,13}, {"logo",_("Draw bitmap (logo) along axis range"),"logo 'fname' [smooth]", mgls_logo ,13}, {"polygon",_("Draw polygon"),"polygon x1 y1 x2 y2 num ['fmt']|x1 y1 z1 x2 y2 z2 num ['fmt']", mgls_polygon ,13}, {"rect",_("Draw rectangle"),"rect x1 y1 x2 y2 ['fmt']|x1 y1 z1 x2 y2 z2 ['fmt']", mgls_rect ,13}, {"rhomb",_("Draw rhombus"),"rhomb x1 y1 x2 y2 r ['fmt']|x1 y1 z1 x2 y2 z2 r ['fmt']", mgls_rhomb ,13}, {"sphere",_("Draw sphere"),"sphere x0 y0 r ['fmt']|x0 y0 z0 r ['fmt']", mgls_sphere ,13}, {"symbol",_("Draw user-defined symbol at given position and direction"),"symbol x y 'id' ['fmt' size]|x y z 'id' ['fmt' size]|x y dx dy 'id' ['fmt' size]|x y z dx dy dz 'id' ['fmt' size]", mgls_symbol ,15}, {"text",_("Draw text at some position or along curve"),"text x y 'txt' ['fmt' size]|x y z 'txt' ['fmt' size]|x y dx dy 'txt' ['fmt' size]|x y z dx dy dz 'txt' ['fmt' size]|Ydat 'txt' ['font']|Xdat Ydat 'txt' ['font']|Xdat Ydat Zdat 'txt' ['font']", mgls_text ,15}, {"title",_("Add title for current subplot/inplot"),"title 'txt' ['fmt' size]", mgls_title ,5}, {"tlabel",_("Draw label for t-axis"),"tlabel 'txt' [pos]", mgls_tlabel ,12}, {"xlabel",_("Draw label for x-axis"),"xlabel 'txt' [pos]", mgls_xlabel ,12}, {"ylabel",_("Draw label for y-axis"),"ylabel 'txt' [pos]", mgls_ylabel,12}, {"zlabel",_("Draw label for z-axis"),"zlabel 'txt' [pos]", mgls_zlabel,12}, {"","","",NULL,0}}; //----------------------------------------------------------------------------- mathgl-2.4.4/src/export_3d.cpp0000644000175000017500000015671613513030041016367 0ustar alastairalastair/*************************************************************************** * export_3d.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mgl2/canvas.h" #include "mgl2/canvas_cf.h" #undef _GR_ #define _GR_ ((mglCanvas *)(*gr)) #define _Gr_ ((mglCanvas *)(gr)) int MGL_NO_EXPORT mgl_tga_save(const char *fname, int w, int h, unsigned char **p); int MGL_NO_EXPORT mgl_pnga_save(const char *fname, int w, int h, unsigned char **p); void MGL_NO_EXPORT mgl_printf(void *fp, bool gz, const char *str, ...); std::string MGL_NO_EXPORT mgl_sprintf(const char *str, ...); //----------------------------------------------------------------------------- void mglTexture::GetRGBA(unsigned char *f) const { for(long i=255;i>=0;i--) { mglColor c1 = col[2*i], c2 = col[2*i+1]; for(long j=0;j<256;j++) { long i0 = 4*(j+256*i); mglColor c = c1 + (c2-c1)*(j/255.); f[i0] = int(255*c.r); f[i0+1] = int(255*c.g); f[i0+2] = int(255*c.b); f[i0+3] = int(255*c.a); } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_obj_glyph_old(HMGL gr, const mglPrim &q, const mglPnt &p, FILE *fp) { mreal f = q.p/2, dx=p.u/2, dy=p.v/2, x,y; mreal c=q.s*cos(q.w*M_PI/180), s=-q.s*sin(q.w*M_PI/180); if(mgl_isnan(q.s)) c=s=0; double b[4] = {c,-s, s,c}; long i=q.n1+1; const mglGlyph &g = gr->GetGlf(q.n4); const mreal dd = 0.004; if(q.n3&8) { fprintf(fp,"v %g %g %g\n",p.x+b[0]*dx+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z); fprintf(fp,"v %g %g %g\n",p.x+b[0]*dx+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z); fprintf(fp,"v %g %g %g\n",p.x+b[0]*(dx+f)+b[1]*(dy-dd),p.y+b[2]*dx+b[3]*(dy-dd),p.z); fprintf(fp,"v %g %g %g\n",p.x+b[0]*(dx+f)+b[1]*(dy+dd),p.y+b[2]*dx+b[3]*(dy+dd),p.z); if(!(q.n3&4)) // glyph_line(p,f,true, d); { fprintf(fp,"f -1/%ld -3/%ld -2/%ld\n",i,i,i); fprintf(fp,"f -4/%ld -2/%ld -3/%ld\n",i,i,i); } else // glyph_line(p,f,false, d); { fprintf(fp,"l -1/%ld -2/%ld\n",i,i); fprintf(fp,"l -3/%ld -4/%ld\n",i,i); fprintf(fp,"l -1/%ld -3/%ld\n",i,i); fprintf(fp,"l -2/%ld -4/%ld\n",i,i); } } else { if(!(q.n3&4)) // glyph_fill(p,f,g, d); { for(long ik=0;ik': fprintf(fp,"v %g %g %g\n",p.x-ss/2,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss/2,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); break; case 'O': for(long j=0;j<=20;j++) fprintf(fp,"v %g %g %g\n",p.x+ss*mgl_cos[(j*36)%360],p.y+ss*mgl_cos[(270+j*36)%360],p.z); for(long j=0;j<20;j++) fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", j-21,i, j-20,i, i,i); break; case 'C': fprintf(fp,"p %ld\n", i); case 'o': for(long j=0;j<=20;j++) fprintf(fp,"v %g %g %g\n",p.x+ss*mgl_cos[(j*36)%360],p.y+ss*mgl_cos[(270+j*36)%360],p.z); for(long j=0;j<20;j++) fprintf(fp,"l %ld/%ld %ld/%ld\n", j-21,i, j-20,i); break; } break; case 1: fprintf(fp,"l %ld/%ld %ld/%ld\n", n1,n1, n2,n2); break; case 2: fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n1,n1, n2,n2, n3,n3); break; case 3: fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n1,n1, n2,n2, n3,n3); fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n2,n2, n4,n4, n3,n3); break; case 4: mgl_obj_glyph_old(gr,q,p,fp); break; } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr, int use_png) { if(gr->GetPrmNum()==0) return; // nothing to do long m1=0,m2=0; for(size_t i=0;iGrp.size();i++) // prepare array of indirect indexing { long m = gr->Grp[i].Id; if(mm2) m2=m; } long *ng = new long[m2-m1+1]; for(size_t i=0;iGrp.size();i++) ng[gr->Grp[i].Id-m1] = i; for(long i=0;iGetPrmNum();i++) // collect data for groups // it is rather expensive (extra 4b per primitive) but need for export to 3D { long m = gr->GetPrm(i,false).id-m1; if(m>=0 && mGrp[ng[m]].p.push_back(i); } delete []ng; size_t len=strlen(fname),ntxt=gr->GetTxtNum(); FILE *fp=fopen(fname,"wt"); if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } // vertices definition const std::string loc = setlocale(LC_NUMERIC, "C"); fprintf(fp,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); for(long i=0;iGetPntNum();i++) { const mglPnt &pp = gr->GetPnt(i); fprintf(fp,"v %g %g %g\n",pp.x,pp.y,pp.z); fprintf(fp,"vt %g %g\n",1-pp.ta,1-pp.c/ntxt); // if(mgl_isnan(pp.u)) fprintf(fp,"vn 0 0 0\n"); // else fprintf(fp,"vn %g %g %g\n",pp.u,pp.v,pp.w); } // primitive definition in groups char *tname = new char[len+15]; strcpy(tname,fname); tname[len-4]=0; fprintf(fp,"# Primitives Definitions\nmtllib %s.mtl\nusemtl %s\n",tname,tname); for(size_t i=0;iGrp.size();i++) { fprintf(fp,"g %s\n",gr->Grp[i].Lbl.c_str()); std::vector &p = gr->Grp[i].p; for(size_t j=0;jGetPrm(p[j],false); mgl_obj_prim_old(gr, q, gr->GetPnt(q.n1), fp, mgl_isnan(q.s)?0:q.s); } gr->Grp[i].p.clear(); // we don't need indexes anymore } // try to save "ungrouped" primitives fclose(fp); // prepare MTL file tname[len-4]='.'; tname[len-3]='m'; tname[len-2]='t'; tname[len-1]='l'; fp=fopen(tname,"wt"); tname[len-4]=0; fprintf(fp,"newmtl %s\n",tname); fprintf(fp,"Ka 1.000 1.000 1.000\n"); fprintf(fp,"Kd 1.000 1.000 1.000\n"); fprintf(fp,"Ks 0.000 0.000 0.000\n"); fprintf(fp,"d 1.0\nTr 0.0\nillum 2\n"); if(use_png) strcat(tname,"_texture.png"); // { tname[len-4]='.'; tname[len-3]='p'; tname[len-2]='n'; tname[len-1]='g'; } else strcat(tname,"_texture.tga"); // { tname[len-4]='.'; tname[len-3]='t'; tname[len-2]='g'; tname[len-1]='a'; } fprintf(fp,"map_Ka %s\nmap_Kd %s\nmap_Ks %s\n",tname,tname,tname); fclose(fp); // prepare texture file (TGA or PNG) long j=gr->GetTxtNum(); unsigned char *buf = new unsigned char[4*256*256*j]; unsigned char **pbuf= (unsigned char **)malloc(256*j*sizeof(unsigned char *)); for(long i=0;i<256*j;i++) pbuf[i] = buf+4*256*i; for(long i=0;iGetTxt(i).GetRGBA(buf+i*256*256*4); if(use_png) mgl_pnga_save(tname,256,256*j,pbuf); else mgl_tga_save(tname,256,256*j,pbuf); free(pbuf); delete []buf; delete []tname; setlocale(LC_NUMERIC, loc.c_str()); } void MGL_EXPORT mgl_write_obj_old_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_obj_old(_GR_,s,d,*use_png); delete []s; delete []d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_stl(HMGL gr, const char *fname,const char *descr) { if(gr->GetPrmNum()==0) return; // nothing to do FILE *fp = fopen(fname,"wt"); if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } const std::string loc = setlocale(LC_NUMERIC, "C"); fprintf(fp,"solid %s\n",(descr && *descr)?descr:"mathgl"); mglPnt pp; for(long i=0;iGetPrmNum();i++) { const mglPrim &q=gr->GetPrm(i,false); if(q.type==2) // triangles { pp = gr->GetPnt(q.n1); fprintf(fp,"facet normal %.2g %.2g %.2g\nouter loop\n",pp.u,pp.v,pp.w); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); pp = gr->GetPnt(q.n2); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); pp = gr->GetPnt(q.n3); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); fprintf(fp,"endloop\nendfacet\n"); } if(q.type==3) // quadrangles { pp = gr->GetPnt(q.n1); fprintf(fp,"facet normal %.2g %.2g %.2g\nouter loop\n",pp.u,pp.v,pp.w); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); pp = gr->GetPnt(q.n2); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); pp = gr->GetPnt(q.n3); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); fprintf(fp,"endloop\nendfacet\n"); pp = gr->GetPnt(q.n1); fprintf(fp,"facet normal %.2g %.2g %.2g\nouter loop\n",pp.u,pp.v,pp.w); pp = gr->GetPnt(q.n4); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); pp = gr->GetPnt(q.n2); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); pp = gr->GetPnt(q.n3); fprintf(fp,"vertex %g %g %g\n",pp.x,pp.y,pp.z); fprintf(fp,"endloop\nendfacet\n"); } } fprintf(fp,"endsolid %s",(descr && *descr)?descr:"mathgl"); fclose(fp); setlocale(LC_NUMERIC, loc.c_str()); } void MGL_EXPORT mgl_write_stl_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_stl(_GR_,s,d); delete []s; delete []d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_xyz(HMGL gr, const char *fname,const char *descr) { if(gr->GetPrmNum()==0) return; // nothing to do FILE *fp=fopen(fname,"wt"), *ff; // vertices definition if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } const std::string loc = setlocale(LC_NUMERIC, "C"); fprintf(fp,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); fprintf(fp,"# List of Vertices, with (x,y,z) coordinates.\n"); for(long i=0;iGetPntNum();i++) { const mglPnt &pp = gr->GetPnt(i); fprintf(fp,"%g %g %g\n",pp.x,pp.y,pp.z); } fclose(fp); // primitive definition size_t len=strlen(fname); char *tname = new char[len+2]; strcpy(tname,fname); tname[len+1]=tname[len]=0; tname[len]='l'; fp = fopen(tname,"wt"); tname[len]='f'; ff = fopen(tname,"wt"); fprintf(fp,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); fprintf(fp,"# Indices of vertices to connect for lines\n"); fprintf(ff,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); fprintf(ff,"# Indices of vertices to connect for faces\n"); for(long i=0;iGetPrmNum();i++) { const mglPrim &q=gr->GetPrm(i,false); if(q.type==1) fprintf(fp,"%ld %ld\n",q.n1+1,q.n2+1); if(q.type==2) fprintf(ff,"%ld %ld %ld\n",q.n1+1,q.n2+1,q.n3+1); if(q.type==3) fprintf(ff,"%ld %ld %ld\n%ld %ld %ld\n",q.n1+1,q.n2+1,q.n3+1,q.n4+1,q.n2+1,q.n3+1); } fclose(fp); fclose(ff); delete []tname; setlocale(LC_NUMERIC, loc.c_str()); } void MGL_EXPORT mgl_write_xyz_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_xyz(_GR_,s,d); delete []s; delete []d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_off(HMGL gr, const char *fname,const char *descr, int colored) { long nf=0; for(long i=0;iGetPrmNum();i++) // find number of faces { const mglPrim &q=gr->GetPrm(i,false); if(q.type==2 || q.type==3) nf++; } if(nf<=0) return; // nothing to do FILE *fp=fopen(fname,"wt"); if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } const std::string loc = setlocale(LC_NUMERIC, "C"); // vertices definition if(colored) fprintf(fp,"COFF\n# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); else fprintf(fp,"OFF\n# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname); fprintf(fp,"# List of Vertices, with (x,y,z,r,g,b,a) coordinates.\n"); fprintf(fp,"%ld %ld 0\n",gr->GetPntNum(), nf); for(long i=0;iGetPntNum();i++) { const mglPnt &pp = gr->GetPnt(i); if(colored) fprintf(fp,"%g %g %g %g %g %g %g\n", pp.x, pp.y, pp.z, pp.r, pp.g, pp.b, pp.a); else fprintf(fp,"%g %g %g\n", pp.x, pp.y, pp.z); } for(long i=0;iGetPrmNum();i++) { const mglPrim &q=gr->GetPrm(i,false); const mglPnt &p1=gr->GetPnt(q.n1); if(colored) { if(q.type==2) fprintf(fp,"3 %ld %ld %ld\n",q.n1,q.n2,q.n3); else if(q.type==3) fprintf(fp,"4 %ld %ld %ld %ld\n",q.n1,q.n2,q.n4,q.n3); } else { if(q.type==2) { const mglPnt &p2=gr->GetPnt(q.n2), &p3=gr->GetPnt(q.n3); if(p1.a>mgl_min_a || p2.a>mgl_min_a || p3.a>mgl_min_a) fprintf(fp,"3 %ld %ld %ld %.2g %.2g %.2g %.2g\n",q.n1,q.n2,q.n3, (p1.r+p2.r+p3.r)/3, (p1.g+p2.g+p3.g)/3, (p1.b+p2.b+p3.b)/3, (p1.a+p2.a+p3.a)/3); } else if(q.type==3) { const mglPnt &p2=gr->GetPnt(q.n2), &p3=gr->GetPnt(q.n3), &p4=gr->GetPnt(q.n4); if(p1.a>mgl_min_a || p2.a>mgl_min_a || p3.a>mgl_min_a || p4.a>mgl_min_a) fprintf(fp,"4 %ld %ld %ld %ld %.2g %.2g %.2g %.2g\n",q.n1,q.n2,q.n4,q.n3, (p1.r+p2.r+p3.r+p4.r)/4, (p1.g+p2.g+p3.g+p4.g)/4, (p1.b+p2.b+p3.b+p4.b)/4, (p1.a+p2.a+p3.a+p4.a)/4); } } } fclose(fp); setlocale(LC_NUMERIC, loc.c_str()); } void MGL_EXPORT mgl_write_off_(uintptr_t *gr, const char *fname,const char *descr,int *colored,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_off(_GR_,s,d,*colored); delete []s; delete []d; } //----------------------------------------------------------------------------- bool mglCanvas::WriteJSON(const char *fname, bool force_zlib) { bool fl = strcmp(fname,"-"); bool gz = force_zlib || fname[strlen(fname)-1]=='z'; void *fp = fl ? (gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt")) : stdout; if (!fp) return true; std::string s=GetJSON(); if(gz) gzprintf((gzFile)fp, "%s", s.c_str()); else fprintf((FILE *)fp, "%s", s.c_str()); if(fl) { if(gz) gzclose((gzFile)fp); else fclose((FILE *)fp); } return false; } //----------------------------------------------------------------------------- MGL_EXPORT const char *mgl_get_json(HMGL gr) { static std::string json; mglCanvas *g = dynamic_cast(gr); if(g) json = g->GetJSON(); return json.c_str(); } //----------------------------------------------------------------------------- std::string mglCanvas::GetJSON() { ClearUnused(); // clear unused points PreparePrim(3); std::string res, buf; long ll=0,l=(long)Pnt.size(); long factor = Width>1?10:10000; const std::string loc = setlocale(LC_NUMERIC, "C"); res = res + mgl_sprintf("{\n\"width\":%d,\t\"height\":%d,\t\"depth\":%d,\t\"plotid\":\"%s\",\t\"npnts\":%ld,\t\"pnts\":[\n", factor*Width, factor*Height, factor*Depth, PlotId.c_str(), l); for(long i=0;i xy; // vector for glyphs coordinates (to be separated from pnts) res.reserve(60*(ll+1)); #pragma omp parallel for private(buf) for(long i=0;in2) { n1=p.n2; n2=p.n1; } long ps=p.s==p.s?long(100*factor*p.s):0, pw=p.w==p.w?long(100*p.w):0, pp=p.p==p.p?mgl_int(1e5*p.p):0; if(cp.r[3]==255 || p.type==0 || p.type==1 || p.type==4 || p.type==6) buf = mgl_sprintf("[%d,%ld,%ld,%ld,%ld,%d,%ld,%ld,%ld,0,\"#%02x%02x%02x\"],\n", p.type, n1, n2, n3, n4, p.id, ps,pw,pp, int(cp.r[0]),int(cp.r[1]),int(cp.r[2])); else if(cp.r[3]) buf = mgl_sprintf("[%d,%ld,%ld,%ld,%ld,%d,%ld,%ld,%ld,0,\"rgba(%d,%d,%d,%.2g)\"],\n", p.type, n1, n2, n3, n4, p.id, ps,pw,pp, int(cp.r[0]),int(cp.r[1]),int(cp.r[2]),cp.r[3]/255.); else buf = ""; #pragma omp critical res += buf; } res += "[-1,0,0,0,0,0,0,0,0,0,\"#000000\"]\n"; // need to add this empty block l = (long)xy.size(); res = res + mgl_sprintf("],\t\"ncoor\":%lu,\t\"coor\":[\n",(unsigned long)l); for(long i=0;iWriteJSON(fname); } void MGL_EXPORT mgl_write_json_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_json(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_json_z(HMGL gr, const char *fname,const char *) { _Gr_->WriteJSON(fname,true); } void MGL_EXPORT mgl_write_json_z_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_json_z(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- bool mglCanvas::ExportMGLD(const char *fname, const char *descr) { if(Pnt.size()<1 || Prm.size()<1) return true; FILE *fp=fopen(fname,"wt"); if(!fp) return true; const std::string loc = setlocale(LC_NUMERIC, "C"); // NOTE: I'll save Ptx. So prim type=6 is useless,and no LaTeX fprintf(fp,"MGLD %lu %lu %lu %lu %d %d\n# %s\n", (unsigned long)Pnt.size(), (unsigned long)Prm.size(), (unsigned long)Txt.size(), (unsigned long)Glf.size(), Width, Height, (descr && *descr) ? descr : fname); fprintf(fp,"# Vertexes: x y z c t ta u v w r g b a\n"); for(size_t i=0;iExportMGLD(fname, descr); } void MGL_EXPORT mgl_export_mgld_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_export_mgld(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- bool mglCanvas::ImportMGLD(const char *fname, bool add) { FILE *fp=fopen(fname,"rt"); if(!fp) return true; char *buf=new char[512]; if(!fgets(buf,512,fp)) *buf=0; if(strncmp(buf,"MGLD",4)) { delete []buf; fclose(fp); return true; } unsigned long n=0,m=0,l=0,k=0, npnt=0, nglf=0; int w=0,h=0,d; sscanf(buf+5,"%lu%lu%lu%lu%d%d",&n,&m,&l,&k,&w,&h); if(w<=0 || h<=0) { w=Width; h=Height; } d = long(sqrt(double(w*h))); if(n==0 || m==0 || l==0) { delete []buf; fclose(fp); return true; } const std::string loc = setlocale(LC_NUMERIC, "C"); if(!add) { Clf(); Txt.clear(); } else { ClfZB(); npnt=Pnt.size(); nglf=Glf.size(); } LightScale(&B); #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexGlf); pthread_mutex_lock(&mutexPnt); pthread_mutex_lock(&mutexPrm); pthread_mutex_lock(&mutexTxt); #endif #pragma omp critical { Pnt.reserve(n); Prm.reserve(m); Txt.reserve(l); Glf.reserve(k); mglPnt p; float tmp; for(unsigned long i=0;i=0?q.n1+npnt:-1; q.n2 = q.n2>=0?q.n2+npnt:-1; switch(q.type) { case 3: q.n4 = q.n4>=0?q.n4+npnt:-1; case 2: q.n3 = q.n3>=0?q.n3+npnt:-1; q.m = mask; break; case 4: q.s *= (Width=0?q.n4+nglf:-1; break; } Prm.push_back(q); } mglTexture t; for(unsigned long i=0;i' ') k=1; if(sm==2 && k) break; } sscanf(buf,"%d%g", &sm, &a); t.Set(buf+j, sm, a); Txt.push_back(t); } mglGlyph g; for(unsigned long i=0;iImportMGLD(fname, add); } void MGL_EXPORT mgl_import_mgld_(uintptr_t *gr, const char *fname, int *add, int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; mgl_import_mgld(_GR_,s,*add); delete []s; } //----------------------------------------------------------------------------- /*void MGL_EXPORT mgl_xgl_prim(const mglPrim &q, const mglPnt &p, FILE *fp, mreal size) { char type = q.n4; mreal ss=size*0.35; long i=q.n1; switch(q.type) { case 0: if(!strchr("xsSoO",type)) ss *= 1.1; if(type=='.' || ss==0) fprintf(fp,"p %ld\n", i); else switch(type) // TODO: save mark by PATCH { case 'P': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss,p.z); fprintf(fp,"l -4/%ld -3/%ld\n", i,i); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -4/%ld\n", i,i); case '+': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y+ss,p.z); fprintf(fp,"l -4/%ld -3/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); break; case 'X': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss,p.z); fprintf(fp,"l -4/%ld -3/%ld\n", i,i); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -4/%ld\n", i,i); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); fprintf(fp,"l -2/%ld -4/%ld\n", i,i); break; case 'x': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss,p.z); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); fprintf(fp,"l -2/%ld -4/%ld\n", i,i); break; case 'S': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss,p.z); fprintf(fp,"f -4/%ld -3/%ld -2/%ld -1/%ld\n",i,i,i,i); break; case 's': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss,p.z); fprintf(fp,"l -4/%ld -3/%ld\n", i,i); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -4/%ld\n", i,i); break; case 'D': fprintf(fp,"v %g %g %g\n",p.x,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y,p.z); fprintf(fp,"f -4/%ld -3/%ld -2/%ld -1/%ld\n",i,i,i,i); break; case 'd': fprintf(fp,"v %g %g %g\n",p.x,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y,p.z); fprintf(fp,"l -4/%ld -3/%ld\n", i,i); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -4/%ld\n", i,i); break; case 'Y': fprintf(fp,"v %g %g %g\n",p.x,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+0.8*ss,p.y+0.6*ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-0.8*ss,p.y+0.6*ss,p.z); fprintf(fp,"l -3/%ld %ld/%ld\n", i,i,i); fprintf(fp,"l -2/%ld %ld/%ld\n", i,i,i); fprintf(fp,"l -1/%ld %ld/%ld\n", i,i,i); break; case '*': fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y,p.z); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"v %g %g %g\n",p.x+0.6*ss,p.y+0.8*ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-0.6*ss,p.y-0.8*ss,p.z); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"v %g %g %g\n",p.x+0.6*ss,p.y-0.8*ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-0.6*ss,p.y+0.8*ss,p.z); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); break; case 'T': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y+ss,p.z); fprintf(fp,"f -3/%ld -2/%ld -1/%ld\n", i,i,i); break; case '^': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y-ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y-ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y+ss,p.z); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); break; case 'V': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y-ss,p.z); fprintf(fp,"f -3/%ld -2/%ld -1/%ld\n", i,i,i); break; case 'v': fprintf(fp,"v %g %g %g\n",p.x-ss,p.y+ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y+ss/2,p.z); fprintf(fp,"v %g %g %g\n",p.x,p.y-ss,p.z); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); break; case 'L': fprintf(fp,"v %g %g %g\n",p.x+ss/2,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss/2,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y,p.z); fprintf(fp,"f -3/%ld -2/%ld -1/%ld\n", i,i,i); break; case '<': fprintf(fp,"v %g %g %g\n",p.x+ss/2,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss/2,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss,p.y,p.z); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); break; case 'R': fprintf(fp,"v %g %g %g\n",p.x-ss/2,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss/2,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"f -3/%ld -2/%ld -1/%ld\n", i,i,i); break; case '>': fprintf(fp,"v %g %g %g\n",p.x-ss/2,p.y+ss,p.z); fprintf(fp,"v %g %g %g\n",p.x-ss/2,p.y-ss,p.z); fprintf(fp,"v %g %g %g\n",p.x+ss,p.y,p.z); fprintf(fp,"l -3/%ld -2/%ld\n", i,i); fprintf(fp,"l -2/%ld -1/%ld\n", i,i); fprintf(fp,"l -1/%ld -3/%ld\n", i,i); break; case 'O': for(long j=0;j<=20;j++) fprintf(fp,"v %g %g %g\n",p.x+ss*mgl_cos[(j*36)%360],p.y+ss*mgl_cos[(270+j*36)%360],p.z); for(long j=0;j<20;j++) fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", j-21,i, j-20,i, i,i); break; case 'C': fprintf(fp,"p %ld\n", i); case 'o': for(long j=0;j<=20;j++) fprintf(fp,"v %g %g %g\n",p.x+ss*mgl_cos[(j*36)%360],p.y+ss*mgl_cos[(270+j*36)%360],p.z); for(long j=0;j<20;j++) fprintf(fp,"l %ld/%ld %ld/%ld\n", j-21,i, j-20,i); break; } break; case 1: fprintf(fp,"l %ld/%ld %ld/%ld\n", q.n1,q.n1, q.n2,q.n2); break; case 2: fprintf(fp,"f %ld/%ld/%ld %ld/%ld/%ld %ld/%ld/%ld\n", q.n1,q.n1,q.n1, q.n2,q.n2,q.n2, q.n3,q.n3,q.n3); break; case 3: fprintf(fp,"f %ld/%ld/%ld %ld/%ld/%ld %ld/%ld/%ld %ld/%ld/%ld\n", q.n1,q.n1,q.n1, q.n2,q.n2,q.n2, q.n3,q.n3,q.n3, q.n4,q.n4,q.n4); break; case 4: break; // TODO: add glyphs export later } } //----------------------------------------------------------------------------- void mglCanvas::WriteXGL(const char *fname,const char *descr) { if(GetPrmNum()==0) return; // nothing to do FILE *fp=fopen(fname,"wt"); if(!fp) return true; fprintf(fp,"\n%s\n", (descr && *descr)?descr:fname); fprintf(fp,"%g, %g, %g\n", BDef[0]/255., BDef[1]/255., BDef[2]/255.); fprintf(fp,"\n%g, %g, %g\n",AmbBr, AmbBr, AmbBr); if(get(MGL_ENABLE_LIGHT)) for(size_t i=0;i<10;i++) if(light[i].n && mgl_isnan(light[i].r.x)) { fprintf(fp, "\n%g, %g, %g\n", light[i].d.x, light[i].d.y, light[i].d.z); fprintf(fp, "%g, %g, %g\n\n", light[i].c.r, light[i].c.g, light[i].c.b); } fprintf(fp,""); // TODO: add textures long m1=0,m2=0,m; for(size_t i=0;im2) m2=m; } long *ng = new long[m2-m1+1]; for(size_t i=0;iGrp[i].Id-m1] = i; for(size_t i=0;i=0 && m p; mglPrim q; char *pg=new char[GetPntNum()]; for(size_t i=0;i\n%s\n\n",Grp[i].Lbl.c_str()); for(size_t j=0;j%g, %g, %g

\n",j, s.x, s.y, s.z); fprintf(fp,"%g, %g, %g\n",j, s.x, s.y, s.z); } // TODO: add line styles for(size_t j=0;j\n"); // finish with this object Grp[i].p.clear(); // we don't need indexes anymore } // TODO: try to save "ungrouped" primitives fprintf(fp,""); fclose(fp); delete []pg; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_xgl(HMGL gr, const char *fname,const char *descr) { _Gr_->WriteXGL(fname,descr); } void MGL_EXPORT mgl_write_xgl_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_xgl(_GR_,s,d); delete []s; delete []d; }*/ //----------------------------------------------------------------------------- void MGL_EXPORT mgl_x3d_mdef(HMGL gr, void *fp, bool gz) { /* bool m_p=false,m_x=false,m_d=false,m_v=false,m_t=false, m_s=false,m_a=false,m_o=false,m_T=false, m_V=false,m_S=false,m_D=false,m_Y=false,m_l=false, m_L=false,m_r=false,m_R=false,m_X=false,m_P=false; for(long i=0;iGetPrmNum();i++) { const mglPrim q = gr->GetPrm(i,false); if(q.type>0) continue; if(q.n4=='+') m_p = true; if(q.n4=='x') m_x = true; if(q.n4=='s') m_s = true; if(q.n4=='d') m_d = true; if(q.n4=='v') m_v = true; if(q.n4=='^') m_t = true; if(q.n4=='*') m_a = true; if(q.n4=='o' || q.n4=='O' || q.n4=='C') m_o = true; if(q.n4=='S') m_S = true; if(q.n4=='D') m_D = true; if(q.n4=='V') m_V = true; if(q.n4=='T') m_T = true; if(q.n4=='<') m_l = true; if(q.n4=='L') m_L = true; if(q.n4=='>') m_r = true; if(q.n4=='R') m_R = true; if(q.n4=='Y') m_Y = true; if(q.n4=='P') m_P = true; if(q.n4=='X') m_X = true; } if(m_P) { m_p=true; m_s=true; } if(m_X) { m_x=true; m_s=true; } if(m_p) mgl_printf(fp, gz, "\n" "\n" "\n\n");*/ /*if(m_x) mgl_printf(fp, gz, "/m_x {sm sm rm s2 s2 rl 0 sm 2 mul rm sm 2 mul s2 rl d0} def\n"); // TODO * if(m_s) mgl_printf(fp, gz, "/m_s {sm sm rm 0 s2 rl s2 0 rl 0 sm 2 mul rl cp d0} def\n"); * if(m_d) mgl_printf(fp, gz, "/m_d {sm 0 rm ss ss rl ss sm rl sm sm rl cp d0} def\n"); * if(m_v) mgl_printf(fp, gz, "/m_v {sm ss 2 div rm s2 0 rl sm sm 1.5 mul rl d0 cp} def\n"); * if(m_t) mgl_printf(fp, gz, "/m_t {sm sm 2 div rm s2 0 rl sm ss 1.5 mul rl d0 cp} def\n"); * if(m_a) mgl_printf(fp, gz, "/m_a {sm 0 rm s2 0 rl sm 1.6 mul sm 0.8 mul rm ss 1.2 mul ss 1.6 mul rl 0 sm 1.6 mul rm sm 1.2 mul ss 1.6 mul rl d0} def\n"); * if(m_o) mgl_printf(fp, gz, "/m_o {ss 0 360 d0 arc} def\n"); * if(m_S) mgl_printf(fp, gz, "/m_S {sm sm rm 0 s2 rl s2 0 rl 0 sm 2 mul rl cp} def\n"); * if(m_D) mgl_printf(fp, gz, "/m_D {sm 0 rm ss ss rl ss sm rl sm sm rl cp} def\n"); * if(m_V) mgl_printf(fp, gz, "/m_V {sm ss 2 div rm s2 0 rl sm sm 1.5 mul rl cp} def\n"); * if(m_T) mgl_printf(fp, gz, "/m_T {sm sm 2 div rm s2 0 rl sm ss 1.5 mul rl cp} def\n"); * if(m_Y) mgl_printf(fp, gz, "/m_Y {0 sm rm 0 ss rl sm ss rl s2 0 rm sm sm rl d0} def\n"); * if(m_r) mgl_printf(fp, gz, "/m_r {sm 2 div sm rm 0 s2 rl ss 1.5 mul sm rl d0 cp} def\n"); * if(m_l) mgl_printf(fp, gz, "/m_l {ss 2 div sm rm 0 s2 rl sm 1.5 mul sm rl d0 cp} def\n"); * if(m_R) mgl_printf(fp, gz, "/m_R {sm 2 div sm rm 0 s2 rl ss 1.5 mul sm rl cp} def\n"); * if(m_L) mgl_printf(fp, gz, "/m_L {ss 2 div sm rm 0 s2 rl sm 1.5 mul sm rl cp} def\n"); * if(m_P) mgl_printf(fp, gz, "/m_P {m_p 0 sm rm m_s} def\n"); * if(m_X) mgl_printf(fp, gz, "/m_X {m_x ss sm rm m_s} def\n");*/ // if(m_C) mgl_printf(fp, gz, "/m_C {m_c m_o} def\n"); // mgl_printf(fp, gz, "\n"); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_x3d_prim(const mglPrim &q, const mglPnt &p, const long *pnt, void *fp,bool gz, mreal size) { // /* if(q.type==0) // mark { mreal x0 = p1.x,y0 = p1.y; sprintf(str,"1 lw %.2g %.2g %.2g rgb ", cp.r,cp.g,cp.b); wp=1; if(q.s!=gr->mark_size()/gr->FontFactor()) { mgl_printf(fp, gz, "/ss {%g} def\n",q.s*0.4*gr->FontFactor()); mgl_printf(fp, gz, "/s2 {%g} def\n",q.s*0.8*gr->FontFactor()); mgl_printf(fp, gz, "/sm {-%g} def\n",q.s*0.4*gr->FontFactor()); } switch(q.n4) { case '+': mgl_printf(fp, gz, "np %g %g mt m_p %sdr\n",x0,y0,str); break; case 'x': mgl_printf(fp, gz, "np %g %g mt m_x %sdr\n",x0,y0,str); break; case 's': mgl_printf(fp, gz, "np %g %g mt m_s %sdr\n",x0,y0,str); break; case 'd': mgl_printf(fp, gz, "np %g %g mt m_d %sdr\n",x0,y0,str); break; case '*': mgl_printf(fp, gz, "np %g %g mt m_a %sdr\n",x0,y0,str); break; case 'v': mgl_printf(fp, gz, "np %g %g mt m_v %sdr\n",x0,y0,str); break; case '^': mgl_printf(fp, gz, "np %g %g mt m_t %sdr\n",x0,y0,str); break; case 'S': mgl_printf(fp, gz, "np %g %g mt m_S %sfill\n",x0,y0,str); break; case 'D': mgl_printf(fp, gz, "np %g %g mt m_D %sfill\n",x0,y0,str); break; case 'V': mgl_printf(fp, gz, "np %g %g mt m_V %sfill\n",x0,y0,str); break; case 'T': mgl_printf(fp, gz, "np %g %g mt m_T %sfill\n",x0,y0,str); break; case 'o': mgl_printf(fp, gz, "%g %g m_o %sdr\n",x0,y0,str);break; case 'O': mgl_printf(fp, gz, "%g %g m_o %sfill\n",x0,y0,str);break; case 'Y': mgl_printf(fp, gz, "np %g %g mt m_Y %sdr\n",x0,y0,str); break; case '<': mgl_printf(fp, gz, "np %g %g mt m_l %sdr\n",x0,y0,str); break; case '>': mgl_printf(fp, gz, "np %g %g mt m_r %sdr\n",x0,y0,str); break; case 'L': mgl_printf(fp, gz, "np %g %g mt m_L %sfill\n",x0,y0,str); break; case 'R': mgl_printf(fp, gz, "np %g %g mt m_R %sfill\n",x0,y0,str); break; case 'P': mgl_printf(fp, gz, "np %g %g mt m_P %sdr\n",x0,y0,str); break; case 'X': mgl_printf(fp, gz, "np %g %g mt m_X %sdr\n",x0,y0,str); break; case 'C': mgl_printf(fp, gz, "%g %g m_o %g %g m_c %sdr\n",x0,y0,x0,y0,str); break; default: mgl_printf(fp, gz, "%g %g m_c %sfill\n",x0,y0,str); } if(q.s!=gr->mark_size()/gr->FontFactor()) { mgl_printf(fp, gz, "/ss {%g} def\n",0.4*gr->mark_size()); mgl_printf(fp, gz, "/s2 {%g} def\n",0.8*gr->mark_size()); mgl_printf(fp, gz, "/sm {-%g} def\n",0.4*gr->mark_size()); } } else if(q.type==3) // quad { const mglPnt p2=gr->GetPnt(q.n2), p3=gr->GetPnt(q.n3), p4=gr->GetPnt(q.n4); mgl_printf(fp, gz, "np %g %g mt %g %g ll %g %g ll %g %g ll cp %sfill\n", p1.x, p1.y, p2.x, p2.y, p4.x, p4.y, p3.x, p3.y, str); } else if(q.type==2) // trig { const mglPnt p2=gr->GetPnt(q.n2), p3=gr->GetPnt(q.n3); mgl_printf(fp, gz, "np %g %g mt %g %g ll %g %g ll cp %sfill\n", p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, str); } else if(q.type==1) // line { sprintf(str,"%.2g lw %.2g %.2g %.2g rgb ", q.w>1 ? q.w:1., cp.r,cp.g,cp.b); wp = q.w>1 ? q.w:1; st = q.n3; put_line(gr,fp,gz,i,wp,cp,st, "np %g %g mt ", "%g %g ll ", false, 1); const char *sd = mgl_get_dash(q.n3,q.w); if(sd && sd[0]) mgl_printf(fp, gz, "%s [%s] %g sd dr\n",str,sd,q.w*q.s); else mgl_printf(fp, gz, "%s d0 dr\n",str); } else if(q.type==4) // glyph { mreal ss = q.s/2, xx = p1.u, yy = p1.v, zz = p1.w; mgl_printf(fp, gz, "gsave\t%g %g translate %g %g scale %g rotate %s\n", p1.x, p1.y, ss, ss, -q.w, str); if(q.n3&8) // this is "line" { mreal dy = 0.004,f=fabs(zz); mgl_printf(fp, gz, "np %g %g mt %g %g ll %g %g ll %g %g ll cp ", xx,yy+dy, xx+f,yy+dy, xx+f,yy-dy, xx,yy-dy); } else mgl_printf(fp, gz, "%.3g %.3g translate %g %g scale %c%c_%04x ", xx, yy, zz, zz, q.n3&1?'b':'n', q.n3&2?'i':'n', q.n4); if(q.n3&4) mgl_printf(fp, gz, "dr"); else mgl_printf(fp, gz, "eofill"); mgl_printf(fp, gz, " grestore\n"); }*/ } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr) { if(gr->GetPrmNum()<1) return; time_t now; time(&now); bool gz = fname[strlen(fname)-1]=='z'; void *fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt"); if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } const std::string loc = setlocale(LC_NUMERIC, "C"); mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n\n\n",fname); mgl_printf(fp, gz, "\n",(descr && *descr)?descr:fname); mgl_printf(fp, gz, "\n",ctime(&now)); mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n\n"); // 1. first we have to define proto for marks and glyphs mgl_x3d_mdef(gr, fp, gz); // here should be defined textures ... but since X3D support RGBA then omit it in this version // 2. now find group for primitives long m1=0,m2=0,m; for(size_t i=0;iGrp.size();i++) // prepare array of indirect indexing { m = gr->Grp[i].Id; if(mm2) m2=m; } long *ng = new long[m2-m1+1]; for(size_t i=0;iGrp.size();i++) ng[gr->Grp[i].Id-m1] = i; for(long i=0;iGetPrmNum();i++) // collect data for groups // it is rather expensive (extra 4b per primitive) but need for export to 3D { m = gr->GetPrm(i,false).id-m1; if(m>=0 && mGrp[ng[m]].p.push_back(i); } delete []ng; // primitive definition in groups long npnt = gr->GetPntNum(); long *pnt=new long[npnt]; mglPrim q; for(size_t i=0;iGrp.size();i++) { mgl_printf(fp,gz,"\n",gr->Grp[i].Lbl.c_str()); std::vector &p = gr->Grp[i].p; // define coordinates, colors and so on long line=-1, face=-1, other=-1; for(size_t j=0;jGetPrm(p[j],false); if(q.type==1) line=q.n1; // find kind of primitives in the group if(q.type==2 || q.type==3) face =q.n1; if(q.type>3 || q.type==0) other=q.n1; } // now save lines if(line>=0) { mglColor c=gr->GetPntC(line); bool same=true; // check if there are the same colors for all line segments for(size_t j=0;jGetPrm(p[j],false); if(q.type==1 && c!=gr->GetPntC(q.n1)) same=false; } memset(pnt,-1,npnt*sizeof(long)); for(size_t j=0,k=0;jGetPrm(p[j],false); if(q.type!=1) continue; if(q.n1>=0 && pnt[q.n1]<0) { pnt[q.n1]=k; k++; } if(q.n2>=0 && pnt[q.n2]<0) { pnt[q.n2]=k; k++; } } mgl_printf(fp, gz, ""); mgl_printf(fp, gz, ""); // TODO save IndexedLineSet here + manual color is same==true mgl_printf(fp, gz, ""); } // now save faces if(face>=0) { mglColor c=gr->GetPntC(face); bool same=true; // check if there are the same colors for all line segments for(size_t j=0;jGetPrm(p[j],false); if((q.type==2 || q.type==3) && c!=gr->GetPntC(q.n1)) same=false; } memset(pnt,-1,npnt*sizeof(long)); for(size_t j=0,k=0;jGetPrm(p[j],false); if(q.type!=2 && q.type!=3) continue; if(q.n1>=0 && pnt[q.n1]<0) { pnt[q.n1]=k; k++; } if(q.n2>=0 && pnt[q.n2]<0) { pnt[q.n2]=k; k++; } if(q.n3>=0 && pnt[q.n3]<0) { pnt[q.n3]=k; k++; } if(q.type==3 && q.n4>=0 && pnt[q.n4]<0) { pnt[q.n4]=k; k++; } } mgl_printf(fp, gz, ""); mgl_printf(fp, gz, ""); // TODO save IndexedLineSet here + manual color is same==true mgl_printf(fp, gz, ""); } // now save other primitives if(other>=0) { /* memset(pnt,-1,npnt*sizeof(long)); for(j=0,k=0;jGetPrm(p[j],false); if(q.type!=2 && q.type!=3) continue; if(q.n1>=0 && pnt[q.n1]<0) { pnt[q.n1]=k; k++; } if(q.n2>=0 && pnt[q.n2]<0) { pnt[q.n2]=k; k++; } if(q.n3>=0 && pnt[q.n3]<0) { pnt[q.n3]=k; k++; } if(q.type==3 && q.n4>=0 && pnt[q.n4]<0) { pnt[q.n4]=k; k++; } } mgl_printf(fp, gz, ""); mgl_printf(fp, gz, ""); // TODO save IndexedLineSet here + manual color is same==true mgl_printf(fp, gz, "");*/ } // no normals since mathgl ones are "signless" -- x3d should calculate it by itself for(size_t j=0;jGetPrm(p[j],false); // TODO: collect by type (quads,trig,line) and draw together??? mgl_x3d_prim(q, gr->GetPnt(q.n1), pnt, fp,gz, q.s*gr->FontFactor()); } mgl_printf(fp,gz,"\n",gr->Grp[i].Lbl.c_str()); gr->Grp[i].p.clear(); // we don't need indexes anymore } mgl_printf(fp, gz, "\n"); if(gz) gzclose((gzFile)fp); else fclose((FILE *)fp); setlocale(LC_NUMERIC, loc.c_str()); delete []pnt; } void MGL_EXPORT mgl_write_x3d_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_x3d(_GR_,s,d); delete []s; delete []d; } //----------------------------------------------------------------------------- mathgl-2.4.4/src/export_2d.cpp0000644000175000017500000010730113513030041016350 0ustar alastairalastair/*************************************************************************** * export_2d.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/canvas.h" #include "mgl2/canvas_cf.h" #include "mgl2/font.h" #include #include #include #undef _GR_ #define _GR_ ((mglCanvas *)(*gr)) #define _Gr_ ((mglCanvas *)(gr)) void mgl_printf(void *fp, bool gz, const char *str, ...); //----------------------------------------------------------------------------- static const char *mgl_get_dash(unsigned short d, mreal w,char dlm) { static std::string s; if(d==0xffff) return ""; int f=0, p=d&1, n=p?0:1; s = p ? "" : "0"; for(int i=0;i<16;i++) { int j = i;//15-i; if(((d>>j)&1) == p) f++; else { s += mgl_str_num(f*w)+dlm; p = (d>>j)&1; f = 1; n++; } } s += mgl_str_num(f*w) + ((n%2) ? "" : " 0"); return s.c_str(); } //----------------------------------------------------------------------------- bool MGL_LOCAL_PURE mgl_is_same(HMGL gr, long i, mreal wp,uint32_t cp, int st) { const mglPrim &pr=_Gr_->GetPrm(i); if(abs(pr.type)!=1) return false; if(pr.w>=1 && wp!=pr.w) return false; if(pr.w<1 && wp!=1) return false; if(st!=pr.n3) return false; return (cp==_Gr_->GetPrmCol(i)); } //----------------------------------------------------------------------------- std::vector static put_line(HMGL gr, long i, mreal wp, uint32_t cp,int st) { std::vector ids; long n1=gr->GetPrm(i).n1, n2=gr->GetPrm(i).n2; if(n1>n2) { n1=gr->GetPrm(i).n2; n2=gr->GetPrm(i).n1; } if(n1<0 || n2<0) return ids; const mglPnt &pp1 = gr->GetPnt(n1), &pp2 = gr->GetPnt(n2); mreal x0=pp1.x, y0=pp1.y; bool ok=true; long j; // first point while(ok) // try to find starting point { for(ok=false,j=i+1;jGetPrmNum();j++) { mglPrim &q = gr->GetPrm(j); if(q.type>1) break; if(mgl_is_same(gr, j, wp,cp,st) && q.type==1 && q.n1>=0 && q.n2>=0) // previous point { const mglPnt &p1 = gr->GetPnt(q.n1); const mglPnt &p2 = gr->GetPnt(q.n2); if(p2.x==x0 && p2.y==y0) { ok = true; ids.push_back(q.n1); x0 = p1.x; y0 = p1.y; q.type = -1; } else if(p1.x==x0 && p1.y==y0) { ok = true; ids.push_back(q.n2); x0 = p2.x; y0 = p2.y; q.type = -1; } } } } std::reverse(ids.begin(),ids.end()); ids.push_back(n1); ids.push_back(n2); x0 = pp2.x; y0 = pp2.y; ok = true; while(ok) // try to find starting point { for(ok=false,j=i+1;jGetPrmNum();j++) { mglPrim &q = gr->GetPrm(j); if(q.type>1) break; if(mgl_is_same(gr, j,wp,cp,st) && q.type==1 && q.n1>=0 && q.n2>=0) // next point { const mglPnt &p1 = gr->GetPnt(q.n1); const mglPnt &p2 = gr->GetPnt(q.n2); if(p2.x==x0 && p2.y==y0) { ok = true; ids.push_back(q.n1); x0 = p1.x; y0 = p1.y; q.type = -1; } else if(p1.x==x0 && p1.y==y0) { ok = true; ids.push_back(q.n2); x0 = p2.x; y0 = p2.y; q.type = -1; } } } } return ids; } //----------------------------------------------------------------------------- //put_desc(fp,"%c%c%c_%04x {", "np %d %d mt %d %d ll %d %d ll cp fill\n", //"np %d %d mt ", "%d %d ll ", "cp dr\n", "} def") void static put_desc(HMGL gr, void *fp, bool gz, const char *pre, const char *ln1, const char *ln2, const char *ln3, const char *suf) { long n=0; for(long i=0;iGetPrmNum();i++) if(gr->GetPrm(i).type==4) n++; if(n==0) return; // no glyphs wchar_t *g = new wchar_t[n]; int *s = new int[n]; n=0; for(long i=0;iGetPrmNum();i++) { const mglPrim q = gr->GetPrm(i); if(q.type!=4 || (q.n3&8)) continue; // not a glyph bool is=false; for(long j=0;jGetGlf(q.n4); int nl=g.nl; const short *ln=g.line; bool np=true; if(ln && nl>0) for(long ik=0;ik> pat\n"); } else { mgl_printf(fp, gz, "/PaintProc { gsave %d rotate\n",-ang); for(int i=-4;i<4;i++) for(int j=-4;j<4;j++) { int ii = (8+i)&7, jj = (8+j)&7; if(pd & (1L<<(ii+8*jj))) mgl_printf(fp, gz, "%g %g %g %g rf\n",i*pw,j*pw,pw,pw); } mgl_printf(fp, gz, "grestore}\n>> pat\n"); } return true; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr) { if(!fname || *fname==0) return; if(gr->GetPrmNum()<1) return; _Gr_->clr(MGL_FINISHED); _Gr_->PreparePrim(1); time_t now; time(&now); bool gz = fname[strlen(fname)-1]=='z'; void *fp; if(!strcmp(fname,"-")) fp = stdout; // allow to write in stdout else fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt"); if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } int w = _Gr_->GetWidth(), h = _Gr_->GetHeight(); int x1=gr->BBoxX1, x2=gr->BBoxX2<0?w:gr->BBoxX2, y1=gr->BBoxY1, y2=gr->BBoxY2<0?h:gr->BBoxY2; if(x1<0 || x1>=x2 || y1<0 || y1>=y2) { x1=y1=0; x2=w; y2=h; } if(gz) { unsigned len = strlen(fname), pos=0; char *buf = new char[len+4]; memcpy(buf,fname,len); if(buf[len-3]=='.') pos = len-2; else if(buf[len-2]=='.') pos = len-1; else { buf[len-1]='.'; pos = len; } if(pos) { buf[pos]=buf[pos+1]='b'; buf[pos+2]=0; } FILE *fb = fopen(buf,"w"); fprintf(fb, "%%%%BoundingBox: %d %d %d %d\n", x1, h-y2, x2, h-y1); fclose(fb); delete []buf; } const std::string loc = setlocale(LC_NUMERIC, "C"); mgl_printf(fp, gz, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: %d %d %d %d\n", x1, h-y2, x2, h-y1); mgl_printf(fp, gz, "%%%%Created by MathGL library\n%%%%Title: %s\n",descr ? descr : fname); mgl_printf(fp, gz, "%%%%CreationDate: %s\n",ctime(&now)); mgl_printf(fp, gz, "%%%%LanguageLevel: 2\n50 dict begin"); mgl_printf(fp, gz, "/lw {setlinewidth} def\n/rgb {setrgbcolor} def\n"); mgl_printf(fp, gz, "/np {newpath} def\n/cp {closepath} def\n"); mgl_printf(fp, gz, "/ll {lineto} def\n/mt {moveto} def\n"); mgl_printf(fp, gz, "/rl {rlineto} def\n/rm {rmoveto} def\n/dr {stroke} def\n"); mgl_printf(fp, gz, "/ss {%g} def\n",0.35*gr->mark_size()); mgl_printf(fp, gz, "/s2 {%g} def\n",0.7*gr->mark_size()); mgl_printf(fp, gz, "/sm {-%g} def\n",0.35*gr->mark_size()); mgl_printf(fp, gz, "/m_c {ss 0.3 mul 0 360 arc} def\n"); mgl_printf(fp, gz, "/d0 {[] 0 setdash} def\n/sd {setdash} def\n"); mgl_printf(fp, gz, "/pat {[1 0 0 1 0 0] makepattern /Mask exch def [/Pattern /DeviceRGB] setcolorspace} def\n"); mgl_printf(fp, gz, "/mask {Mask setpattern} def\n/rf {rectfill} def\n"); bool m_p=false,m_x=false,m_d=false,m_v=false,m_t=false, m_s=false,m_a=false,m_o=false,m_T=false, m_V=false,m_S=false,m_D=false,m_Y=false,m_l=false, m_L=false,m_r=false,m_R=false,m_X=false,m_P=false; // add mark definition if present for(long i=0;iGetPrmNum();i++) { const mglPrim q = gr->GetPrm(i); if(q.type>0) continue; if(q.n4=='+') m_p = true; if(q.n4=='x') m_x = true; if(q.n4=='s') m_s = true; if(q.n4=='d') m_d = true; if(q.n4=='v') m_v = true; if(q.n4=='^') m_t = true; if(q.n4=='*') m_a = true; if(q.n4=='o' || q.n4=='O' || q.n4=='C') m_o = true; if(q.n4=='S') m_S = true; if(q.n4=='D') m_D = true; if(q.n4=='V') m_V = true; if(q.n4=='T') m_T = true; if(q.n4=='<') m_l = true; if(q.n4=='L') m_L = true; if(q.n4=='>') m_r = true; if(q.n4=='R') m_R = true; if(q.n4=='Y') m_Y = true; if(q.n4=='P') m_P = true; if(q.n4=='X') m_X = true; } if(m_P) { m_p=true; m_s=true; } if(m_X) { m_x=true; m_s=true; } if(m_p) mgl_printf(fp, gz, "/m_p {sm 0 rm s2 0 rl sm sm rm 0 s2 rl d0} def\n"); if(m_x) mgl_printf(fp, gz, "/m_x {sm sm rm s2 s2 rl 0 sm 2 mul rm sm 2 mul s2 rl d0} def\n"); if(m_s) mgl_printf(fp, gz, "/m_s {sm sm rm 0 s2 rl s2 0 rl 0 sm 2 mul rl cp d0} def\n"); if(m_d) mgl_printf(fp, gz, "/m_d {sm 0 rm ss ss rl ss sm rl sm sm rl cp d0} def\n"); if(m_v) mgl_printf(fp, gz, "/m_v {sm ss 2 div rm s2 0 rl sm sm 1.5 mul rl d0 cp} def\n"); if(m_t) mgl_printf(fp, gz, "/m_t {sm sm 2 div rm s2 0 rl sm ss 1.5 mul rl d0 cp} def\n"); if(m_a) mgl_printf(fp, gz, "/m_a {sm 0 rm s2 0 rl sm 1.6 mul sm 0.8 mul rm ss 1.2 mul ss 1.6 mul rl 0 sm 1.6 mul rm sm 1.2 mul ss 1.6 mul rl d0} def\n"); if(m_o) mgl_printf(fp, gz, "/m_o {ss 0 360 d0 arc} def\n"); if(m_S) mgl_printf(fp, gz, "/m_S {sm sm rm 0 s2 rl s2 0 rl 0 sm 2 mul rl cp} def\n"); if(m_D) mgl_printf(fp, gz, "/m_D {sm 0 rm ss ss rl ss sm rl sm sm rl cp} def\n"); if(m_V) mgl_printf(fp, gz, "/m_V {sm ss 2 div rm s2 0 rl sm sm 1.5 mul rl cp} def\n"); if(m_T) mgl_printf(fp, gz, "/m_T {sm sm 2 div rm s2 0 rl sm ss 1.5 mul rl cp} def\n"); if(m_Y) mgl_printf(fp, gz, "/m_Y {0 sm rm 0 ss rl sm ss rl s2 0 rm sm sm rl d0} def\n"); if(m_r) mgl_printf(fp, gz, "/m_r {sm 2 div sm rm 0 s2 rl ss 1.5 mul sm rl d0 cp} def\n"); if(m_l) mgl_printf(fp, gz, "/m_l {ss 2 div sm rm 0 s2 rl sm 1.5 mul sm rl d0 cp} def\n"); if(m_R) mgl_printf(fp, gz, "/m_R {sm 2 div sm rm 0 s2 rl ss 1.5 mul sm rl cp} def\n"); if(m_L) mgl_printf(fp, gz, "/m_L {ss 2 div sm rm 0 s2 rl sm 1.5 mul sm rl cp} def\n"); if(m_P) mgl_printf(fp, gz, "/m_P {m_p 0 sm rm m_s} def\n"); if(m_X) mgl_printf(fp, gz, "/m_X {m_x ss sm rm m_s} def\n"); // if(m_C) mgl_printf(fp, gz, "/m_C {m_c m_o} def\n"); mgl_printf(fp, gz, "0 setlinecap\n1 setlinejoin\n\n"); // manual setting round line cap // Write background image first const unsigned char *img = mgl_get_background(gr); bool same = true; unsigned char white[3]={255,255,255}; #pragma omp parallel for for(long i=0;i=y1;j--) for(long i=x1;i0) mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "%02x%02x%02x",img[4*(i+w*j)],img[4*(i+w*j)+1],img[4*(i+w*j)+2]); } mgl_printf(fp, gz, "\n>} false 3 colorimage\ngrestore\n\n"); } else if(memcmp(img,white,3)) mgl_printf(fp, gz, "np 0 0 mt 0 %d ll %d %d ll %d 0 ll cp %g %g %g rgb fill\n", y2-y1, x2-x1, y2-y1, x2-x1, img[0]/255., img[1]/255., img[2]/255.); // write definition for all glyphs put_desc(gr,fp,gz,"/%c%c_%04x { np\n", "\t%d %d mt ", "%d %d ll ", "cp\n", "} def\n"); // write primitives mreal wp=-1; float qs_old=gr->mark_size()/gr->FontFactor(); mglRGBA cp; int st=0; char str[256]="", msk[256]=""; for(long i=0;iGetPrmNum();i++) { const mglPrim &q = gr->GetPrm(i); if(q.type<0) continue; // q.n1>=0 always cp.c = _Gr_->GetPrmCol(i); const mglPnt p1 = gr->GetPnt(q.n1); if(q.type>1) { snprintf(str,256,"%.2g %.2g %.2g rgb ", cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.); str[255]=0; snprintf(msk,256,"%.2g %.2g %.2g mask ", cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.); msk[255]=0; } if(q.type==0) // mark { mreal x0 = p1.x,y0 = p1.y; // snprintf(str,256,"%.2g lw %.2g %.2g %.2g rgb ", 50*q.s*q.w>1?50*q.s*q.w:1, cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.); snprintf(str,256,"%.2g lw %.2g %.2g %.2g rgb ", q.w>1?q.w:1, cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.); str[255]=0; wp=1; // NOTE: this may renew line style if a mark inside! if(q.s!=qs_old) { mgl_printf(fp, gz, "/ss {%g} def\n",q.s); mgl_printf(fp, gz, "/s2 {%g} def\n",q.s*2); mgl_printf(fp, gz, "/sm {-%g} def\n",q.s); qs_old = q.s; } switch(q.n4) { case '+': mgl_printf(fp, gz, "np %g %g mt m_p %sdr\n",x0,y0,str); break; case 'x': mgl_printf(fp, gz, "np %g %g mt m_x %sdr\n",x0,y0,str); break; case 's': mgl_printf(fp, gz, "np %g %g mt m_s %sdr\n",x0,y0,str); break; case 'd': mgl_printf(fp, gz, "np %g %g mt m_d %sdr\n",x0,y0,str); break; case '*': mgl_printf(fp, gz, "np %g %g mt m_a %sdr\n",x0,y0,str); break; case 'v': mgl_printf(fp, gz, "np %g %g mt m_v %sdr\n",x0,y0,str); break; case '^': mgl_printf(fp, gz, "np %g %g mt m_t %sdr\n",x0,y0,str); break; case 'S': mgl_printf(fp, gz, "np %g %g mt m_S %sfill\n",x0,y0,str); break; case 'D': mgl_printf(fp, gz, "np %g %g mt m_D %sfill\n",x0,y0,str); break; case 'V': mgl_printf(fp, gz, "np %g %g mt m_V %sfill\n",x0,y0,str); break; case 'T': mgl_printf(fp, gz, "np %g %g mt m_T %sfill\n",x0,y0,str); break; case 'o': mgl_printf(fp, gz, "%g %g m_o %sdr\n",x0,y0,str);break; case 'O': mgl_printf(fp, gz, "%g %g m_o %sfill\n",x0,y0,str);break; case 'Y': mgl_printf(fp, gz, "np %g %g mt m_Y %sdr\n",x0,y0,str); break; case '<': mgl_printf(fp, gz, "np %g %g mt m_l %sdr\n",x0,y0,str); break; case '>': mgl_printf(fp, gz, "np %g %g mt m_r %sdr\n",x0,y0,str); break; case 'L': mgl_printf(fp, gz, "np %g %g mt m_L %sfill\n",x0,y0,str); break; case 'R': mgl_printf(fp, gz, "np %g %g mt m_R %sfill\n",x0,y0,str); break; case 'P': mgl_printf(fp, gz, "np %g %g mt m_P %sdr\n",x0,y0,str); break; case 'X': mgl_printf(fp, gz, "np %g %g mt m_X %sdr\n",x0,y0,str); break; case 'C': mgl_printf(fp, gz, "%g %g m_o %g %g m_c %sdr\n",x0,y0,x0,y0,str); break; case '.': mgl_printf(fp, gz, "%g %g m_c %sfill\n",x0,y0,str); } } else if(q.type==3) // quad { const mglPnt &p2=gr->GetPnt(q.n2), &p3=gr->GetPnt(q.n3), &p4=gr->GetPnt(q.n4); if(cp.r[3]) // TODO && gr->quad_vis(p1,p2,p3,p4)) { bool mask = mgl_eps_pattern(fp,gz,q); mgl_printf(fp, gz, "np %g %g mt %g %g ll %g %g ll %g %g ll cp %sfill\n", p1.x, p1.y, p2.x, p2.y, p4.x, p4.y, p3.x, p3.y, mask?msk:str); } } else if(q.type==2) // trig { const mglPnt &p2=gr->GetPnt(q.n2), &p3=gr->GetPnt(q.n3); if(cp.r[3]) // TODO && gr->trig_vis(p1,p2,p3)) { bool mask = mgl_eps_pattern(fp,gz,q); mgl_printf(fp, gz, "np %g %g mt %g %g ll %g %g ll cp %sfill\n", p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, mask?msk:str); } } else if(q.type==1) // line { snprintf(str,256,"%.2g lw %.2g %.2g %.2g rgb ", q.w>1 ? q.w:1., cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.); str[255]=0; wp = q.w>1 ? q.w:1; st = q.n3; std::vector ids = put_line(gr,i,wp,cp.c,st); for(size_t j=0;jGetPnt(ids[j]); float x0 = p.x, y0 = p.y; mgl_printf(fp, gz, j==0?"np %g %g mt ":"%g %g ll ",x0,y0); } const char *sd = mgl_get_dash(q.n3,q.w,' '); if(sd && sd[0]) mgl_printf(fp, gz, "%s [%s] %g sd dr\n",str,sd,q.w*q.s); else mgl_printf(fp, gz, "%s d0 dr\n",str); } else if(q.type==4) // glyph { float phi = gr->GetGlyphPhi(gr->GetPnt(q.n2),q.w); if(mgl_isnan(phi)) continue; mreal ss = q.s/2, xx = p1.u, yy = p1.v, zz = q.p; mgl_printf(fp, gz, "gsave\t%g %g translate %g %g scale %g rotate %s\n", p1.x, p1.y, ss, ss, -phi, str); if(q.n3&8) // this is "line" { mreal dy = 0.004,f=fabs(zz); mgl_printf(fp, gz, "np %g %g mt %g %g ll %g %g ll %g %g ll cp ", xx,yy+dy, xx+f,yy+dy, xx+f,yy-dy, xx,yy-dy); } else mgl_printf(fp, gz, "%.3g %.3g translate %g %g scale %c%c_%04x ", xx, yy, zz, zz, q.n3&1?'b':'n', q.n3&2?'i':'n', q.n4); if(q.n3&4) mgl_printf(fp, gz, "dr"); else mgl_printf(fp, gz, "eofill"); mgl_printf(fp, gz, " grestore\n"); } } for(long i=0;iGetPrmNum();i++) { mglPrim &q = gr->GetPrm(i); if(q.type==-1) q.type = 1; } mgl_printf(fp, gz, "\nshowpage\n%%%%EOF\n"); if(strcmp(fname,"-")) { if(gz) gzclose((gzFile)fp); else fclose((FILE *)fp); } setlocale(LC_NUMERIC, loc.c_str()); } void MGL_EXPORT mgl_write_eps_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_eps(_GR_,s,d); delete []s; delete []d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr) { if(!fname || *fname==0) return; if(gr->GetPrmNum()<1) return; _Gr_->clr(MGL_FINISHED); _Gr_->PreparePrim(1); time_t now; time(&now); bool gz = fname[strlen(fname)-1]=='z'; long hh = _Gr_->GetHeight(), ww = _Gr_->GetWidth(); void *fp = stdout; // allow to write in stdout bool head = true; if(strcmp(fname,"-")) fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt"); else head = false; if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } int x1=gr->BBoxX1, x2=gr->BBoxX2<0?ww:gr->BBoxX2, y1=gr->BBoxY1, y2=gr->BBoxY2<0?hh:gr->BBoxY2; if(x1<0 || x1>=x2 || y1<0 || y1>=y2) { x1=y1=0; x2=ww; y2=hh; } ww = x2-x1; hh = y2-y1; const std::string loc = setlocale(LC_NUMERIC, "C"); if(head) { mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n", ww, hh); mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n\n\n",descr?descr:fname,ctime(&now)); } else { mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "\n", ww, hh); } // write definition for all glyphs put_desc(gr,fp,gz,"\n"); // Write background image first const unsigned char *img = mgl_get_background(gr); bool same = true; unsigned char white[3]={255,255,255}; #pragma omp parallel for for(long i=0;i /* mgl_printf(fp, gz, "%d %d 8 [1 0 0 1 0 0] {<", ww,hh,1+ww*hh/40); for(long j=hh-1;j>=0;j--) for(long i=0;i0) mgl_printf(fp, gz, "\n"); mgl_printf(fp, gz, "%02x%02x%02x",img[4*(i+ww*j)],img[4*(i+ww*j)+1],img[4*(i+ww*j)+2]); } mgl_printf(fp, gz, "\n>} false 3 colorimage\n\n");*/ } else if(memcmp(img,white,3)) { mgl_printf(fp, gz, "\n", img[0], img[1], img[2], img[3]/255.); mgl_printf(fp, gz, " \n", hh, ww, hh, ww); } // currentColor -> inherit ??? mgl_printf(fp, gz, "\n"); // write primitives mreal wp=-1; int st=0; mglRGBA cp; // hh += (y2+y1)/2; for(long i=0;iGetPrmNum();i++) { const mglPrim &q = gr->GetPrm(i); if(q.type<0) continue; // q.n1>=0 always cp.c = _Gr_->GetPrmCol(i); const mglPnt p1=gr->GetPnt(q.n1); if(q.type==0) { mreal x=p1.x-x1,y=hh-p1.y,s=q.s; if(!strchr("xsSoO",q.n4)) s *= 1.1; wp = 1; if(strchr("SDVTLR",q.n4)) mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2])); else mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]), q.w>1?q.w:1); // mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]), 50*q.s*q.w>1?50*q.s*q.w:1); switch(q.n4) { case 'P': mgl_printf(fp, gz, "\n", x-s,y,x+s,y,x,y-s,x,y+s, x-s,y-s,x+s,y-s,x+s,y+s,x-s,y+s,x-s,y-s); break; case '+': mgl_printf(fp, gz, "\n", x-s,y,x+s,y,x,y-s,x,y+s); break; case 'X': mgl_printf(fp, gz, "\n", x-s,y-s,x+s,y+s,x+s,y-s,x-s,y+s, x-s,y-s,x+s,y-s,x+s,y+s,x-s,y+s,x-s,y-s); break; case 'x': mgl_printf(fp, gz, "\n", x-s,y-s,x+s,y+s,x+s,y-s,x-s,y+s); break; case 's': case 'S': mgl_printf(fp, gz, "\n", x-s,y-s,x+s,y-s,x+s,y+s,x-s,y+s); break; case 'd': case 'D': mgl_printf(fp, gz, "\n", x-s,y,x,y-s,x+s,y,x,y+s); break; case 'v': case 'V': mgl_printf(fp, gz, "\n", x-s,y-s/2,x+s,y-s/2,x,y+s); break; case '^': case 'T': mgl_printf(fp, gz, "\n", x-s,y+s/2,x+s,y+s/2,x,y-s); break; case '<': case 'L': mgl_printf(fp, gz, "\n", x+s/2,y+s,x+s/2,y-s,x-s,y); break; case '>': case 'R': mgl_printf(fp, gz, "\n", x-s/2,y+s,x-s/2,y-s,x+s,y); break; case 'Y': mgl_printf(fp, gz, "\n", x,y-s, x,y, x+s,y+s, x,y, x-s,y+s); break; case 'C': mgl_printf(fp, gz, "\n\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]),x,y,x,y,s); break; case 'o': mgl_printf(fp, gz, "\n", x,y,s); break; case 'O': mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]),x,y,s); break; case '*': mgl_printf(fp, gz, "\n", x-s,y,x+s,y,x-0.6*s,y-0.8*s,x+0.6*s,y+0.8*s,x+0.6*s,y-0.8*s,x-0.6*s,y+0.8*s); break; case '.': mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]),x,y); break; } mgl_printf(fp, gz, "\n"); } else if(q.type==1) { mgl_printf(fp,gz,"1) mgl_printf(fp, gz, " stroke-width=\"%g\"", q.w); wp = q.w>1 ? q.w:1; st = q.n3; std::vector ids = put_line(gr,i,wp,cp.c,st); for(size_t j=0;jGetPnt(ids[j]); mgl_printf(fp, gz, j==0?"> \n"); } else if(q.type==2 && cp.r[3]) { const mglPnt &p2=gr->GetPnt(q.n2), &p3=gr->GetPnt(q.n3); mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]),cp.r[3]/255.); mgl_printf(fp, gz, " \n", p1.x-x1, hh-p1.y, p2.x-x1, hh-p2.y, p3.x-x1, hh-p3.y); } else if(q.type==3 && cp.r[3]) { const mglPnt &p2=gr->GetPnt(q.n2), &p3=gr->GetPnt(q.n3), &p4=gr->GetPnt(q.n4); mgl_printf(fp, gz, "\n", int(cp.r[0]),int(cp.r[1]),int(cp.r[2]),cp.r[3]/255.); mgl_printf(fp, gz, " \n", p1.x-x1, hh-p1.y, p2.x-x1, hh-p2.y, p4.x-x1, hh-p4.y, p3.x-x1, hh-p3.y); } else if(q.type==4) { float phi = gr->GetGlyphPhi(gr->GetPnt(q.n2),q.w); if(mgl_isnan(phi)) continue; mreal ss = q.s/2, xx = p1.u, yy = p1.v, zz = q.p; if(q.n3&8) // this is "line" { mgl_printf(fp, gz, "", int(cp.r[0]),int(cp.r[1]),int(cp.r[2])); else mgl_printf(fp, gz, " fill=\"#%02x%02x%02x\">", int(cp.r[0]),int(cp.r[1]),int(cp.r[2])); mreal dy = 0.004,f=fabs(zz); mgl_printf(fp, gz, "\n", xx,yy+dy, xx+f,yy+dy, xx+f,yy-dy, xx,yy-dy); } else { ss *= zz; mgl_printf(fp, gz, "", int(cp.r[0]),int(cp.r[1]),int(cp.r[2])); else mgl_printf(fp, gz, " fill=\"#%02x%02x%02x\">", int(cp.r[0]),int(cp.r[1]),int(cp.r[2])); mgl_printf(fp, gz, "\n", xx/zz, yy/zz, q.n3&1?'b':'n', q.n3&2?'i':'n', q.n4); } } } for(long i=0;iGetPrmNum();i++) { mglPrim &q=gr->GetPrm(i); if(q.type==-1) q.type = 1; } mgl_printf(fp, gz, ""); if(strcmp(fname,"-")) { if(gz) gzclose((gzFile)fp); else fclose((FILE *)fp); } setlocale(LC_NUMERIC, loc.c_str()); } void MGL_EXPORT mgl_write_svg_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_svg(_GR_,s,d); delete []s; delete []d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_tex(HMGL gr, const char *fname,const char *descr) { if(gr->GetPrmNum()<1) return; _Gr_->clr(MGL_FINISHED); _Gr_->PreparePrim(1); FILE *fp = fopen(fname,"w"); if(!fp) { gr->SetWarn(mglWarnOpen,fname); return; } const std::string loc = setlocale(LC_NUMERIC, "C"); fwide(fp,1); fwprintf(fp, L"%% Created by MathGL library\n%% Title: %s\n\n",descr?descr:fname); // provide marks fwprintf(fp, L"\\providecommand{\\mglp}[4]{\\draw[#3] (#1-#4, #2) -- (#1+#4,#2) (#1,#2-#4) -- (#1,#2+#4);}\n"); fwprintf(fp, L"\\providecommand{\\mglx}[4]{\\draw[#3] (#1-#4, #2-#4) -- (#1+#4,#2+#4) (#1+#4,#2-#4) -- (#1-#4,#2+#4);}\n"); fwprintf(fp, L"\\providecommand{\\mgls}[4]{\\draw[#3] (#1-#4, #2-#4) -- (#1+#4,#2-#4) -- (#1+#4,#2+#4) -- (#1-#4,#2+#4) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglS}[4]{\\fill[#3] (#1-#4, #2-#4) -- (#1+#4,#2-#4) -- (#1+#4,#2+#4) -- (#1-#4,#2+#4) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mgld}[4]{\\draw[#3] (#1, #2-#4) -- (#1+#4,#2) -- (#1,#2+#4) -- (#1-#4,#2) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglD}[4]{\\fill[#3] (#1, #2-#4) -- (#1+#4,#2) -- (#1,#2+#4) -- (#1-#4,#2) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglv}[4]{\\draw[#3] (#1-#4, #2+#4/2) -- (#1+#4,#2+#4/2) -- (#1,#2-#4) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglV}[4]{\\fill[#3] (#1-#4, #2+#4/2) -- (#1+#4,#2+#4/2) -- (#1,#2-#4) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglt}[4]{\\draw[#3] (#1-#4, #2-#4/2) -- (#1+#4,#2-#4/2) -- (#1,#2+#4) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglT}[4]{\\fill[#3] (#1-#4, #2-#4/2) -- (#1+#4,#2-#4/2) -- (#1,#2+#4) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mgll}[4]{\\draw[#3] (#1+#4/2, #2-#4) -- (#1+#4/2,#2+#4) -- (#1-#4,#2) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglL}[4]{\\fill[#3] (#1+#4/2, #2-#4) -- (#1+#4/2,#2+#4) -- (#1-#4,#2) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglr}[4]{\\draw[#3] (#1-#4/2, #2-#4) -- (#1-#4/2,#2+#4) -- (#1+#4,#2) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglR}[4]{\\fill[#3] (#1-#4/2, #2-#4) -- (#1-#4/2,#2+#4) -- (#1+#4,#2) -- cycle;}\n"); fwprintf(fp, L"\\providecommand{\\mglR}[4]{\\draw[#3] (#1, #2-#4) -- (#1,#2) -- (#1-#4,#2+#4) (#1,#2) -- (#1+#4,#2+#4);}\n"); fwprintf(fp, L"\\providecommand{\\mgla}[4]{\\draw[#3] (#1-#4, #2) -- (#1+#4,#2) (#1-0.6*#4,#2-0.8*#4) -- (#1+0.6*#4,#2+0.8*#4) (#1-0.6*#4,#2+0.8*#4) -- (#1+0.6*#4,#2-0.8*#4);}\n"); fwprintf(fp, L"\\providecommand{\\mglY}[4]{\\draw[#3] (#1, #2-#4) -- (#1,#2) (#1-#4,#2+#4) -- (#1,#2) (#1+#4,#2+#4) -- (#1,#2);}\n"); fwprintf(fp, L"\\providecommand{\\mglo}[4]{\\draw[#3] (#1, #2) circle (#4);}\n"); fwprintf(fp, L"\\providecommand{\\mglO}[4]{\\fill[#3] (#1, #2) circle (#4);}\n"); fwprintf(fp, L"\\providecommand{\\mglc}[3]{\\draw[#3] (#1, #2) circle (%g);}\n\n", 4e-4*gr->mark_size()); fwprintf(fp, L"\\begin{tikzpicture}\n"); // write primitives first mreal wp=-1; int st=0; mglRGBA cp; char cname[128]; for(long i=0;iGetPrmNum();i++) { const mglPrim &q = gr->GetPrm(i); if(q.type<0) continue; // q.n1>=0 always cp.c = _Gr_->GetPrmCol(i); snprintf(cname,128,"color={rgb,255:red,%d;green,%d;blue,%d}",cp.r[0],cp.r[1],cp.r[2]); cname[127]=0; const mglPnt p1=gr->GetPnt(q.n1); mreal x=p1.x/100,y=p1.y/100,s=q.s/100; if(q.type==0) { if(!strchr("xsSoO",q.n4)) s *= 1.1; wp = 1; switch(q.n4) // NOTE: no thickness for marks in TeX { case 'P': fwprintf(fp, L"\\mglp{%.4g}{%.4g}{%s}{%.4g} \\mgls{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s,x,y,cname,s); break; case 'X': fwprintf(fp, L"\\mglx{%.4g}{%.4g}{%s}{%.4g} \\mgls{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s,x,y,cname,s); break; case 'C': fwprintf(fp, L"\\mglc{%.4g}{%.4g}{%s}{%.4g} \\mglo{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s,x,y,cname,s); break; case '+': fwprintf(fp, L"\\mglp{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'x': fwprintf(fp, L"\\mglx{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 's': fwprintf(fp, L"\\mgls{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'S': fwprintf(fp, L"\\mglS{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'd': fwprintf(fp, L"\\mgld{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'D': fwprintf(fp, L"\\mglD{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case '^': fwprintf(fp, L"\\mglt{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'T': fwprintf(fp, L"\\mglT{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'v': fwprintf(fp, L"\\mglv{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'V': fwprintf(fp, L"\\mglV{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case '<': fwprintf(fp, L"\\mgll{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'L': fwprintf(fp, L"\\mglL{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case '>': fwprintf(fp, L"\\mglr{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'R': fwprintf(fp, L"\\mglR{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'Y': fwprintf(fp, L"\\mglY{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'o': fwprintf(fp, L"\\mglo{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case 'O': fwprintf(fp, L"\\mglO{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; case '*': fwprintf(fp, L"\\mgla{%.4g}{%.4g}{%s}{%.4g}\n", x,y,cname,s); break; default: fwprintf(fp, L"\\mglc{%.4g}{%.4g}{%s}\n", x,y,cname); break; } } else if(q.type==2 && cp.r[3]) { const mglPnt p2=gr->GetPnt(q.n2), p3=gr->GetPnt(q.n3); if(cp.r[3]<255) fwprintf(fp, L"\\fill[%s, fill opacity=%.4g] (%.4g,%.4g) -- (%.4g,%.4g) -- (%.4g,%.4g) -- cycle;\n", cname,cp.r[3]/255., x,y, p2.x/100,p2.y/100, p3.x/100,p3.y/100); else fwprintf(fp, L"\\fill[%s, fill] (%.4g,%.4g) -- (%.4g,%.4g) -- (%.4g,%.4g) -- cycle;\n", cname, x,y, p2.x/100,p2.y/100, p3.x/100,p3.y/100); } else if(q.type==3 && cp.r[3]) { const mglPnt p2=gr->GetPnt(q.n2), p3=gr->GetPnt(q.n3), p4=gr->GetPnt(q.n4); if(cp.r[3]<255) fwprintf(fp, L"\\fill[%s, fill opacity=%.4g] (%.4g,%.4g) -- (%.4g,%.4g) -- (%.4g,%.4g) -- (%.4g,%.4g) -- cycle;\n", cname,cp.r[3]/255., x,y, p2.x/100,p2.y/100, p4.x/100,p4.y/100, p3.x/100,p3.y/100); else fwprintf(fp, L"\\fill[%s, fill] (%.4g,%.4g) -- (%.4g,%.4g) -- (%.4g,%.4g) -- (%.4g,%.4g) -- cycle;\n", cname, x,y, p2.x/100,p2.y/100, p4.x/100,p4.y/100, p3.x/100,p3.y/100); } else if(q.type==1) // lines { //const char *dash[]={"", "8 8","4 4","1 3","7 4 1 4","3 2 1 2"}; const char *w[]={"semithick","thick","very thick","ultra thick"}; int iw=int(q.w-0.5); if(iw>3) iw=3; if(iw<0) fwprintf(fp,L"\\draw[%s] ",cname); else fwprintf(fp,L"\\draw[%s,%s] ",cname,w[iw]); // TODO: add line dashing wp = q.w>1 ? q.w:1; st = q.n3; std::vector ids = put_line(gr,i,wp,cp.c,st); for(size_t j=0;jGetPnt(ids[j]); float x0 = p.x, y0 = p.y; fwprintf(fp, j==0?L"(%.4g,%.4g)":L" -- (%.4g,%.4g)",0.01*x0,y0*0.01); } fwprintf(fp, L";\n"); } else if(q.type==6 && mgl_isnum(q.p)) // text { const mglText &t = gr->GetPtx(q.n3); mreal dy = q.w*cos(q.p*M_PI/180)/100, dx = q.w*sin(q.p*M_PI/180)/100; int f,a; mglGetStyle(t.stl.c_str(), &f, &a); std::string ss=cname; if((a&3)==0) ss.append(",anchor=base west"); if((a&3)==1) ss.append(",anchor=base"); if((a&3)==2) ss.append(",anchor=base east"); // if(f&MGL_FONT_ITAL) ss.append(",font=\\itshape"); // if(f&MGL_FONT_BOLD) ss.append(",font=\\bfshape"); if(t.text.find('\\')!=std::string::npos || t.text.find('{')!=std::string::npos || t.text.find('_')!=std::string::npos || t.text.find('^')!=std::string::npos) fwprintf(fp,L"\\draw[%s] (%.4g,%.4g) node[rotate=%.2g]{$%ls$};\n", ss.c_str(),x-dx,y-dy, -q.p, t.text.c_str()); else fwprintf(fp,L"\\draw[%s] (%.4g,%.4g) node[rotate=%.2g]{%ls};\n", ss.c_str(),x-dx,y-dy, -q.p, t.text.c_str()); } } fwprintf(fp, L"\\end{tikzpicture}\n"); for(long i=0;iGetPrmNum();i++) { mglPrim &q=gr->GetPrm(i); if(q.type==-1) q.type = 1; } fclose(fp); setlocale(LC_NUMERIC, loc.c_str()); // provide main file for viewing figure fp=fopen("mglmain.tex","wt"); if(fp) { fprintf(fp, "%% this file just show figure\n"); fprintf(fp, "\\documentclass{article}\n\\usepackage{tikz}\n"); fprintf(fp, "\\usepackage[T2A]{fontenc}\n\\usepackage[utf8]{inputenc}\n"); fprintf(fp, "\\begin{document}\n\\input{%s}\n\\end{document}\n",fname); fclose(fp); } } void MGL_EXPORT mgl_write_tex_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *d=new char[n+1]; memcpy(d,descr,n); d[n]=0; mgl_write_tex(_GR_,s,d); delete []s; delete []d; } //----------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/complex_ex.cpp���������������������������������������������������������������������0000644�0001750�0001750�00000063370�13513030041�016614� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * data_new.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/datac.h" #include "mgl2/evalc.h" #include "mgl2/thread.h" #include "interp.hpp" void MGL_NO_EXPORT mgl_txt_funcC(const mreal *x, mreal *dx, void *par); HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector &head); //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_trace(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); const mglDataC *dc = dynamic_cast(d); mglDataC *r=new mglDataC(nx); if(dc) { if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;ia[i] = dc->a[i+nx*(i+ny*i)]; else if(ny>=nx) #pragma omp parallel for for(long i=0;ia[i] = dc->a[i+nx*i]; else #pragma omp parallel for for(long i=0;ia[i] = dc->a[i]; } else if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;ia[i] = d->v(i,i,i); else if(ny>=nx) #pragma omp parallel for for(long i=0;ia[i] = d->v(i,i); else #pragma omp parallel for for(long i=0;ia[i] = d->v(i); return r; } uintptr_t MGL_EXPORT mgl_datac_trace_(uintptr_t *d) { return uintptr_t(mgl_datac_trace(_DC_)); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz) { if(!xx || !yy || !zz) { mglData tmp; tmp.a[0]=-1; return mgl_datac_subdata_ext(d,xx?xx:&tmp,yy?yy:&tmp,zz?zz:&tmp); } long n=0,m=0,l=0,j,k; bool ix=false, iy=false, iz=false; if(xx->GetNz()>1) // 3d data { n = xx->GetNx(); m = xx->GetNy(); l = xx->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNz()>1) { n = yy->GetNx(); m = yy->GetNy(); l = yy->GetNz(); j = xx->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNz()>1) { n = zz->GetNx(); m = zz->GetNy(); l = zz->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = xx->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } else if(xx->GetNy()>1) // 2d data { n = xx->GetNx(); m = xx->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNy()>1) { n = yy->GetNx(); m = yy->GetNy(); l = 1; j = xx->GetNx()*xx->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNy()>1) { n = zz->GetNx(); m = zz->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = xx->GetNx()*xx->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); long vx=long(xx->v(0)), vy=long(yy->v(0)), vz=long(zz->v(0)); const mglDataC *dd = dynamic_cast(d); mglDataC *r; if(n*m*l>1) // this is 2d or 3d data { mglDataV tx(n,m,l),ty(n,m,l),tz(n,m,l); if(!ix) { xx = &tx; if(vx>=0) tx.Fill(vx); else tx.All(); } if(!iy) { yy = &ty; if(vy>=0) ty.Fill(vy); else ty.All(); } if(!iz) { zz = &tz; if(vz>=0) tz.Fill(vz); else tz.All(); } r=new mglDataC(n,m,l); if(dd) #pragma omp parallel for for(long i0=0;i0vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x=0 && y=0 && za[x+nx*(y+ny*z)]:NAN; } else #pragma omp parallel for for(long i0=0;i0vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x=0 && y=0 && zv(x,y,z):NAN; } } else // this is 1d data -> try as normal SubData() { mglDataV tx(nx),ty(ny),tz(nz); tx.Fill(0,nx-1); ty.Fill(0,ny-1); tz.Fill(0,nz-1); if(xx->GetNx()>1 || vx>=0) n=xx->GetNx(); else { n=nx; xx = &tx; } if(yy->GetNx()>1 || vy>=0) m=yy->GetNx(); else { m=ny; yy = &ty; } if(zz->GetNx()>1 || vz>=0) l=zz->GetNx(); else { l=nz; zz = &tz; } r=new mglDataC(n,m,l); if(dd) #pragma omp parallel for collapse(3) for(long k=0;kv(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x=0 && y=0 && za[x+nx*(y+ny*z)]:NAN; } else #pragma omp parallel for collapse(3) for(long k=0;kv(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x=0 && y=0 && zv(x,y,z):NAN; } if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} } return r; } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata(HCDT d, long xx,long yy,long zz) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1; int dx=0,dy=0,dz=0; if(xx<0) { xx=0; dx=1; n=nx; } if(yy<0) { yy=0; dy=1; m=ny; } if(zz<0) { zz=0; dz=1; l=nz; } const mglDataC *dd = dynamic_cast(d); mglDataC *r=new mglDataC(n,m,l); if(xx>=nx || yy>=ny || zz>=nz) #pragma omp parallel for for(long i=0;ia[i] = NAN; else if(dd) #pragma omp parallel for collapse(3) for(long k=0;ka[i+n*(j+m*k)] = dd->a[xx+dx*i + nx*(yy+dy*j + ny*(zz+dz*k))]; else #pragma omp parallel for collapse(3) for(long k=0;ka[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k); if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_datac_subdata_(uintptr_t *d, int *xx,int *yy,int *zz) { return uintptr_t(mgl_datac_subdata(_DC_,*xx,*yy,*zz)); } uintptr_t MGL_EXPORT mgl_datac_subdata_ext_(uintptr_t *d, uintptr_t *xx, uintptr_t *yy, uintptr_t *zz) { return uintptr_t(mgl_datac_subdata_ext(_DC_,_DA_(xx),_DA_(yy),_DA_(zz))); } //----------------------------------------------------------------------------- static void *mgl_cresize(void *par) { mglThreadC *t=(mglThreadC *)par; long nx=t->p[0]+0.1, ny=t->p[1]+0.1; long n1=t->p[3]+0.1,n2=t->p[4]+0.1,n3=t->p[5]+0.1; dual *b=t->a; const dual *a=t->b; const mreal *c=(const mreal *)t->v; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { mreal i=(i0%nx), j=((i0/nx)%ny), k=(i0/(nx*ny)); b[i0] = mglSpline3Cs(a,n1,n2,n3, c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]); } return 0; } HADT MGL_EXPORT mgl_datac_resize_box(HCDT dat, long mx,long my,long mz, mreal x1,mreal x2, mreal y1,mreal y2, mreal z1,mreal z2) { // NOTE: only for mglDataC const mglDataC *d=dynamic_cast(dat); if(!d) return 0; long nx = d->nx-1, ny = d->ny-1, nz = d->nz-1; mx = mx<1 ? nx+1:mx; my = my<1 ? ny+1:my; mz = mz<1 ? nz+1:mz; mglDataC *r=new mglDataC(mx,my,mz); mreal par[6]={nx*x1,0,ny*y1,0,nz*z1,0}; long nn[6]={mx,my,mz,nx+1,ny+1,nz+1}; if(mx>1) par[1] = nx*(x2-x1)/(mx-1); if(my>1) par[3] = ny*(y2-y1)/(my-1); if(mz>1) par[5] = nz*(z2-z1)/(mz-1); mglStartThreadC(mgl_cresize,0,mx*my*mz,r->a,d->a,0,nn,par); return r; } HADT MGL_EXPORT mgl_datac_resize(HCDT d, long mx,long my,long mz) { return mgl_datac_resize_box(d, mx,my,mz,0,1,0,1,0,1); } uintptr_t MGL_EXPORT mgl_datac_resize_(uintptr_t *d, int *mx,int *my,int *mz) { return uintptr_t(mgl_datac_resize(_DC_,*mx,*my,*mz)); } uintptr_t MGL_EXPORT mgl_datac_resize_box_(uintptr_t *d, int *mx,int *my,int *mz, mreal *x1,mreal *x2, mreal *y1,mreal *y2, mreal *z1,mreal *z2) { return uintptr_t(mgl_datac_resize_box(_DC_,*mx,*my,*mz,*x1,*x2,*y1,*y2,*z1,*z2)); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_combine(HCDT d1, HCDT d2) { long n1=d1->GetNy(),n2=d2->GetNx(),nx=d1->GetNx(); if(d1->GetNz()>1 || (n1>1 && d2->GetNy()>1) || d2->GetNz()>1) return 0; // wrong dimensions mglDataC *r=new mglDataC; bool dim2=true; if(n1==1) { n1=n2; n2=d2->GetNy(); dim2 = false; } r->Create(nx,n1,n2); if(dim2) n1*=nx; else { n2*=n1; n1=nx; } const mglDataC *c1=dynamic_cast(d1); const mglDataC *c2=dynamic_cast(d2); if(c1 && c2) #pragma omp parallel for collapse(2) for(long j=0;ja[i+n1*j] = c1->a[i]*c2->a[j]; else if(c1) #pragma omp parallel for collapse(2) for(long j=0;ja[i+n1*j] = c1->a[i]*d2->vthr(j); else if(c2) #pragma omp parallel for collapse(2) for(long j=0;ja[i+n1*j] = d1->vthr(i)*c2->a[j]; else #pragma omp parallel for collapse(2) for(long j=0;ja[i+n1*j] = d1->vthr(i)*d2->vthr(j); return r; } uintptr_t MGL_EXPORT mgl_datac_combine_(uintptr_t *a, uintptr_t *b) { return uintptr_t(mgl_datac_combine(_DA_(a),_DA_(b))); } //----------------------------------------------------------------------------- static void *mgl_sumc_z(void *par) { mglThreadC *t=(mglThreadC *)par; long nz=t->p[2], nn=t->n; dual *b=t->a; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; dual *b=t->a; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; dual *b=t->a; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;iGetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; dual *b = new dual[nx*ny*nz]; dual *c = new dual[nx*ny*nz]; const mglDataC *d=dynamic_cast(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(dual)); else #pragma omp parallel for for(long i=0;ivthr(i); if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_sumc_z,0,nx*ny,b,c,0,p); memcpy(c,b,nx*ny*sizeof(dual)); p[2] = 1; } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_sumc_y,0,nx*p[2],b,c,0,p); memcpy(c,b,nx*p[2]*sizeof(dual)); p[1] = p[2]; p[2] = 1; } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_sumc_x,0,p[1]*p[2],b,c,0,p); p[0] = p[1]; p[1] = p[2]; p[2] = 1; memcpy(c,b,p[0]*p[1]*sizeof(dual)); } mglDataC *r=new mglDataC(p[0],p[1],p[2]); memcpy(r->a,c,p[0]*p[1]*p[2]*sizeof(dual)); delete []b; delete []c; return r; } uintptr_t MGL_EXPORT mgl_datac_sum_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; uintptr_t r=uintptr_t(mgl_datac_sum(_DC_,s)); delete []s; return r; } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how) { if(!how || !(*how) || !strchr("xyz",dir)) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); mglDataV x(nx,ny,nz, 0,1,'x'); x.Name(L"x"); mglDataV y(nx,ny,nz, 0,1,'y'); y.Name(L"y"); mglDataV z(nx,ny,nz, 0,1,'z'); z.Name(L"z"); mglDataC u(dat); u.Name(L"u"); // NOTE slow !!! std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&u); HADT res=mglFormulaCalcC(how,list), b=0; if(dir=='x') { b=new mglDataC(nx); #pragma omp parallel for for(long i=0;ivthr(i+nx*j); i0 += u; i1 += u*res->a[i+nx*j]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } if(dir=='y') { b=new mglDataC(ny); #pragma omp parallel for for(long i=0;iv(j,i,k); i0 += u; i1 += u*res->a[j+nx*(i+ny*k)]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } if(dir=='z') { long nn=nx*ny; b=new mglDataC(nz); #pragma omp parallel for for(long i=0;ivthr(j+nn*i); i0 += u; i1 += u*res->a[j+nn*i]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } mgl_delete_datac(res); return b; } uintptr_t MGL_EXPORT mgl_datac_momentum_(uintptr_t *d, char *dir, const char *how, int,int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; uintptr_t r=uintptr_t(mgl_datac_momentum(_DC_,*dir, s)); delete []s; return r; } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm) { if(!idat || (jdat && jdat->GetNN()!=idat->GetNN()) || (kdat && kdat->GetNN()!=idat->GetNN())) return 0; const mglData *dd=dynamic_cast(dat); const mglDataC *dc=dynamic_cast(dat); long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz(); mglDataC *r=new mglDataC(idat->GetNx(),idat->GetNy(),idat->GetNz()); mreal dx = nx-1, dy = ny-1, dz = nz-1; if(!norm) dx=dy=dz=1; if(dd) #pragma omp parallel for for(long i=0;iGetNN();i++) { mreal x=dx*idat->vthr(i), y=jdat?dy*jdat->vthr(i):0, z=kdat?dz*kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?mglSpline3st(dd->a,nx,ny,nz, x,y,z):NAN; } else if(dc) #pragma omp parallel for for(long i=0;iGetNN();i++) { mreal x=dx*idat->vthr(i), y=jdat?dy*jdat->vthr(i):0, z=kdat?dz*kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?mglSpline3st(dc->a,nx,ny,nz, x,y,z):NAN; } else #pragma omp parallel for for(long i=0;iGetNN();i++) { mreal x=dx*idat->vthr(i), y=jdat?dy*jdat->vthr(i):0, z=kdat?dz*kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?dat->linear(x,y,z):NAN;; } return r; } uintptr_t MGL_EXPORT mgl_datac_evaluate_(uintptr_t *d, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm) { return uintptr_t(mgl_datac_evaluate(_DC_,_DA_(idat),_DA_(jdat),_DA_(kdat),*norm)); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq) { std::vector list; const char *id = dat->GetColumnId(); size_t len = strlen(id); for(size_t i=0;iSetInd(i,id[i]); list.push_back(col); } if(list.size()==0) return 0; // no named columns mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz()); t->Name(L"#$mgl"); list.push_back(t); HADT r = mglFormulaCalcC(eq,list); for(size_t i=0;inx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); const mglDataC *c = dynamic_cast(a); if(mz*my*mx==1) { dual v=c?c->a[0]:a->v(0); #pragma omp parallel for for(long i=0;ia[i] += v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } if(c) #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] *= c->a[i]; else #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] *= a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_mul_num(HADT d, mdual a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] *= dual(a); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_div_dat(HADT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); const mglDataC *c = dynamic_cast(a); if(mz*my*mx==1) { dual v=c?c->a[0]:a->v(0); #pragma omp parallel for for(long i=0;ia[i] /= v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } if(c) #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] /= c->a[i]; else #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] /= a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_div_num(HADT d, mdual a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] /= dual(a); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_add_dat(HADT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); const mglDataC *c = dynamic_cast(a); if(mz*my*mx==1) { dual v=c?c->a[0]:a->v(0); #pragma omp parallel for for(long i=0;ia[i] += v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } if(c) #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] += c->a[i]; else #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] += a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_add_num(HADT d, mdual a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] += dual(a); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_sub_dat(HADT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); const mglDataC *c = dynamic_cast(a); if(mz*my*mx==1) { dual v=c?c->a[0]:a->v(0); #pragma omp parallel for for(long i=0;ia[i] -= v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } if(c) #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] -= c->a[i]; else #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] -= a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_sub_num(HADT d, mdual a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] -= dual(a); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_mul_dat_(uintptr_t *d, uintptr_t *b) { mgl_datac_mul_dat(_DC_, _DA_(b)); } void MGL_EXPORT mgl_datac_div_dat_(uintptr_t *d, uintptr_t *b) { mgl_datac_div_dat(_DC_, _DA_(b)); } void MGL_EXPORT mgl_datac_add_dat_(uintptr_t *d, uintptr_t *b) { mgl_datac_add_dat(_DC_, _DA_(b)); } void MGL_EXPORT mgl_datac_sub_dat_(uintptr_t *d, uintptr_t *b) { mgl_datac_sub_dat(_DC_, _DA_(b)); } void MGL_EXPORT mgl_datac_mul_num_(uintptr_t *d, mdual *b) { mgl_datac_mul_num(_DC_, *b); } void MGL_EXPORT mgl_datac_div_num_(uintptr_t *d, mdual *b) { mgl_datac_div_num(_DC_, *b); } void MGL_EXPORT mgl_datac_add_num_(uintptr_t *d, mdual *b) { mgl_datac_add_num(_DC_, *b); } void MGL_EXPORT mgl_datac_sub_num_(uintptr_t *d, mdual *b) { mgl_datac_sub_num(_DC_, *b); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_section(HCDT dat, HCDT ids, char dir, mreal val) { long di = 1, n = dat->GetNx(); if(dir=='y') { di = dat->GetNx(); n = dat->GetNy(); } if(dir=='z') { di = dat->GetNx()*dat->GetNy(); n = dat->GetNz(); } // first collect position of key values std::vector pos; pos.push_back(0); if(mgl_isnan(val)) for(long i=1;ivthr(i*di))) pos.push_back(i); } else for(long i=0;ivthr(i*di)==val) pos.push_back(i); } pos.push_back(n); // add last point (size of data) // now collect required position from section and its lengths std::vector ls, ps; long np = pos.size()-1, nl=0; if(np<1) return NULL; // nothing to do for(long i=0;iGetNN();i++) { long j = mgl_int(ids->vthr(i)+0.5); j = j<0?np+j:j; if(j>=0 && jGetNx(), nz=dat->GetNz(), sh=0; r = new mglDataC(nx,nl,nz); for(size_t s=0;sa[i+nx*(sh+j+nl*k)] = dat->vc(i,pp+j,k); sh += ls[s]; } } else if(dir=='x') { long ny=dat->GetNy(), nz=dat->GetNz(), sh=0; r = new mglDataC(nl,ny,nz); for(size_t s=0;sa[sh+i+nl*(j+ny*k)] = dat->vc(pp+i,j,k); sh += ls[s]; } } else if(dir=='z') { long nx=dat->GetNx(), ny=dat->GetNy(), sh=0; r = new mglDataC(nx,ny,nl); for(size_t s=0;sa[i+nx*(j+ny*(sh+k))] = dat->vc(i,j,pp+k); sh += ls[s]; } } return r; } HADT MGL_EXPORT mgl_datac_section_val(HCDT dat, long id, char dir, mreal val) { mglData v; v.a[0]=id; return mgl_datac_section(dat,&v,dir,val); } uintptr_t MGL_EXPORT mgl_datac_section_(uintptr_t *d, uintptr_t *ids, const char *dir, mreal *val,int) { return uintptr_t(mgl_datac_section(_DT_,_DA_(ids),dir[0],*val)); } uintptr_t MGL_EXPORT mgl_datac_section_val_(uintptr_t *d, int *id, const char *dir, mreal *val,int) { return uintptr_t(mgl_datac_section_val(_DT_,*id,dir[0],*val)); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_find_roots_txt_c(const char *func, const char *vars, HCDT ini) { if(!vars || !(*vars) || !func || !ini) return 0; mglEqTxT par; par.var=vars; par.FillCmplx(func); size_t n = par.str.size(); if(ini->GetNx()!=long(n)) return 0; mreal *xx = new mreal[2*n]; mglDataC *res = new mglDataC(ini); for(long j=0;jGetNy()*ini->GetNz();j++) { for(size_t i=0;ivcthr(i+n*j); xx[2*i] = real(c); xx[2*i+1] = imag(c); } bool ok=mgl_find_roots(2*n,mgl_txt_funcC,xx,&par); for(size_t i=0;ia[i+n*j] = ok?dual(xx[2*i],xx[2*i+1]):NAN; } delete []xx; return res; } uintptr_t MGL_EXPORT mgl_find_roots_txt_c_(const char *func, const char *vars, uintptr_t *ini,int l,int m) { char *s=new char[l+1]; memcpy(s,func,l); s[l]=0; char *v=new char[m+1]; memcpy(v,vars,m); v[m]=0; uintptr_t r = uintptr_t(mgl_find_roots_txt_c(s,v,_DA_(ini))); delete []s; delete []v; return r; } //----------------------------------------------------------------------------- ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/exec_dat.cpp�����������������������������������������������������������������������0000644�0001750�0001750�00000232123�13513030041�016217� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * exec_dat.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef WIN32 #include #include #else #include #endif #include "mgl2/base.h" #include "mgl2/parser.h" wchar_t *mgl_str_copy(const char *s); //----------------------------------------------------------------------------- int static mgls_addto(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dd")) *d += *(a[1].d); else if(d && !strcmp(k,"dn")) *d += a[1].v; else if(c && !strcmp(k,"dd")) *c += *(a[1].d); else if(c && !strcmp(k,"dn")) *c += a[1].c; else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_apde(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; if(k[1]=='d' && a[1].d->temp) return 5; mglData *d = dynamic_cast(a[0].d), *f = dynamic_cast(a[1].d); mglDataC *c = dynamic_cast(a[0].d); if(d && f) { mglDataC r; if(!strcmp(k,"ddsdd")) r = gr->APDEc(a[2].s.s, *(a[3].d), *(a[4].d), 0.1,100,opt); else if(!strcmp(k,"ddsddn")) r = gr->APDEc(a[2].s.s, *(a[3].d), *(a[4].d), a[5].v,100,opt); else if(!strcmp(k,"ddsddnn")) r = gr->APDEc(a[2].s.s, *(a[3].d), *(a[4].d), a[5].v,a[6].v,opt); else res = 1; if(res==0) { *d = r.Abs(); *f = r.Arg(); } } else if(d) { if(!strcmp(k,"dsdd")) *d = gr->APDE(a[1].s.s, *(a[2].d), *(a[3].d), 0.1,100,opt); else if(!strcmp(k,"dsddn")) *d = gr->APDE(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,100,opt); else if(!strcmp(k,"dsddnn")) *d = gr->APDE(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt); else res = 1; } else if(c) { if(!strcmp(k,"dsdd")) *c = gr->APDEc(a[1].s.s, *(a[2].d), *(a[3].d), 0.1,100,opt); else if(!strcmp(k,"dsddn")) *c = gr->APDEc(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,100,opt); else if(!strcmp(k,"dsddnn")) *c = gr->APDEc(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_clean(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Clean(mgl_int(a[1].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_coil(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dnn")) d->Coil(a[1].v, a[2].v); else if(d && !strcmp(k,"dnnn")) d->Coil(a[1].v, a[2].v, a[3].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_column(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_column(a[1].d,a[2].s.s)); else if(c && !strcmp(k,"dds")) *c = mglDataC(true,mgl_datac_column(a[1].d,a[2].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_combine(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ddd")) *d = mglData(true,mgl_data_combine(a[1].d, a[2].d)); else if(c && !strcmp(k,"ddd")) *c = mglDataC(true,mgl_datac_combine(a[1].d, a[2].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_conts(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dnd")) *d = mglData(true,mgl_data_conts(a[1].v,a[2].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_copy(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(c && !strcmp(k,"dd")) c->Set(a[1].d); else if(!d) return 1; else if(!strcmp(k,"dd")) d->Set(a[1].d); else if(!strcmp(k,"dds")) { d->Set(a[1].d); gr->Fill(*d, a[2].s.s); } else if(!strcmp(k,"ddd")) { mglData *D = dynamic_cast(a[1].d); mglDataC *C = dynamic_cast(a[2].d); if(D && C) { d->Set(C->Real()); D->Set(C->Imag()); } else res = 1; } else if(!strcmp(k,"dn")) *d = a[1].v; else if(!strcmp(k,"ds") && gr->pr) d->Set(mgl_parser_find_var(gr->pr, a[1].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_correl(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_correl(a[1].d, a[1].d, a[2].s.s)); else if(d && !strcmp(k,"ddds")) *d = mglData(true,mgl_data_correl(a[1].d, a[2].d, a[3].s.s)); else if(c && !strcmp(k,"dds")) *c = mglDataC(true,mgl_datac_correl(a[1].d, a[1].d, a[2].s.s)); else if(c && !strcmp(k,"ddds")) *c = mglDataC(true,mgl_datac_correl(a[1].d, a[2].d, a[3].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cosfft(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->CosFFT(a[1].s.s); else if(c && !strcmp(k,"ds")) d->CosFFT(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_crop(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dnns")) d->Crop(mgl_int(a[1].v),mgl_int(a[2].v),a[3].s.s[0]); else if(d && !strcmp(k,"ds")) d->Crop(a[1].s.s); else if(c && !strcmp(k,"dnns")) c->Crop(mgl_int(a[1].v),mgl_int(a[2].v),a[3].s.s[0]); else if(c && !strcmp(k,"ds")) c->Crop(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cumsum(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->CumSum(a[1].s.s); else if(c && !strcmp(k,"ds")) c->CumSum(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_datagrid(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!strcmp(k,"dddd") && d) gr->DataGrid(*d, *(a[1].d), *(a[2].d), *(a[3].d),opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_datas(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) { char *buf=new char[1024]; long n=mgl_datas_hdf(a[0].s.s,buf,1024); if(n<0) { delete []buf; buf=new char[-n]; mgl_datas_hdf(a[0].s.s,buf,-n); } gr->SetWarn(-1,buf); delete []buf; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_delete(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if((!strcmp(k,"d") || !strcmp(k,"s")) && gr->pr) mgl_parser_del_var(gr->pr, a[0].s.s); else if(d && !strcmp(k,"ds")) d->Delete(a[1].s.s[0]); else if(d && !strcmp(k,"dsn")) d->Delete(a[1].s.s[0], mgl_int(a[2].v)); else if(d && !strcmp(k,"dsnn")) d->Delete(a[1].s.s[0], mgl_int(a[2].v), mgl_int(a[3].v)); else if(c && !strcmp(k,"ds")) c->Delete(a[1].s.s[0]); else if(c && !strcmp(k,"dsn")) c->Delete(a[1].s.s[0], mgl_int(a[2].v)); else if(c && !strcmp(k,"dsnn")) c->Delete(a[1].s.s[0], mgl_int(a[2].v), mgl_int(a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_detect(mglGraph *, long, mglArg *a, const char *k, const char *) { mglData *r = dynamic_cast(a[0].d); int res = 0; if(r && !strcmp(k, "ddnn")) r->Set(mglDetect(*(a[1].d), a[2].v, a[3].v)); else if(r && !strcmp(k, "ddnnn")) r->Set(mglDetect(*(a[1].d), a[2].v, a[3].v, a[4].v)); else if(r && !strcmp(k, "ddnnnn")) r->Set(mglDetect(*(a[1].d), a[2].v, a[3].v, a[4].v, a[5].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_diff(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Diff(a[1].s.s); else if(d && !strcmp(k,"ddd")) d->Diff(*(a[1].d), *(a[2].d)); else if(d && !strcmp(k,"dddd")) d->Diff(*(a[1].d), *(a[2].d), *(a[3].d)); else if(c && !strcmp(k,"ds")) c->Diff(a[1].s.s); // else if(c && !strcmp(k,"ddd")) c->Diff(*(a[1].d), *(a[2].d)); // TODO Add later // else if(c && !strcmp(k,"dddd")) c->Diff(*(a[1].d), *(a[2].d), *(a[3].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_diff2(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Diff2(a[1].s.s); else if(c && !strcmp(k,"ds")) c->Diff2(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_diffract(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; mglDataC *c = dynamic_cast(a[0].d); if(c && !strcmp(k,"dsn")) c->Diffraction(a[1].s.s, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_dilate(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"d")) d->Dilate(); else if(d && !strcmp(k,"dn")) d->Dilate(a[1].v); else if(d && !strcmp(k,"dnn")) d->Dilate(a[1].v, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_divto(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dd")) *d /= *(a[1].d); else if(d && !strcmp(k,"dn")) *d /= a[1].v; else if(c && !strcmp(k,"dd")) *c /= *(a[1].d); else if(c && !strcmp(k,"dn")) *c /= a[1].c; else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_echo(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) gr->SetWarn(-1,a[0].d->Get().c_str()); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_envelop(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"d")) d->Envelop(); else if(d && !strcmp(k,"ds")) d->Envelop(a[1].s.s[0]); else if(c && !strcmp(k,"d")) c->Envelop(); else if(c && !strcmp(k,"ds")) c->Envelop(a[1].s.s[0]); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_erode(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"d")) d->Erode(); else if(d && !strcmp(k,"dn")) d->Erode(a[1].v); else if(d && !strcmp(k,"dnn")) d->Erode(a[1].v, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_evaluate(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && k[0]=='d' && k[1]=='d' && k[2]=='d') { if(k[3]==0) *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,0,0,true)); else if(!strcmp(k+3,"n")) *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,0,0, a[3].v!=0)); else if(!strcmp(k+3,"d")) *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,0,true)); else if(!strcmp(k+3,"dn")) *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,0, a[4].v!=0)); else if(!strcmp(k+3,"dd")) *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,a[4].d,true)); else if(!strcmp(k+3,"ddn")) *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,a[4].d, a[5].v!=0)); else res = 1; } else if(c && k[0]=='d' && k[1]=='d' && k[2]=='d') { if(k[3]==0) *c = mglDataC(true,mgl_datac_evaluate(a[1].d,a[2].d,0,0,true)); else if(!strcmp(k+3,"n")) *c = mglDataC(true,mgl_datac_evaluate(a[1].d,a[2].d,0,0, a[3].v!=0)); else if(!strcmp(k+3,"d")) *c = mglDataC(true,mgl_datac_evaluate(a[1].d,a[2].d,a[3].d,0,true)); else if(!strcmp(k+3,"dn")) *c = mglDataC(true,mgl_datac_evaluate(a[1].d,a[2].d,a[3].d,0, a[4].v!=0)); else if(!strcmp(k+3,"dd")) *c = mglDataC(true,mgl_datac_evaluate(a[1].d,a[2].d,a[3].d,a[4].d,true)); else if(!strcmp(k+3,"ddn")) *c = mglDataC(true,mgl_datac_evaluate(a[1].d,a[2].d,a[3].d,a[4].d, a[5].v!=0)); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_export(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"dss")) a[0].d->Export(a[1].s.s, a[2].s.s); else if(!strcmp(k,"dssnn")) a[0].d->Export(a[1].s.s, a[2].s.s, a[3].v,a[4].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_extend(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Extend(mgl_int(a[1].v)); else if(d && !strcmp(k,"dnn")) d->Extend(mgl_int(a[1].v),mgl_int(a[2].v)); else if(c && !strcmp(k,"dn")) c->Extend(mgl_int(a[1].v)); else if(c && !strcmp(k,"dnn")) c->Extend(mgl_int(a[1].v),mgl_int(a[2].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_minmax(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dd")) *d = mglData(true,mgl_data_minmax(a[1].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_connect(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; // if(k[0]=='d' && a[0].d->temp) return 5; mglData *d1 = dynamic_cast(a[0].d); mglData *d2 = dynamic_cast(a[1].d); if(d1 && !strcmp(k,"ddd")) *d1 = mglData(true,mgl_data_connect(a[1].d,a[2].d)); else if(d1 && d2 && !strcmp(k,"dd")) mgl_data_connect_r(d1,d2); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fill(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && k[0]=='d') { if(!strcmp(k,"dnn")) d->Fill(a[1].v,a[2].v); else if(!strcmp(k,"dnns")) d->Fill(a[1].v,a[2].v,a[3].s.s[0]); else if(!strcmp(k,"ds")) gr->Fill(*d,a[1].s.s,opt); else if(!strcmp(k,"dsd")) gr->Fill(*d,a[1].s.s, *(a[2].d),opt); else if(!strcmp(k,"dsdd")) gr->Fill(*d,a[1].s.s, *(a[2].d), *(a[3].d),opt); else res = 1; } else if(c && k[0]=='d') { if(!strcmp(k,"dnn")) c->Fill(a[1].v,a[2].v); else if(!strcmp(k,"dnns")) c->Fill(a[1].v,a[2].v,a[3].s.s[0]); else if(!strcmp(k,"ds")) gr->Fill(*c,a[1].s.s,opt); else if(!strcmp(k,"dsd")) gr->Fill(*c,a[1].s.s, *(a[2].d),opt); else if(!strcmp(k,"dsdd")) gr->Fill(*c,a[1].s.s, *(a[2].d), *(a[3].d),opt); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fillsample(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->FillSample(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fit(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dddddssd")) { mglData *i = dynamic_cast(a[7].d); if(i) *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s, a[6].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"dddddss")) *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s, a[6].s.s,opt); else if(!strcmp(k,"ddddssd")) { mglData *i = dynamic_cast(a[6].d); if(i) *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s, a[5].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"ddddss")) *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s, a[5].s.s,opt); else if(!strcmp(k,"dddssd")) { mglData *i = dynamic_cast(a[5].d); if(i) *d = gr->Fit(*(a[1].d), *(a[2].d), a[3].s.s, a[4].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"dddss")) *d = gr->Fit(*(a[1].d), *(a[2].d), a[3].s.s, a[4].s.s,opt); else if(!strcmp(k,"ddssd")) { mglData *i = dynamic_cast(a[4].d); if(i) *d = gr->Fit(*(a[1].d), a[2].s.s, a[3].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"ddss")) *d = gr->Fit(*(a[1].d), a[2].s.s, a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fits(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"ddddddssd")) { mglData *i = dynamic_cast(a[8].d); if(i) *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.s, a[7].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"ddddddss")) *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.s, a[7].s.s,opt); else if(!strcmp(k,"dddddssd")) { mglData *i = dynamic_cast(a[7].d); if(i) *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s, a[6].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"dddddss")) *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s, a[6].s.s,opt); else if(!strcmp(k,"ddddssd")) { mglData *i = dynamic_cast(a[6].d); if(i) *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s, a[5].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"ddddss")) *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s, a[5].s.s,opt); else if(!strcmp(k,"dddssd")) { mglData *i = dynamic_cast(a[5].d); if(i) *d = gr->FitS(*(a[1].d), *(a[2].d), a[3].s.s, a[4].s.s, *i,opt); else res = 1; } else if(!strcmp(k,"dddss")) *d = gr->FitS(*(a[1].d), *(a[2].d), a[3].s.s, a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fourier(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *re = dynamic_cast(a[0].d), *im = dynamic_cast(a[1].d); mglDataC *c = dynamic_cast(a[0].d); if(!strcmp(k,"dds") && re && im) mglFourier(*re,*im,a[2].s.s); else if(!strcmp(k,"ds") && c) c->FFT(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_gspline(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ddd")) d->RefillGS(*(a[1].d),*(a[2].d),gr->Self()->Min.x,gr->Self()->Max.x,-1); else if(d && !strcmp(k,"dddn")) d->RefillGS(*(a[1].d),*(a[2].d),gr->Self()->Min.x,gr->Self()->Max.x,mgl_int(a[3].v)); else if(c && !strcmp(k,"ddd")) c->RefillGS(*(a[1].d),*(a[2].d),gr->Self()->Min.x,gr->Self()->Max.x,-1); else if(c && !strcmp(k,"dddn")) c->RefillGS(*(a[1].d),*(a[2].d),gr->Self()->Min.x,gr->Self()->Max.x,mgl_int(a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_hankel(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Hankel(a[1].s.s); else if(c && !strcmp(k,"ds")) c->Hankel(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_hist(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"ddd")) *d = gr->Hist(*(a[1].d), *(a[2].d),opt); else if(!strcmp(k,"dddd")) *d = gr->Hist(*(a[1].d), *(a[2].d), *(a[3].d),opt); else if(!strcmp(k,"ddddd")) *d = gr->Hist(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d),opt); else if(!strcmp(k,"ddnnn")) *d = mglData(true,mgl_data_hist(a[1].d,int(a[2].v+0.5), a[3].v, a[4].v, 0)); else if(!strcmp(k,"ddnnnn")) *d = mglData(true,mgl_data_hist(a[1].d,mgl_int(a[2].v), a[3].v, a[4].v, mgl_int(a[5].v))); else if(!strcmp(k,"dddnnn")) *d = mglData(true,mgl_data_hist_w(a[1].d,a[2].d, mgl_int(a[3].v), a[4].v, a[5].v, 0)); else if(!strcmp(k,"dddnnnn")) *d = mglData(true,mgl_data_hist_w(a[1].d,a[2].d, mgl_int(a[3].v), a[4].v, a[5].v, mgl_int(a[6].v))); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_idset(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; if(!strcmp(k,"ds")) a[0].d->SetColumnId(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_import(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dss")) d->Import(a[1].s.s, a[2].s.s); else if(!strcmp(k,"dssnn")) d->Import(a[1].s.s, a[2].s.s, a[3].v,a[4].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_info(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) gr->SetWarn(-1,a[0].d->PrintInfo()); else if(!strcmp(k,"s")) gr->SetWarn(-1,a[0].s.s); else if(!strcmp(k,"n")) gr->SetWarn(-1,("value = "+mgl_str_num(a[0].v)).c_str()); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_insert(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Insert(a[1].s.s[0]); else if(d && !strcmp(k,"dsn")) d->Insert(a[1].s.s[0], mgl_int(a[2].v)); else if(d && !strcmp(k,"dsnn")) d->Insert(a[1].s.s[0], mgl_int(a[2].v), mgl_int(a[3].v)); else if(c && !strcmp(k,"ds")) c->Insert(a[1].s.s[0]); else if(c && !strcmp(k,"dsn")) c->Insert(a[1].s.s[0], mgl_int(a[2].v)); else if(c && !strcmp(k,"dsnn")) c->Insert(a[1].s.s[0], mgl_int(a[2].v), mgl_int(a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_integrate(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Integral(a[1].s.s); else if(c && !strcmp(k,"ds")) c->Integral(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_jacobian(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"ddd")) *d = mglJacobian(*(a[1].d), *(a[2].d)); else if(!strcmp(k,"dddd")) *d = mglJacobian(*(a[1].d), *(a[2].d), *(a[3].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_join(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if((!d && !c) || k[1]!='d') res = 1; else if(d) for(long i=1;k[i]=='d';i++) d->Join(*(a[i].d)); else if(c) for(long i=1;k[i]=='d';i++) c->Join(*(a[i].d)); return res; } //----------------------------------------------------------------------------- int static mgls_limit(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Limit(a[1].v); else if(c && !strcmp(k,"dn")) c->Limit(a[1].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_max(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_max_dir(a[1].d,a[2].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_min(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_min_dir(a[1].d,a[2].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_mirror(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Mirror(a[1].s.s); else if(c && !strcmp(k,"ds")) c->Mirror(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_modify(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Modify(a[1].s.s); else if(d && !strcmp(k,"dsn")) d->Modify(a[1].s.s, mgl_int(a[2].v)); else if(d && !strcmp(k,"dsd")) d->Modify(a[1].s.s,*(a[2].d)); else if(d && !strcmp(k,"dsdd")) d->Modify(a[1].s.s,*(a[2].d),*(a[3].d)); else if(c && !strcmp(k,"ds")) c->Modify(a[1].s.s); else if(c && !strcmp(k,"dsn")) c->Modify(a[1].s.s, mgl_int(a[2].v)); else if(c && !strcmp(k,"dsd")) c->Modify(a[1].s.s,*(a[2].d)); else if(c && !strcmp(k,"dsdd")) c->Modify(a[1].s.s,*(a[2].d),*(a[3].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_momentum(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_momentum(a[1].d,'z', a[2].s.s)); else if(d && !strcmp(k,"ddss")) *d = mglData(true,mgl_data_momentum(a[1].d,a[3].s.s[0], a[2].s.s)); else if(c && !strcmp(k,"dds")) *c = mglDataC(true,mgl_datac_momentum(a[1].d,'z', a[2].s.s)); else if(c && !strcmp(k,"ddss")) *c = mglDataC(true,mgl_datac_momentum(a[1].d,a[3].s.s[0], a[2].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_multo(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dd")) *d *= *(a[1].d); else if(d && !strcmp(k,"dn")) *d *= a[1].v; else if(c && !strcmp(k,"dd")) *c *= *(a[1].d); else if(c && !strcmp(k,"dn")) *c *= a[1].c; else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_new(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Create(mgl_int(a[1].v)); else if(d && !strcmp(k,"dns")) { d->Create(mgl_int(a[1].v)); d->Fill(gr->Self(),a[2].s.s,opt); } else if(d && !strcmp(k,"dnn")) d->Create(mgl_int(a[1].v),mgl_int(a[2].v)); else if(d && !strcmp(k,"dnns")) { d->Create(mgl_int(a[1].v),mgl_int(a[2].v)); d->Fill(gr->Self(),a[3].s.s,opt); } else if(d && !strcmp(k,"dnnn")) d->Create(mgl_int(a[1].v),mgl_int(a[2].v),mgl_int(a[3].v)); else if(d && !strcmp(k,"dnnns")) { d->Create(mgl_int(a[1].v),mgl_int(a[2].v),mgl_int(a[3].v)); d->Fill(gr->Self(),a[4].s.s,opt); } else if(c && !strcmp(k,"dn")) c->Create(mgl_int(a[1].v)); else if(c && !strcmp(k,"dns")) { c->Create(mgl_int(a[1].v)); c->Fill(gr->Self(),a[2].s.s,opt); } else if(c && !strcmp(k,"dnn")) c->Create(mgl_int(a[1].v),mgl_int(a[2].v)); else if(c && !strcmp(k,"dnns")) { c->Create(mgl_int(a[1].v),mgl_int(a[2].v)); c->Fill(gr->Self(),a[3].s.s,opt); } else if(c && !strcmp(k,"dnnn")) c->Create(mgl_int(a[1].v),mgl_int(a[2].v),mgl_int(a[3].v)); else if(c && !strcmp(k,"dnnns")) { c->Create(mgl_int(a[1].v),mgl_int(a[2].v),mgl_int(a[3].v)); c->Fill(gr->Self(),a[4].s.s,opt); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_norm(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dnn")) d->Norm(a[1].v,a[2].v); else if(!strcmp(k,"dnnn")) d->Norm(a[1].v,a[2].v,a[3].v!=0); else if(!strcmp(k,"dnnnn")) d->Norm(a[1].v,a[2].v,a[3].v!=0,mgl_int(a[4].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_normsl(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dnn")) d->NormSl(a[1].v, a[2].v); else if(!strcmp(k,"dnns")) d->NormSl(a[1].v, a[2].v, a[3].s.s[0]); else if(!strcmp(k,"dnnsn")) d->NormSl(a[1].v, a[2].v, a[3].s.s[0],a[4].v); else if(!strcmp(k,"dnnsnn"))d->NormSl(a[1].v, a[2].v, a[3].s.s[0],a[4].v,a[5].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ode(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d) { if(!strcmp(k,"dssd")) *d = mglODE(a[1].s.s, a[2].s.s, *(a[3].d)); else if(!strcmp(k,"dssdnn")) *d = mglODE(a[1].s.s, a[2].s.s, *(a[3].d), a[4].v, a[5].v); } else if(c) { if(!strcmp(k,"dssd")) *c = mglODEc(a[1].s.s, a[2].s.s, *(a[3].d)); else if(!strcmp(k,"dssdnn")) *c = mglODEc(a[1].s.s, a[2].s.s, *(a[3].d), a[4].v, a[5].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_openhdf(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s") && gr->pr) mgl_parser_openhdf(gr->pr, a[0].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_pde(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; if(k[1]=='d' && a[1].d->temp) return 5; mglData *d = dynamic_cast(a[0].d), *f = dynamic_cast(a[1].d); mglDataC *c = dynamic_cast(a[0].d); if(d && f) { mglDataC r; if(!strcmp(k,"ddsdd")) r = gr->PDEc(a[2].s.s, *(a[3].d), *(a[4].d), 0.1,100,opt); else if(!strcmp(k,"ddsddn")) r = gr->PDEc(a[2].s.s, *(a[3].d), *(a[4].d), a[5].v,100,opt); else if(!strcmp(k,"ddsddnn")) r = gr->PDEc(a[2].s.s, *(a[3].d), *(a[4].d), a[5].v,a[6].v,opt); else res = 1; if(res==0) { *d = r.Abs(); *f = r.Arg(); } } else if(d) { if(!strcmp(k,"dsdd")) *d = gr->PDE(a[1].s.s, *(a[2].d), *(a[3].d), 0.1,100,opt); else if(!strcmp(k,"dsddn")) *d = gr->PDE(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,100,opt); else if(!strcmp(k,"dsddnn")) *d = gr->PDE(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt); else res = 1; } else if(c) { if(!strcmp(k,"dsdd")) *c = gr->PDEc(a[1].s.s, *(a[2].d), *(a[3].d), 0.1,100,opt); else if(!strcmp(k,"dsddn")) *c = gr->PDEc(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,100,opt); else if(!strcmp(k,"dsddnn")) *c = gr->PDEc(a[1].s.s, *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_print(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) printf("%s\n",a[0].d->PrintInfo()); else if(!strcmp(k,"s")) printf("%s\n",a[0].s.s); else if(!strcmp(k,"n")) printf("value = %g\n",a[0].v); else res = 1; fflush(stdout); return res; } //----------------------------------------------------------------------------- int static mgls_progress(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn") && mgl_progress_func) mgl_progress_func(mgl_int(a[0].v), mgl_int(a[1].v), gr->Self()); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_pulse(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_pulse(a[1].d,a[2].s[0])); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_put(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d) { if(!strcmp(k,"dn")) d->Put(a[1].v); else if(!strcmp(k,"dnn")) d->Put(a[1].v, mgl_int(a[2].v)); else if(!strcmp(k,"dnnn")) d->Put(a[1].v, mgl_int(a[2].v),mgl_int(a[3].v)); else if(!strcmp(k,"dnnnn")) d->Put(a[1].v, mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v)); else if(!strcmp(k,"dd")) d->Put(*(a[1].d)); else if(!strcmp(k,"ddn")) d->Put(*(a[1].d), mgl_int(a[2].v)); else if(!strcmp(k,"ddnn")) d->Put(*(a[1].d), mgl_int(a[2].v),mgl_int(a[3].v)); else if(!strcmp(k,"ddnnn")) d->Put(*(a[1].d), mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v)); else res = 1; } else if(c) { if(!strcmp(k,"dn")) c->Put(a[1].c); else if(!strcmp(k,"dnn")) c->Put(a[1].c, mgl_int(a[2].v)); else if(!strcmp(k,"dnnn")) c->Put(a[1].c, mgl_int(a[2].v),mgl_int(a[3].v)); else if(!strcmp(k,"dnnnn")) c->Put(a[1].c, mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v)); else if(!strcmp(k,"dd")) c->Put(*(a[1].d)); else if(!strcmp(k,"ddn")) c->Put(*(a[1].d), mgl_int(a[2].v)); else if(!strcmp(k,"ddnn")) c->Put(*(a[1].d), mgl_int(a[2].v),mgl_int(a[3].v)); else if(!strcmp(k,"ddnnn")) c->Put(*(a[1].d), mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v)); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_putsfit(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; gr->Self()->SaveState(opt); if(!strcmp(k,"nn")) gr->PutsFit(mglPoint(a[0].v,a[1].v)); else if(!strcmp(k,"nns")) gr->PutsFit(mglPoint(a[0].v,a[1].v), a[2].s.s); else if(!strcmp(k,"nnss")) gr->PutsFit(mglPoint(a[0].v,a[1].v), a[2].s.s,a[3].s.s); else if(!strcmp(k,"nnssn")) gr->PutsFit(mglPoint(a[0].v,a[1].v), a[2].s.s,a[3].s.s,a[4].v); else if(!strcmp(k,"nnn")) gr->PutsFit(mglPoint(a[0].v,a[1].v,a[2].v)); else if(!strcmp(k,"nnns")) gr->PutsFit(mglPoint(a[0].v,a[1].v,a[2].v), a[3].s.s); else if(!strcmp(k,"nnnss")) gr->PutsFit(mglPoint(a[0].v,a[1].v,a[2].v), a[3].s.s,a[4].s.s); else if(!strcmp(k,"nnnssn"))gr->PutsFit(mglPoint(a[0].v,a[1].v,a[2].v), a[3].s.s,a[4].s.s,a[5].v); else res = 1; gr->Self()->LoadState(); return res; } //----------------------------------------------------------------------------- int static mgls_qo2d(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; if(k[1]=='d' && a[1].d->temp) return 5; mglData *d = dynamic_cast(a[0].d), *f = dynamic_cast(a[1].d); mglDataC *c = dynamic_cast(a[0].d); if(d && f) { mglDataC r; if(!strcmp(k,"ddsddd")) r = mglDataC(true, mgl_qo2d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, 1,100, 0,0)); else if(!strcmp(k,"ddsdddn")) r = mglDataC(true, mgl_qo2d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, a[6].v,100, 0,0)); else if(!strcmp(k,"ddsdddnn")) r = mglDataC(true, mgl_qo2d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, 0,0)); else if(!strcmp(k,"ddsdddnndd")) r = mglDataC(true, mgl_qo2d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, dynamic_cast(a[8].d),dynamic_cast(a[9].d))); else res = 1; if(res==0) { *d = r.Abs(); *f = r.Arg(); } } else if(d) { if(!strcmp(k,"dsddd")) *d = mglData(true, mgl_qo2d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, 1,100, 0,0)); else if(!strcmp(k,"dsdddn")) *d = mglData(true, mgl_qo2d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0)); else if(!strcmp(k,"dsdddnn")) *d = mglData(true, mgl_qo2d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0)); else if(!strcmp(k,"dsdddnndd")) *d = mglData(true, mgl_qo2d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, dynamic_cast(a[7].d),dynamic_cast(a[8].d))); else res = 1; } else if(c) { if(!strcmp(k,"dsddd")) *c = mglDataC(true, mgl_qo2d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, 1,100, 0,0)); else if(!strcmp(k,"dsdddn")) *c = mglDataC(true, mgl_qo2d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0)); else if(!strcmp(k,"dsdddnn")) *c = mglDataC(true, mgl_qo2d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0)); else if(!strcmp(k,"dsdddnndd")) *c = mglDataC(true, mgl_qo2d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, dynamic_cast(a[7].d),dynamic_cast(a[8].d))); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_qo3d(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; if(k[1]=='d' && a[1].d->temp) return 5; mglData *d = dynamic_cast(a[0].d), *f = dynamic_cast(a[1].d); mglDataC *c = dynamic_cast(a[0].d); if(d && f) { mglDataC r; if(!strcmp(k,"ddsddd")) r = mglDataC(true, mgl_qo3d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, 1,100, 0,0,0)); else if(!strcmp(k,"ddsdddn")) r = mglDataC(true, mgl_qo3d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, a[6].v,100, 0,0,0)); else if(!strcmp(k,"ddsdddnn")) r = mglDataC(true, mgl_qo3d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, 0,0,0)); else if(!strcmp(k,"ddsdddnnddd")) r = mglDataC(true, mgl_qo3d_solve_c(a[2].s.s, a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, dynamic_cast(a[8].d),dynamic_cast(a[9].d),dynamic_cast(a[10].d))); else res = 1; if(res==0) { *d = r.Abs(); *f = r.Arg(); } } else if(d) { if(!strcmp(k,"dsddd")) *d = mglData(true, mgl_qo3d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, 1,100, 0,0,0)); else if(!strcmp(k,"dsdddn")) *d = mglData(true, mgl_qo3d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0,0)); else if(!strcmp(k,"dsdddnn")) *d = mglData(true, mgl_qo3d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0,0)); else if(!strcmp(k,"dsdddnnddd")) *d = mglData(true, mgl_qo3d_solve(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, dynamic_cast(a[7].d),dynamic_cast(a[8].d),dynamic_cast(a[9].d))); else res = 1; } else if(c) { if(!strcmp(k,"dsddd")) *c = mglDataC(true, mgl_qo3d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, 1,100, 0,0,0)); else if(!strcmp(k,"dsdddn")) *c = mglDataC(true, mgl_qo3d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0,0)); else if(!strcmp(k,"dsdddnn")) *c = mglDataC(true, mgl_qo3d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0,0)); else if(!strcmp(k,"dsdddnnddd")) *c = mglDataC(true, mgl_qo3d_solve_c(a[1].s.s, a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, dynamic_cast(a[7].d),dynamic_cast(a[8].d),dynamic_cast(a[9].d))); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ray(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dsnnnn")) *d = mglRay(a[1].s.s, mglPoint(a[2].v, a[3].v), mglPoint(a[4].v, a[5].v)); else if(!strcmp(k,"dsnnnnnn")) *d = mglRay(a[1].s.s, mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v)); else if(!strcmp(k,"dsnnnnnnn")) *d = mglRay(a[1].s.s, mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v), a[8].v); else if(!strcmp(k,"dsnnnnnnnn")) *d = mglRay(a[1].s.s, mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v), a[8].v,a[9].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_read(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; bool rr=true; if(k[0]=='d' && a[0].d->temp) return 5; if(k[1]=='d' && a[1].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglData *f = dynamic_cast(a[1].d); mglDataC *c = dynamic_cast(a[0].d); if(c) { if(!strcmp(k,"ds")) rr=c->Read(a[1].s.s); else if(!strcmp(k,"dsn")) rr=c->Read(a[1].s.s, mgl_int(a[2].v)); else if(!strcmp(k,"dsnn")) rr=c->Read(a[1].s.s, mgl_int(a[2].v),mgl_int(a[3].v)); else if(!strcmp(k,"dsnnn")) rr=c->Read(a[1].s.s, mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v)); else res = 1; } else if(d && f && k[0]=='d' && k[1]=='d' && k[2]=='s') { mglDataC r; if(k[3]==0) rr=r.Read(a[2].s.s); else if(!strcmp(k+3,"n")) rr=r.Read(a[2].s.s, mgl_int(a[3].v)); else if(!strcmp(k+3,"nn")) rr=r.Read(a[2].s.s, mgl_int(a[3].v),mgl_int(a[4].v)); else if(!strcmp(k+3,"nnn")) rr=r.Read(a[2].s.s, mgl_int(a[3].v),mgl_int(a[4].v),mgl_int(a[5].v)); else res = 1; if(res==0) { *d = r.Real(); *f = r.Imag(); } } else if(d) { if(!strcmp(k,"ds")) rr=d->Read(a[1].s.s); else if(!strcmp(k,"dsn")) rr=d->Read(a[1].s.s, mgl_int(a[2].v)); else if(!strcmp(k,"dsnn")) rr=d->Read(a[1].s.s, mgl_int(a[2].v),mgl_int(a[3].v)); else if(!strcmp(k,"dsnnn")) rr=d->Read(a[1].s.s, mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v)); else res = 1; } else res = 1; if(!rr) gr->SetWarn(mglWarnFile,"Read"); return res; } //----------------------------------------------------------------------------- int static mgls_readall(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; bool rr=true; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) rr=d->ReadAll(a[1].s.s); else if(d && !strcmp(k,"dsn")) rr=d->ReadAll(a[1].s.s, a[2].v); else if(d && !strcmp(k,"dsnn")) rr=d->ReadRange(a[1].s.s, a[2].v, a[3].v); else if(d && !strcmp(k,"dsnnn")) rr=d->ReadRange(a[1].s.s, a[2].v, a[3].v, a[4].v); else if(d && !strcmp(k,"dsnnnn")) rr=d->ReadRange(a[1].s.s, a[2].v, a[3].v, a[4].v, a[5].v); else if(c && !strcmp(k,"ds")) rr=c->ReadAll(a[1].s.s); else if(c && !strcmp(k,"dsn")) rr=c->ReadAll(a[1].s.s, a[2].v); else if(c && !strcmp(k,"dsnn")) rr=c->ReadRange(a[1].s.s, a[2].v, a[3].v); else if(c && !strcmp(k,"dsnnn")) rr=c->ReadRange(a[1].s.s, a[2].v, a[3].v, a[4].v); else if(c && !strcmp(k,"dsnnnn")) rr=c->ReadRange(a[1].s.s, a[2].v, a[3].v, a[4].v, a[5].v); else res = 1; if(!rr) gr->SetWarn(mglWarnFile,"ReadAll"); return res; } //----------------------------------------------------------------------------- int static mgls_readhdf(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dss")) d->ReadHDF(a[1].s.s, a[2].s.s); else if(c && !strcmp(k,"dss")) c->ReadHDF(a[1].s.s, a[2].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_readmat(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; bool rr=true; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) rr=d->ReadMat(a[1].s.s); else if(d && !strcmp(k,"dsn")) rr=d->ReadMat(a[1].s.s, mgl_int(a[2].v)); else if(c && !strcmp(k,"ds")) rr=c->ReadMat(a[1].s.s); else if(c && !strcmp(k,"dsn")) rr=c->ReadMat(a[1].s.s, mgl_int(a[2].v)); else res = 1; if(!rr) gr->SetWarn(mglWarnFile,"ReadMat"); return res; } //----------------------------------------------------------------------------- int static mgls_rearrange(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Rearrange(mgl_int(a[1].v)); else if(d && !strcmp(k,"dnn")) d->Rearrange(mgl_int(a[1].v), mgl_int(a[2].v)); else if(d && !strcmp(k,"dnnn")) d->Rearrange(mgl_int(a[1].v), mgl_int(a[2].v), mgl_int(a[3].v)); else if(c && !strcmp(k,"dn")) c->Rearrange(mgl_int(a[1].v)); else if(c && !strcmp(k,"dnn")) c->Rearrange(mgl_int(a[1].v), mgl_int(a[2].v)); else if(c && !strcmp(k,"dnnn")) c->Rearrange(mgl_int(a[1].v), mgl_int(a[2].v), mgl_int(a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_refill(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && k[0]=='d' && k[1]=='d' && k[2]=='d') { if(k[3]==0) gr->Refill(*d,*(a[1].d),*(a[2].d),-1,opt); else if(!strcmp(k+3,"n")) gr->Refill(*d,*(a[1].d),*(a[2].d),mgl_int(a[3].v),opt); else if(!strcmp(k+3,"d")) gr->Refill(*d,*(a[1].d),*(a[2].d),*(a[3].d),-1,opt); else if(!strcmp(k+3,"dn")) gr->Refill(*d,*(a[1].d),*(a[2].d),*(a[3].d),mgl_int(a[4].v),opt); else if(!strcmp(k+3,"dd")) gr->Refill(*d,*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),opt); else res = 1; } else if(c && k[0]=='d' && k[1]=='d' && k[2]=='d') { if(k[3]==0) gr->Refill(*c,*(a[1].d),*(a[2].d),-1,opt); else if(!strcmp(k+3,"n")) gr->Refill(*c,*(a[1].d),*(a[2].d),mgl_int(a[3].v),opt); else if(!strcmp(k+3,"d")) gr->Refill(*c,*(a[1].d),*(a[2].d),*(a[3].d),-1,opt); else if(!strcmp(k+3,"dn")) gr->Refill(*c,*(a[1].d),*(a[2].d),*(a[3].d),mgl_int(a[4].v),opt); else if(!strcmp(k+3,"dd")) gr->Refill(*c,*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),opt); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_resize(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ddn")) *d = mglData(true,mgl_data_resize_box(a[1].d, mgl_int(a[2].v),0,0, 0,1, 0,1, 0,1)); else if(d && !strcmp(k,"ddnn")) *d = mglData(true,mgl_data_resize_box(a[1].d, mgl_int(a[2].v),mgl_int(a[3].v),0, 0,1, 0,1, 0,1)); else if(d && !strcmp(k,"ddnnn"))*d = mglData(true,mgl_data_resize_box(a[1].d, mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v), 0,1, 0,1, 0,1)); else if(c && !strcmp(k,"ddn")) *c = mglDataC(true,mgl_datac_resize_box(a[1].d, mgl_int(a[2].v),0,0, 0,1, 0,1, 0,1)); else if(c && !strcmp(k,"ddnn")) *c = mglDataC(true,mgl_datac_resize_box(a[1].d, mgl_int(a[2].v),mgl_int(a[3].v),0, 0,1, 0,1, 0,1)); else if(c && !strcmp(k,"ddnnn"))*c = mglDataC(true,mgl_datac_resize_box(a[1].d, mgl_int(a[2].v),mgl_int(a[3].v),mgl_int(a[4].v), 0,1, 0,1, 0,1)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_rkstep(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"ss") && gr->pr) mgl_rk_step_w(gr->pr, a[0].s.w, a[1].s.w, 1); else if(!strcmp(k,"ssn") && gr->pr) mgl_rk_step_w(gr->pr, a[0].s.w, a[1].s.w, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_roll(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dsn")) d->Roll(a[1].s.s[0], mgl_int(a[2].v)); else if(c && !strcmp(k,"dsn")) c->Roll(a[1].s.s[0], mgl_int(a[2].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_roots(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dsds")) *d = mglData(true,mgl_data_roots(a[1].s.s, a[2].d, a[3].s[0])); else if(!strcmp(k,"dsns")) d->a[0] = mgl_find_root_txt(a[1].s.s, a[2].v, a[3].s[0]); else if(!strcmp(k,"dsd")) *d = mglData(true,mgl_data_roots(a[1].s.s, a[2].d, 'x')); else if(!strcmp(k,"dsn")) d->a[0] = mgl_find_root_txt(a[1].s.s, a[2].v, 'x'); else if(!strcmp(k,"dssd")) *d = mglData(true,mgl_find_roots_txt(a[1].s.s, a[2].s.s, a[3].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_save(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"ds")) a[0].d->Save(a[1].s.s); else if(!strcmp(k,"ss")) { FILE *fp = fopen(a[1].s.s,"a"); size_t pos; std::string s=a[0].s.s; while((pos=s.find("\\n"))!=std::string::npos) { s[pos]=' '; s[pos+1]='\n'; } while((pos=s.find("\b\b"))!=std::string::npos) s.erase(pos,2); fprintf(fp,"%s\n",s.c_str()); fclose(fp); } else if(!strcmp(k,"sss")) { FILE *fp = fopen(a[1].s.s,a[2].s.s); size_t pos; std::string s=a[0].s.s; while((pos=s.find("\\n"))!=std::string::npos) { s[pos]=' '; s[pos+1]='\n'; } while((pos=s.find("\b\b"))!=std::string::npos) s.erase(pos,2); fprintf(fp,"%s\n",s.c_str()); fclose(fp); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_savehdf(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"dss")) a[0].d->SaveHDF(a[1].s.s, a[2].s.s); else if(!strcmp(k,"dssn")) a[0].d->SaveHDF(a[1].s.s, a[2].s.s,mgl_int(a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_scanfile(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"dss")) { mglData *d = dynamic_cast(a[0].d); if(!d) return 1; d->ScanFile(a[1].s.s, a[2].s.s); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_section(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d) { if(!strcmp(k,"dddsn")) *d = mglData(true,mgl_data_section(a[1].d, a[2].d, a[3].s[0], a[4].v)); else if(!strcmp(k,"ddds")) *d = mglData(true,mgl_data_section(a[1].d, a[2].d, a[3].s[0], NAN)); else if(!strcmp(k,"ddd")) *d = mglData(true,mgl_data_section(a[1].d, a[2].d, 'y', NAN)); else if(!strcmp(k,"ddnsn")) *d = mglData(true,mgl_data_section_val(a[1].d, mgl_int(a[2].v), a[3].s[0], a[4].v)); else if(!strcmp(k,"ddns")) *d = mglData(true,mgl_data_section_val(a[1].d, mgl_int(a[2].v), a[3].s[0], NAN)); else if(!strcmp(k,"ddn")) *d = mglData(true,mgl_data_section_val(a[1].d, mgl_int(a[2].v), 'y', NAN)); else res = 1; } else if(c) { if(!strcmp(k,"dddsn")) *d = mglDataC(true,mgl_datac_section(a[1].d, a[2].d, a[3].s[0], a[4].v)); else if(!strcmp(k,"ddds")) *d = mglDataC(true,mgl_datac_section(a[1].d, a[2].d, a[3].s[0], NAN)); else if(!strcmp(k,"ddd")) *d = mglDataC(true,mgl_datac_section(a[1].d, a[2].d, 'y', NAN)); else if(!strcmp(k,"ddnsn")) *d = mglDataC(true,mgl_datac_section_val(a[1].d, mgl_int(a[2].v), a[3].s[0], a[4].v)); else if(!strcmp(k,"ddns")) *d = mglDataC(true,mgl_datac_section_val(a[1].d, mgl_int(a[2].v), a[3].s[0], NAN)); else if(!strcmp(k,"ddn")) *d = mglDataC(true,mgl_datac_section_val(a[1].d, mgl_int(a[2].v), 'y', NAN)); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_sew(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"d")) d->Sew(); else if(!strcmp(k,"ds")) d->Sew(a[1].s.s); else if(!strcmp(k,"dsn")) d->Sew(a[1].s.s, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_sinfft(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->SinFFT(a[1].s.s); else if(d && !strcmp(k,"ds")) c->SinFFT(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_smooth(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"d")) d->Smooth(); else if(d && !strcmp(k,"ds")) d->Smooth(a[1].s.s); else if(c && !strcmp(k,"d")) c->Smooth(); else if(c && !strcmp(k,"ds")) c->Smooth(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_solve(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"ddns")) *d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], 0, true)); else if(!strcmp(k,"ddnsn")) *d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], 0, a[4].v!=0)); else if(!strcmp(k,"ddnsd")) *d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], a[4].d, true)); else if(!strcmp(k,"ddnsdn"))*d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], a[4].d, a[5].v!=0)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_sort(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Sort(a[1].v, -1); else if(d && !strcmp(k,"dnn")) d->Sort(a[1].v, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_squeeze(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dn")) d->Squeeze(mgl_int(a[1].v)); else if(d && !strcmp(k,"dnn")) d->Squeeze(mgl_int(a[1].v), mgl_int(a[2].v)); else if(d && !strcmp(k,"dnnn")) d->Squeeze(mgl_int(a[1].v), mgl_int(a[2].v),mgl_int(a[3].v)); else if(d && !strcmp(k,"dnnnn"))d->Squeeze(mgl_int(a[1].v), mgl_int(a[2].v),mgl_int(a[3].v), a[4].v); else if(c && !strcmp(k,"dn")) c->Squeeze(mgl_int(a[1].v)); else if(c && !strcmp(k,"dnn")) c->Squeeze(mgl_int(a[1].v), mgl_int(a[2].v)); else if(c && !strcmp(k,"dnnn")) c->Squeeze(mgl_int(a[1].v), mgl_int(a[2].v),mgl_int(a[3].v)); else if(c && !strcmp(k,"dnnnn"))c->Squeeze(mgl_int(a[1].v), mgl_int(a[2].v),mgl_int(a[3].v), a[4].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_stfad(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"dddn")) *d = mglSTFA(*(a[1].d),*(a[2].d), mgl_int(a[3].v)); else if(!strcmp(k,"dddns")) *d = mglSTFA(*(a[1].d),*(a[2].d), mgl_int(a[3].v), a[4].s.s[0]); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_subdata(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d) { if(!strcmp(k,"ddn")) *d = mglData(true,mgl_data_subdata(a[1].d, mgl_int(a[2].v), -1, -1)); else if(!strcmp(k,"ddnn")) *d = mglData(true,mgl_data_subdata(a[1].d, mgl_int(a[2].v), mgl_int(a[3].v), -1)); else if(!strcmp(k,"ddnnn")) *d = mglData(true,mgl_data_subdata(a[1].d, mgl_int(a[2].v), mgl_int(a[3].v), mgl_int(a[4].v))); else if(!strcmp(k,"ddd")) *d = mglData(true,mgl_data_subdata_ext(a[1].d, a[2].d, 0, 0)); else if(!strcmp(k,"dddd")) *d = mglData(true,mgl_data_subdata_ext(a[1].d, a[2].d, a[3].d, 0)); else if(!strcmp(k,"ddddd")) *d = mglData(true,mgl_data_subdata_ext(a[1].d, a[2].d, a[3].d, a[4].d)); else res = 1; } else if(c) { if(!strcmp(k,"ddn")) *c = mglDataC(true,mgl_datac_subdata(a[1].d, mgl_int(a[2].v), -1, -1)); else if(!strcmp(k,"ddnn")) *c = mglDataC(true,mgl_datac_subdata(a[1].d, mgl_int(a[2].v), mgl_int(a[3].v), -1)); else if(!strcmp(k,"ddnnn")) *c = mglDataC(true,mgl_datac_subdata(a[1].d, mgl_int(a[2].v), mgl_int(a[3].v), mgl_int(a[4].v))); else if(!strcmp(k,"ddd")) *c = mglDataC(true,mgl_datac_subdata_ext(a[1].d, a[2].d, 0, 0)); else if(!strcmp(k,"dddd")) *c = mglDataC(true,mgl_datac_subdata_ext(a[1].d, a[2].d, a[3].d, 0)); else if(!strcmp(k,"ddddd")) *c = mglDataC(true,mgl_datac_subdata_ext(a[1].d, a[2].d, a[3].d, a[4].d)); else res = 1; } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_subto(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dd")) *d -= *(a[1].d); else if(d && !strcmp(k,"dn")) *d -= a[1].v; else if(c && !strcmp(k,"dd")) *c -= *(a[1].d); else if(c && !strcmp(k,"dn")) *c -= a[1].c; else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_sum(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dds")) *d = mglData(true,mgl_data_sum(a[1].d,a[2].s.s)); else if(c && !strcmp(k,"dds")) *c = mglDataC(true,mgl_datac_sum(a[1].d,a[2].s.s)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_swap(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"ds")) d->Swap(a[1].s.s); else if(c && !strcmp(k,"ds")) c->Swap(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_trace(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"dd")) *d = mglData(true,mgl_data_trace(a[1].d)); else if(c && !strcmp(k,"dd")) *c = mglDataC(true,mgl_datac_trace(a[1].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_transform(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!strcmp(k,"dsdd") && d) *d = mglTransform(*(a[2].d),*(a[3].d),a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_transforma(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!strcmp(k,"dsdd") && d) *d = mglTransformA(*(a[2].d),*(a[3].d),a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_transpose(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(d && !strcmp(k,"d")) d->Transpose(); else if(d && !strcmp(k,"ds")) d->Transpose(a[1].s.s); else if(c && !strcmp(k,"d")) c->Transpose(); else if(c && !strcmp(k,"ds")) c->Transpose(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_triangulate(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); if(!d) return 1; if(!strcmp(k,"ddd")) *d = mglTriangulation(*(a[1].d), *(a[2].d)); else if(!strcmp(k,"dddd")) *d = mglTriangulation(*(a[1].d), *(a[2].d), *(a[3].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tridmat(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(c && !strcmp(k,"ddddds")) *c = mglTridMatC(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s); else if(d && !strcmp(k,"ddddds")) *d = mglTridMat(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_var(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); // TODO use mglDataV here?! if(!d) return 1; if(!strcmp(k,"dnn")) { d->Create(mgl_int(a[1].v)); d->Fill(a[2].v, NAN); } else if(!strcmp(k,"dnnn")) { d->Create(mgl_int(a[1].v)); d->Fill(a[2].v, a[3].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_wavelet(mglGraph *, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]=='d' && a[0].d->temp) return 5; mglData *d = dynamic_cast(a[0].d); mglDataC *c = dynamic_cast(a[0].d); if(!strcmp(k,"dsn") && d) d->Wavelet(a[1].s.s, mgl_int(a[2].v)); else if(!strcmp(k,"dsn") && c) c->Wavelet(a[1].s.s, mgl_int(a[2].v)); else res = 1; return res; } //----------------------------------------------------------------------------- mglCommand mgls_dat_cmd[] = { {"addto",_("Add data or number"),"addto Var Dat|Var num", mgls_addto ,3}, {"apde",_("Solve PDE using advanced method (X-Y only)"),"apde Res 'ham' IniRe IniIm [dz k0]", mgls_apde ,4}, {"clean",_("Remove duplicate rows"),"clean Dat id", mgls_clean ,3}, {"coil",_("Project periodical data in [v1,v2]"),"coil Dat v1 v2 [sep]", mgls_coil ,16}, {"column",_("Get data column filled by formula on column ids"),"column Res Dat 'eq'", mgls_column ,4}, {"combine",_("Direct multiplication of arrays"), "combine Res Adat Bdat", mgls_combine ,4}, {"connect",_("Get indexes or resort data for found connected surfaces dependent on j,k"),"connect Adat Bdat|Res Adat Bdat", mgls_connect ,4}, {"conts",_("Get contour lines for dat[i,j]=val, separated by NAN"),"conts Res val Dat", mgls_conts ,4}, {"copy",_("Copy data from another variable"),"copy Dat1 Dat2 ['eq']|ReDat ImDat Cdat|Dat val|Dat 'name'", mgls_copy ,4}, {"correl",_("Find correlation between data arrays"), "correl Res Adat Bdat 'dir'|Res Adat 'dir'", mgls_correl ,4}, {"cosfft",_("Cos-Fourier transform at some direction"),"cosfft Dat 'dir'", mgls_cosfft ,16}, {"crop",_("Crop edge of data"),"crop Dat n1 n2 'dir'|Dat 'how'", mgls_crop ,16}, {"cumsum",_("Cumulative summation along direction(s)"),"cumsum Dat 'dir'", mgls_cumsum ,16}, {"datagrid",_("Fill data by triangulated values"),"datagrid Var Xdat Ydat Zdat", mgls_datagrid ,3}, {"datas",_("Print list of data names in HDF file"),"datas 'fname'", mgls_datas ,3}, {"delete",_("Delete data or slice of data"),"delete Dat|'Dat'|Dat 'dir' [pos=0 num=1]", mgls_delete ,3}, {"detect",_("Detect curves for maximums of data array"), "detect Res Dat lvl dj [di min_len]", mgls_detect, 4}, {"diff",_("Numerically differentiate data"),"diff Var 'dir'|Var Dir Const1 [Const2]", mgls_diff ,16}, {"diff2",_("Numerically double differentiate data"),"diff2 Var 'dir'", mgls_diff2 ,16}, {"diffract",_("Step for pulse diffraction"),"diffract Res 'how' q", mgls_diffract ,16}, {"dilate",_("Dilate data larger val"),"dilate Dat [val step]", mgls_dilate ,3}, {"divto",_("Divide by data or number"),"divto Var Dat|Var num", mgls_divto ,3}, {"echo",_("Print content of the data"),"echo Dat", mgls_echo ,3}, {"envelop",_("Find envelop for the data"),"envelop Dat ['dir']", mgls_envelop ,16}, {"erode",_("Erode data larger val"),"erode Dat [val step]", mgls_erode ,3}, {"evaluate",_("Evaluate (interpolate) values of array Dat at points i=idat,j=jdat,k=kdat"),"evaluate Res Dat Idat [norm]|Res Dat Idat Jdat [norm]|Res Dat Idat Jdat Kdat [norm]", mgls_evaluate ,4}, {"export",_("Export data to PNG file"),"export Dat 'fname' 'sch' [v1 v2]", mgls_export ,3}, {"extend",_("Extend data array"),"extend Dat dim1 [dim2]", mgls_extend ,3}, {"minmax",_("Get positions of local maximums and minimums"),"minmax Res Dat", mgls_minmax ,4}, {"fill",_("Fill data linearly in range [v1, v2]"),"fill Var v1 v2 ['dir']|Var 'eq' [Vdat Wdat]", mgls_fill ,3}, {"fillsample",_("Fill x-,k-samples for transforms"),"fillsample Var 'how'", mgls_fillsample ,3}, {"fit",_("Fit data to formula"),"fit Res A 'eq' 'var' [Ini]|Res X A 'eq' 'var' [Ini]|Res X Y A 'eq' 'var' [Ini]|Res X Y Z A 'eq' 'var' [Ini]", mgls_fit ,4}, {"fits",_("Fit data to formula"),"fits Res A S 'eq' 'var' [Ini]|Res X A S 'eq' 'var' [Ini]|Res X Y A S 'eq' 'var' [Ini]|Res X Y Z A S 'eq' 'var' [Ini]", mgls_fits ,4}, {"fourier",_("In-place Fourier transform"),"fourier ReDat ImDat 'dir'|Cmplx 'dir'", mgls_fourier , 16}, {"gspline",_("Fill data by global spline of Vdat"),"gspline Dat Xdat Vdat [sl]", mgls_gspline ,3}, {"hankel",_("Hankel transform at some direction"),"hankel Dat 'dir'", mgls_hankel ,16}, {"hist",_("Create histogram (distribution) of data values"),"hist Res Dat num v1 v2 [nsub]|Res Dat Wdat num v1 v2 [nsub]|Res Xdat Dat|Res Xdat Ydat Dat|Res Xdat Ydat Zdat Dat", mgls_hist ,4}, {"idset",_("Set column id for data"),"idset Dat 'ids'", mgls_idset ,3}, {"import",_("Import data from PNG file"),"import Dat 'fname' 'scheme' [v1 v2]", mgls_import ,4}, {"info",_("Print message or information about the data"),"info Dat|'message'|const", mgls_info ,3}, {"insert",_("Insert slice of data"),"insert Dat 'dir' [pos=0 num=1]", mgls_insert ,3}, {"integrate",_("Integrate data along direction(s)"),"integrate Dat 'dir'", mgls_integrate ,16}, {"jacobian",_("Get Jacobian"),"jacobian Res Xdat Ydat [Zdat]", mgls_jacobian ,4}, {"join",_("Join data arrays"),"join Dat Add1 ...", mgls_join ,3}, {"limit",_("Limit data to be inside [-v,v]"),"limit Dat v", mgls_limit ,16}, {"max",_("Find maximal value over direction"),"max Res Dat 'dir'", mgls_max ,4}, {"min",_("Find minimal value over direction"),"min Res Dat 'dir'", mgls_min ,4}, {"mirror",_("Mirror data at some direction"),"mirror Dat 'dir'", mgls_mirror ,16}, {"modify",_("Modify data values by formula"),"modify Dat 'eq' [num]|Dat 'eq' Vdat [Wdat]", mgls_modify ,3}, {"momentum",_("Get momentum along direction"),"momentum Res Dat 'how' ['dir']", mgls_momentum ,4}, {"multo",_("Multiply by data or number"),"multo Var Dat|Var num", mgls_multo ,3}, {"new",_("Create new data"),"new Dat nx ['eq']|Dat nx ny ['eq']|Dat nx ny nz ['eq']", mgls_new ,4}, {"norm",_("Normalize data"),"norm Dat v1 v2 [sym dim]", mgls_norm ,16}, {"normsl",_("Normalize data slice by slice"),"normsl Dat v1 v2 ['dir' keep sym] ", mgls_normsl ,16}, {"ode",_("Solve ODE"),"ode Res 'df' 'var' Ini [dt tmax]", mgls_ode ,4}, {"openhdf",_("Open all data arrays from HDF file"),"openhdf 'fname'", mgls_openhdf ,3}, {"pde",_("Solve PDE"),"pde Res 'ham' IniRe IniIm [dz k0]", mgls_pde ,4}, {"print",_("Immediately print the message"),"print 'message'|Dat|const", mgls_print ,3}, {"progress",_("Immediately display the progress of calculation"),"progress value maximal", mgls_progress ,3}, {"pulse",_("Get pulse properties"),"pulse Res Dat 'dir'", mgls_pulse ,4}, {"put",_("Put value (numeric or array) to given data element"),"put Dat val [i j k]|Dat Val [i j k]", mgls_put ,3}, {"putsfit",_("Print fitted formula"),"putsfit x y ['pre' 'font' size]|x y z ['pre' 'font' size]", mgls_putsfit ,15}, {"qo2d",_("Solve PDE in accompanied coordinates for 2d case"),"qo2d Res 'ham' IniRe IniIm Ray [r k0 Xout Yout]", mgls_qo2d ,4}, {"qo3d",_("Solve PDE in accompanied coordinates for 3d case"),"qo3d Res 'ham' IniRe IniIm Ray [r k0 Xout Yout Zout]", mgls_qo3d ,4}, {"ray",_("Solve Hamiltonian ODE (find GO ray or trajectory)"),"ray Res 'ham' x0 y0 z0 px0 py0 pz0 [dt=0.1 tmax=10]", mgls_ray ,4}, {"read",_("Read data from file"),"read Dat 'file' [nx ny nz]|ReDat ImDat 'file' [nx ny nz]", mgls_read ,4}, {"readall",_("Read and join data from several files"),"readall Dat 'templ' [slice]|Dat 'templ' from to [step slice]", mgls_readall ,4}, {"readhdf",_("Read data with name 'id' from HDF file"),"readhdf Dat 'file' 'id'", mgls_readhdf ,4}, {"readmat",_("Read data from file with sizes specified in first row"),"readmat Dat 'file' [dim]", mgls_readmat ,4}, {"rearrange",_("Rearrange data dimensions"),"rearrange Dat mx [my mz]", mgls_rearrange ,3}, {"refill",_("Fill data by interpolation of Vdat"),"refill Dat Xdat Vdat [sl]|Dat Xdat Ydat Vdat [sl]|Dat Xdat Ydat Zdat Vdat", mgls_refill ,3}, {"resize",_("Resize data array"),"resize Res Dat mx [my mz]", mgls_resize ,4}, {"rkstep",_("Perform Runge-Kutta step"),"rkstep 'Diff1;Diff2;...' 'Var1;Var2;...' [dt]", mgls_rkstep, 6}, {"roll",_("Roll data along direction(s)"),"roll Dat 'dir' num", mgls_roll ,16}, {"roots",_("Find roots using data as initial values"), "roots Res 'func' Ini ['var']|Res 'func' ini ['var']|Res 'func' 'vars' Ini", mgls_roots ,4}, {"save",_("Save data to file"),"save Dat 'file'|'str' 'file' ['how']", mgls_save ,3}, {"savehdf",_("Save data to HDF5 file"),"savehdf Dat 'file' 'id' [rewrite]", mgls_savehdf ,3}, {"scanfile",_("Get formated data from file"),"scanfile Dat 'fname 'templ'", mgls_scanfile ,4}, {"section",_("Extract sub-array between values"),"section Res Dat id ['dir' val]|Res Dat Ids ['dir' val]", mgls_section ,4}, {"sew",_("Remove jump into the data, like phase jumps"),"sew Dat ['dir' da]", mgls_sew ,16}, {"sinfft",_("Sin-Fourier transform at some direction"),"sinfft Dat 'dir'", mgls_sinfft ,16}, {"smooth",_("Smooth data"),"smooth Dat ['how']", mgls_smooth ,16}, {"solve",_("Find root Dat[i,j,k]=val (inverse evaluate)"),"solve Res Dat val 'dir' [Idat norm]", mgls_solve ,4}, {"sort",_("Sort data by values in column"),"sort Dat idx [idy]", mgls_sort ,3}, {"squeeze",_("Squeeze data"),"squeeze Dat kx [ky kz smooth]", mgls_squeeze ,3}, {"stfad",_("Do STFA transform"),"stfad Res Real Imag dn ['dir']", mgls_stfad ,4}, {"subdata",_("Extract sub-array"),"subdata Res Dat ix [iy iz]|Res Dat Xdat [Ydat Zdat]", mgls_subdata ,4}, {"subto",_("Subtract data or number"),"subto Var Dat|Var num", mgls_subto ,3}, {"sum",_("Find summation over direction"),"sum Res Dat 'dir'", mgls_sum ,4}, {"swap",_("Swap data (useful after Fourier transform)"),"swap Dat 'dir'", mgls_swap ,16}, {"trace",_("Get trace of array"),"trace Res Dat", mgls_trace ,4}, {"transform",_("Do integral transform of data"),"transform Res 'how' Rdat Idat", mgls_transform ,4}, {"transforma",_("Do integral transform of data"),"transforma Res 'how' Adat Pdat", mgls_transforma ,4}, {"transpose",_("Transpose data array"),"transpose Dat ['dir']", mgls_transpose ,16}, {"triangulate",_("Find triangles of randomly placed points"),"triangulate Res Xdat Ydat|Res Xdat Ydat Zdat", mgls_triangulate ,4}, {"tridmat",_("Solve tridiagonal matrix"),"tridmat Res A B C D 'how'", mgls_tridmat ,4}, {"var",_("Create new 1D data and fill it in range"),"var Dat nx x1 [x2]", mgls_var ,4}, {"wavelet",_("Wavelet transform at some direction"),"wavelet Dat 'dir' k", mgls_wavelet ,16}, {"","","",NULL,0}}; //----------------------------------------------------------------------------- ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/exec_gr.cpp������������������������������������������������������������������������0000644�0001750�0001750�00000203267�13513030041�016066� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * exec_1d.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef WIN32 #include #include #else #include #endif #include "mgl2/base.h" #include "mgl2/parser.h" wchar_t *mgl_str_copy(const char *s); //----------------------------------------------------------------------------- // 1D //----------------------------------------------------------------------------- int static mgls_area(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Area(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Area(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Area(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Area(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Area(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Area(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_axial(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Axial(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Axial(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Axial(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Axial(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_bars(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Bars(*(a[0].d), "",opt); else if(!strcmp(k,"ds")) gr->Bars(*(a[0].d), a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Bars(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Bars(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Bars(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Bars(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_barh(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Barh(*(a[0].d), "",opt); else if(!strcmp(k,"ds")) gr->Barh(*(a[0].d), a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Barh(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Barh(*(a[0].d), *(a[1].d), a[2].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_bifurcation(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"nd")) gr->Bifurcation(a[0].v,*(a[1].d),"",opt); else if(!strcmp(k,"nds")) gr->Bifurcation(a[0].v,*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ns")) gr->Bifurcation(a[0].v,a[1].s.s,"",opt); else if(!strcmp(k,"nss")) gr->Bifurcation(a[0].v,a[1].s.s,a[2].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_boxplot(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->BoxPlot(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->BoxPlot(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->BoxPlot(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->BoxPlot(*(a[0].d),*(a[1].d),a[2].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_candle(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Candle(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Candle(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Candle(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Candle(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Candle(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Candle(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Candle(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Candle(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->Candle(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds"))gr->Candle(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_chart(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Chart(*(a[0].d), "",opt); else if(!strcmp(k,"ds")) gr->Chart(*(a[0].d), a[1].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cones(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Cones(*(a[0].d), "",opt); else if(!strcmp(k,"ds")) gr->Cones(*(a[0].d), a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Cones(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Cones(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Cones(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Cones(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_error(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Error(*(a[0].d),*(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Error(*(a[0].d),*(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Error(*(a[0].d),*(a[1].d),*(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Error(*(a[0].d),*(a[1].d),*(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Error(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Error(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_iris(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ds")) gr->Iris(*(a[0].d),a[1].s.w,"",opt); else if(!strcmp(k,"dss")) gr->Iris(*(a[0].d),a[1].s.w,a[2].s.s,opt); else if(!strcmp(k,"dds")) gr->Iris(*(a[0].d),*(a[1].d),a[2].s.w,"",opt); else if(!strcmp(k,"ddss")) gr->Iris(*(a[0].d),*(a[1].d),a[2].s.w,a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_label(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ds")) gr->Label(*(a[0].d), a[1].s.w, "",opt); else if(!strcmp(k,"dss")) gr->Label(*(a[0].d), a[1].s.w, a[2].s.s,opt); else if(!strcmp(k,"dds")) gr->Label(*(a[0].d), *(a[1].d), a[2].s.w, "",opt); else if(!strcmp(k,"ddss")) gr->Label(*(a[0].d), *(a[1].d), a[2].s.w, a[3].s.s,opt); else if(!strcmp(k,"ddds")) gr->Label(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.w, "",opt); else if(!strcmp(k,"dddss")) gr->Label(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.w, a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_lamerey(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"nd")) gr->Lamerey(a[0].v,*(a[1].d),"",opt); else if(!strcmp(k,"nds")) gr->Lamerey(a[0].v,*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ns")) gr->Lamerey(a[0].v,a[1].s.s,"",opt); else if(!strcmp(k,"nss")) gr->Lamerey(a[0].v,a[1].s.s,a[2].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_mark(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Mark(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Mark(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Mark(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Mark(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Mark(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Mark(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ohlc(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dddd")) gr->OHLC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->OHLC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->OHLC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d), "",opt); else if(!strcmp(k,"ddddds")) gr->OHLC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d), a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_plot(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Plot(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Plot(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Plot(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Plot(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Plot(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Plot(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"nns")) gr->Mark(mglPoint(a[0].v,a[1].v,NAN),a[2].s.s); else if(!strcmp(k,"nnns")) gr->Mark(mglPoint(a[0].v,a[1].v,a[2].v),a[3].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_radar(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Radar(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Radar(*(a[0].d),a[1].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_region(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Region(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Region(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Region(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Region(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Region(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Region(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"dddddd")) gr->Region(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"dddddds")) gr->Region(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_stem(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Stem(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Stem(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Stem(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Stem(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Stem(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Stem(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_step(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Step(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Step(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Step(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Step(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Step(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Step(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_table(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Table(*(a[0].d), L"", "#|",opt); else if(!strcmp(k,"ds")) gr->Table(*(a[0].d), a[1].s.w, "#|",opt); else if(!strcmp(k,"dss")) gr->Table(*(a[0].d), a[1].s.w, a[2].s.s,opt); else if(!strcmp(k,"nnd")) gr->Table(a[0].v, a[1].v, *(a[2].d), L"", "#|",opt); else if(!strcmp(k,"nnds")) gr->Table(a[0].v, a[1].v, *(a[2].d), a[3].s.w, "#|",opt); else if(!strcmp(k,"nndss")) gr->Table(a[0].v, a[1].v, *(a[2].d), a[3].s.w, a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tape(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Tape(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Tape(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Tape(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Tape(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Tape(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Tape(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tens(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Tens(*(a[0].d),*(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Tens(*(a[0].d),*(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Tens(*(a[0].d),*(a[1].d),*(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Tens(*(a[0].d),*(a[1].d),*(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Tens(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Tens(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); return res; } //----------------------------------------------------------------------------- int static mgls_textmark(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ds")) gr->TextMark(*(a[0].d),a[1].s.w,"",opt); else if(!strcmp(k,"dss")) gr->TextMark(*(a[0].d),a[1].s.w,a[2].s.s,opt); else if(!strcmp(k,"dds")) gr->TextMark(*(a[0].d),*(a[1].d),a[2].s.w,"",opt); else if(!strcmp(k,"ddss")) gr->TextMark(*(a[0].d),*(a[1].d),a[2].s.w,a[3].s.s,opt); else if(!strcmp(k,"ddds")) gr->TextMark(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.w,"",opt); else if(!strcmp(k,"dddss")) gr->TextMark(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.w,a[4].s.s,opt); else if(!strcmp(k,"dddds")) gr->TextMark(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.w,"",opt); else if(!strcmp(k,"ddddss"))gr->TextMark(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.w,a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_torus(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Torus(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Torus(*(a[0].d),*(a[1].d),a[2].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tube(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dn")) gr->Tube(*(a[0].d),a[1].v,"",opt); else if(!strcmp(k,"dns")) gr->Tube(*(a[0].d),a[1].v,a[2].s.s,opt); else if(!strcmp(k,"dd")) gr->Tube(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Tube(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddn")) gr->Tube(*(a[0].d),*(a[1].d),a[2].v,"",opt); else if(!strcmp(k,"ddns")) gr->Tube(*(a[0].d),*(a[1].d),a[2].v,a[3].s.s,opt); else if(!strcmp(k,"ddd")) gr->Tube(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Tube(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddn")) gr->Tube(*(a[0].d),*(a[1].d),*(a[2].d),a[3].v,"",opt); else if(!strcmp(k,"dddns")) gr->Tube(*(a[0].d),*(a[1].d),*(a[2].d),a[3].v,a[4].s.s,opt); else if(!strcmp(k,"dddd")) gr->Tube(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Tube(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- // 2D //----------------------------------------------------------------------------- int static mgls_belt(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Belt(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Belt(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Belt(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Belt(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_beltc(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->BeltC(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->BeltC(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->BeltC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->BeltC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_boxs(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Boxs(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Boxs(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Boxs(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Boxs(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cont(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Cont(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Cont(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->Cont(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Cont(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Cont(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Cont(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Cont(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Cont(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,opt); else if(!strcmp(k,"ndddd")) gr->ContGen(a[0].v, *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d),"",opt); else if(!strcmp(k,"ndddds")) gr->ContGen(a[0].v, *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contd(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContD(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->ContD(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->ContD(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->ContD(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->ContD(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->ContD(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->ContD(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->ContD(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contf(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContF(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->ContF(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->ContF(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->ContF(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->ContF(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->ContF(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->ContF(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->ContF(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,opt); else if(!strcmp(k,"nndddd")) gr->ContFGen(a[0].v, a[1].v, *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d),"",opt); else if(!strcmp(k,"nndddds")) gr->ContFGen(a[0].v, a[1].v, *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contp(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dddd")) gr->ContP(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->ContP(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->ContP(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), "",opt); else if(!strcmp(k,"ddddds")) gr->ContP(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contv(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContV(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->ContV(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dd")) gr->ContV(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->ContV(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->ContV(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->ContV(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->ContV(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->ContV(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_dens(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Dens(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Dens(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Dens(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Dens(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fall(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Fall(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Fall(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Fall(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Fall(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_grid2(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Grid(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Grid(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Grid(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Grid(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_map(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Map(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Map(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->Map(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Map(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_mesh(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Mesh(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Mesh(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Mesh(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Mesh(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_pmap(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Pmap(*(a[0].d), *(a[1].d), "",opt); else if(!strcmp(k,"dds")) gr->Pmap(*(a[0].d), *(a[1].d), a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Pmap(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Pmap(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Pmap(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Pmap(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_stfa(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddn")) gr->STFA(*(a[0].d),*(a[1].d), mgl_int(a[2].v), "",opt); else if(!strcmp(k,"ddns")) gr->STFA(*(a[0].d),*(a[1].d), mgl_int(a[2].v), a[3].s.s,opt); else if(!strcmp(k,"ddddn")) gr->STFA(*(a[0].d),*(a[1].d), *(a[2].d),*(a[3].d), mgl_int(a[4].v), "",opt); else if(!strcmp(k,"ddddns")) gr->STFA(*(a[0].d),*(a[1].d), *(a[2].d),*(a[3].d), mgl_int(a[4].v), a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surf(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Surf(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Surf(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Surf(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Surf(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surfc(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->SurfC(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->SurfC(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->SurfC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->SurfC(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surfa(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->SurfA(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->SurfA(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->SurfA(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->SurfA(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surfca(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->SurfCA(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->SurfCA(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"ddddd")) gr->SurfCA(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds"))gr->SurfCA(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tile(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Tile(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Tile(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Tile(*(a[0].d), *(a[1].d), *(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Tile(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Tile(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Tile(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tiles(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->TileS(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->TileS(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->TileS(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->TileS(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->TileS(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds")) gr->TileS(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_triplot(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->TriPlot(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->TriPlot(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->TriPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->TriPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->TriPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds"))gr->TriPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_quadplot(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->QuadPlot(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->QuadPlot(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->QuadPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->QuadPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->QuadPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds"))gr->QuadPlot(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tricont(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dddd")) gr->TriCont(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->TriCont(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->TriContV(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds")) gr->TriContV(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else if(!strcmp(k,"dddddd")) gr->TriCont(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"dddddds")) gr->TriCont(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tricontv(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dddd")) gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds")) gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else if(!strcmp(k,"dddddd")) gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"dddddds")) gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- // 3D //----------------------------------------------------------------------------- int static mgls_beam(mglGraph *gr, long , mglArg *a, const char *k, const char *) // NOTE beam can be made obsolete ??? { int res=0; if(!strcmp(k,"ddddn")) gr->Beam(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].v,"",0, 3); else if(!strcmp(k,"ddddns")) gr->Beam(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].v,a[5].s.s,0, 3); else if(!strcmp(k,"ddddnsn")) gr->Beam(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].v,a[5].s.s,mgl_int(a[6].v), 3); else if(!strcmp(k,"ddddnsnn")) gr->Beam(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].v,a[5].s.s,mgl_int(a[6].v), mgl_int(a[7].v)); else if(!strcmp(k,"nddddn")) gr->Beam(a[0].v,*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].v,"",0); else if(!strcmp(k,"nddddns")) gr->Beam(a[0].v,*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].v,a[6].s.s,0); else if(!strcmp(k,"nddddnsn")) gr->Beam(a[0].v,*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].v,a[6].s.s,mgl_int(a[7].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cloud(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Cloud(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Cloud(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dddd")) gr->Cloud(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Cloud(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cont3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Cont3(*(a[0].d), "", -1,opt); else if(!strcmp(k,"ds")) gr->Cont3(*(a[0].d), a[1].s.s, -1,opt); else if(!strcmp(k,"dsn")) gr->Cont3(*(a[0].d), a[1].s.s, mgl_int(a[2].v),opt); else if(!strcmp(k,"dd")) gr->Cont3(*(a[0].d), *(a[1].d), "", -1,opt); else if(!strcmp(k,"dds")) gr->Cont3(*(a[0].d), *(a[1].d), a[2].s.s,-1,opt); else if(!strcmp(k,"ddsn")) gr->Cont3(*(a[0].d), *(a[1].d), a[2].s.s,mgl_int(a[3].v),opt); else if(!strcmp(k,"dddd")) gr->Cont3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "", -1,opt); else if(!strcmp(k,"dddds")) gr->Cont3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,-1,opt); else if(!strcmp(k,"ddddsn")) gr->Cont3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,mgl_int(a[5].v),opt); else if(!strcmp(k,"ddddd")) gr->Cont3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), "", -1,opt); else if(!strcmp(k,"ddddds")) gr->Cont3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s,-1,opt); else if(!strcmp(k,"dddddsn"))gr->Cont3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s,mgl_int(a[6].v),opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contf3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContF3(*(a[0].d), "", -1,opt); else if(!strcmp(k,"ds")) gr->ContF3(*(a[0].d), a[1].s.s, -1,opt); else if(!strcmp(k,"dsn")) gr->ContF3(*(a[0].d), a[1].s.s, mgl_int(a[2].v),opt); else if(!strcmp(k,"dd")) gr->ContF3(*(a[0].d), *(a[1].d), "", -1,opt); else if(!strcmp(k,"dds")) gr->ContF3(*(a[0].d), *(a[1].d), a[2].s.s,-1,opt); else if(!strcmp(k,"ddsn")) gr->ContF3(*(a[0].d), *(a[1].d), a[2].s.s,mgl_int(a[3].v),opt); else if(!strcmp(k,"dddd")) gr->ContF3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), "", -1,opt); else if(!strcmp(k,"dddds")) gr->ContF3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,-1,opt); else if(!strcmp(k,"ddddsn")) gr->ContF3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), a[4].s.s,mgl_int(a[5].v),opt); else if(!strcmp(k,"ddddd")) gr->ContF3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), "", -1,opt); else if(!strcmp(k,"ddddds")) gr->ContF3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s,-1,opt); else if(!strcmp(k,"dddddsn"))gr->ContF3(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.s,mgl_int(a[6].v),opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contx(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContX(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->ContX(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->ContX(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contfx(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContFX(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->ContFX(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->ContFX(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_conty(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContY(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->ContY(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->ContY(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contfy(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContFY(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->ContFY(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->ContFY(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contz(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContZ(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->ContZ(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->ContZ(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_contfz(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->ContFZ(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->ContFZ(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->ContFZ(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_crust(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->Crust(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Crust(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_dens3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Dens3(*(a[0].d),"",-1,opt); else if(!strcmp(k,"ds")) gr->Dens3(*(a[0].d),a[1].s.s,-1,opt); else if(!strcmp(k,"dsn")) gr->Dens3(*(a[0].d),a[1].s.s,mgl_int(a[2].v),opt); else if(!strcmp(k,"dddd")) gr->Dens3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"", -1,opt); else if(!strcmp(k,"dddds")) gr->Dens3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,-1,opt); else if(!strcmp(k,"ddddsn")) gr->Dens3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,mgl_int(a[5].v),opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_densx(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->DensX(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->DensX(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->DensX(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_densy(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->DensY(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->DensY(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->DensY(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_densz(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->DensZ(*(a[0].d),"",NAN,opt); else if(!strcmp(k,"ds")) gr->DensZ(*(a[0].d),a[1].s.s,NAN,opt); else if(!strcmp(k,"dsn")) gr->DensZ(*(a[0].d),a[1].s.s,a[2].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_dots(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->Dots(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Dots(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Dots(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Dots(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"ddddd")) gr->Dots(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"ddddds"))gr->Dots(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_grid3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Grid3(*(a[0].d),"",-1,opt); else if(!strcmp(k,"ds")) gr->Grid3(*(a[0].d),a[1].s.s,-1,opt); else if(!strcmp(k,"dsn")) gr->Grid3(*(a[0].d),a[1].s.s,mgl_int(a[2].v),opt); else if(!strcmp(k,"dddd")) gr->Grid3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",-1,opt); else if(!strcmp(k,"dddds")) gr->Grid3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,-1,opt); else if(!strcmp(k,"ddddsn"))gr->Grid3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,mgl_int(a[5].v),opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surf3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Surf3(*(a[0].d),"",opt); else if(!strcmp(k,"ds")) gr->Surf3(*(a[0].d),a[1].s.s,opt); else if(!strcmp(k,"dn")) gr->Surf3(a[1].v,*(a[0].d),"",opt); else if(!strcmp(k,"dns")) gr->Surf3(a[1].v,*(a[0].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->Surf3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Surf3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); else if(!strcmp(k,"ddddn")) gr->Surf3(a[4].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"ddddns"))gr->Surf3(a[4].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[5].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surf3c(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Surf3C(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Surf3C(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddn")) gr->Surf3C(a[2].v,*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"ddns")) gr->Surf3C(a[2].v,*(a[0].d),*(a[1].d),a[3].s.s,opt); else if(!strcmp(k,"ddddd")) gr->Surf3C(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d), "",opt); else if(!strcmp(k,"ddddds")) gr->Surf3C(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d), a[5].s.s,opt); else if(!strcmp(k,"dddddn")) gr->Surf3C(a[5].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"dddddns")) gr->Surf3C(a[5].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surf3a(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Surf3A(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Surf3A(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddn")) gr->Surf3A(a[2].v,*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"ddns")) gr->Surf3A(a[2].v,*(a[0].d),*(a[1].d),a[3].s.s,opt); else if(!strcmp(k,"ddddd")) gr->Surf3A(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d), "",opt); else if(!strcmp(k,"ddddds")) gr->Surf3A(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d), a[5].s.s,opt); else if(!strcmp(k,"dddddn")) gr->Surf3A(a[5].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt); else if(!strcmp(k,"dddddns")) gr->Surf3A(a[5].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_surf3ca(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->Surf3CA(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Surf3CA(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddn")) gr->Surf3CA(a[4].v,*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"dddns")) gr->Surf3CA(a[4].v,*(a[0].d),*(a[1].d),*(a[2].d),a[4].s.s,opt); else if(!strcmp(k,"dddddd")) gr->Surf3CA(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d), "",opt); else if(!strcmp(k,"dddddds")) gr->Surf3CA(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d), a[6].s.s,opt); else if(!strcmp(k,"ddddddn")) gr->Surf3CA(a[6].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"ddddddns")) gr->Surf3CA(a[6].v,*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[7].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- // Vect //----------------------------------------------------------------------------- int static mgls_dew(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Dew(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Dew(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"dddd")) gr->Dew(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Dew(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_flow(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Flow(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Flow(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Flow(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Flow(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Flow(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Flow(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"dddddd")) gr->Flow(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"dddddds")) gr->Flow(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else if(!strcmp(k,"nndd")) gr->FlowP(mglPoint(a[0].v,a[1].v,NAN), *(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"nndds")) gr->FlowP(mglPoint(a[0].v,a[1].v,NAN), *(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"nndddd")) gr->FlowP(mglPoint(a[0].v,a[1].v,NAN), *(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"nndddds")) gr->FlowP(mglPoint(a[0].v,a[1].v,NAN), *(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else if(!strcmp(k,"nnnddd")) gr->FlowP(mglPoint(a[0].v,a[1].v,a[2].v), *(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"nnnddds")) gr->FlowP(mglPoint(a[0].v,a[1].v,a[2].v), *(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else if(!strcmp(k,"nnndddddd")) gr->FlowP(mglPoint(a[0].v,a[1].v,a[2].v), *(a[3].d),*(a[4].d),*(a[5].d),*(a[6].d),*(a[7].d),*(a[8].d),"",opt); else if(!strcmp(k,"nnndddddds")) gr->FlowP(mglPoint(a[0].v,a[1].v,a[2].v), *(a[3].d),*(a[4].d),*(a[5].d),*(a[6].d),*(a[7].d),*(a[8].d),a[9].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_flow3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->Flow3(*(a[0].d),*(a[1].d),*(a[2].d),"",-1,opt); else if(!strcmp(k,"ddds")) gr->Flow3(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,-1,opt); else if(!strcmp(k,"dddsn")) gr->Flow3(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,a[4].v,opt); else if(!strcmp(k,"dddddd")) gr->Flow3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",-1,opt); else if(!strcmp(k,"dddddds")) gr->Flow3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,-1,opt); else if(!strcmp(k,"ddddddsn")) gr->Flow3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,a[7].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_grad(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"d")) gr->Grad(*(a[0].d), "",opt); else if(!strcmp(k,"ds")) gr->Grad(*(a[0].d), a[1].s.s,opt); else if(!strcmp(k,"ddd")) gr->Grad(*(a[0].d),*(a[1].d),*(a[2].d), "",opt); else if(!strcmp(k,"ddds")) gr->Grad(*(a[0].d),*(a[1].d),*(a[2].d), a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Grad(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt); else if(!strcmp(k,"dddds")) gr->Grad(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_pipe(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Pipe(*(a[0].d),*(a[1].d),"",0.05,opt); else if(!strcmp(k,"dds")) gr->Pipe(*(a[0].d),*(a[1].d),a[2].s.s,0.05,opt); else if(!strcmp(k,"ddsn")) gr->Pipe(*(a[0].d),*(a[1].d),a[2].s.s,a[3].v,opt); else if(!strcmp(k,"dddd")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",0.05,opt); else if(!strcmp(k,"dddds")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,0.05,opt); else if(!strcmp(k,"ddddsn")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,a[5].v,opt); else if(!strcmp(k,"ddd")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),"",0.05,opt); else if(!strcmp(k,"ddds")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,0.05,opt); else if(!strcmp(k,"dddsn")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,a[4].v,opt); else if(!strcmp(k,"dddddd")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",0.05,opt); else if(!strcmp(k,"dddddds")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,0.05,opt); else if(!strcmp(k,"ddddddsn")) gr->Pipe(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,a[7].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_traj(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dddd")) gr->Traj(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Traj(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"dddddd")) gr->Traj(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"dddddds")) gr->Traj(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_vect(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"dd")) gr->Vect(*(a[0].d),*(a[1].d),"",opt); else if(!strcmp(k,"dds")) gr->Vect(*(a[0].d),*(a[1].d),a[2].s.s,opt); else if(!strcmp(k,"ddd")) gr->Vect(*(a[0].d),*(a[1].d),*(a[2].d),"",opt); else if(!strcmp(k,"ddds")) gr->Vect(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,opt); else if(!strcmp(k,"dddd")) gr->Vect(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt); else if(!strcmp(k,"dddds")) gr->Vect(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.s,opt); else if(!strcmp(k,"dddddd")) gr->Vect(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt); else if(!strcmp(k,"dddddds")) gr->Vect(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,opt); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_vect3(mglGraph *gr, long , mglArg *a, const char *k, const char *opt) { int res=0; if(!strcmp(k,"ddd")) gr->Vect3(*(a[0].d),*(a[1].d),*(a[2].d),"",-1,opt); else if(!strcmp(k,"ddds")) gr->Vect3(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,-1,opt); else if(!strcmp(k,"dddsn")) gr->Vect3(*(a[0].d),*(a[1].d),*(a[2].d),a[3].s.s,a[4].v,opt); else if(!strcmp(k,"dddddd")) gr->Vect3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",-1,opt); else if(!strcmp(k,"dddddds")) gr->Vect3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,-1,opt); else if(!strcmp(k,"ddddddsn")) gr->Vect3(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.s,a[7].v,opt); else res = 1; return res; } //----------------------------------------------------------------------------- mglCommand mgls_grf_cmd[] = { {"area",_("Draw area plot for 1D data"),"area Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_area ,7}, {"axial",_("Draw surfaces of contour lines rotation"),"axial Zdat ['fmt' num]|Xdat Ydat Zdat ['fmt' num]", mgls_axial ,8}, {"barh",_("Draw horizontal bars for 1D data"), "barh Ydat ['fmt' above]|Xdat Ydat ['fmt' above]", mgls_barh ,7}, {"bars",_("Draw bars for 1D data"),"bars Ydat ['fmt' above]|Xdat Ydat ['fmt' above]|Xdat Ydat Zdat ['fmt' above]", mgls_bars ,7}, {"beam",_("Draw quasi-optical beam"),"beam Ray G1 G2 Adat r ['sch' flag num]|val Ray G1 G2 Adat r ['sch' flag num]", mgls_beam ,9}, {"belt",_("Draw belts"),"belt Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_belt ,8}, {"beltc",_("Draw belts colored by other data"),"beltc Zdat Cdat ['fmt']|Xdat Ydat Zdat Cdat ['fmt']", mgls_beltc ,8}, {"bifurcation",_("Draw Bifurcation diagram"),"bifurcation dx Func ['fmt']|dx 'func' ['fmt']", mgls_bifurcation,13}, {"boxplot",_("Draw boxplot for 2D data"),"boxplot Ydat ['fmt']|Xdat Ydat ['fmt']", mgls_boxplot ,7}, {"boxs",_("Draw boxes"),"boxs Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_boxs ,8}, {"candle",_("Draw candlestick chart"),"candle candle Vdat1 ['fmt']|Vdat1 Vdat2 ['fmt']|Vdat1 Ydat1 Ydat2 ['fmt']||Vdat1 Vdat2 Ydat1 Ydat2 ['fmt']|Xdat Vdat1 Vdat2 Ydat1 Ydat2 ['fmt']", mgls_candle ,7}, {"chart",_("Draw chart"),"chart Dat ['fmt']", mgls_chart ,7}, {"cloud",_("Draw cloud"),"cloud Adat ['fmt']|Xdat Ydat Zdat Adat ['fmt']", mgls_cloud ,9}, {"cones",_("Draw cones for 1D data"),"cones Ydat ['fmt' above]|Xdat Ydat ['fmt' above]|Xdat Ydat Zdat ['fmt' above]", mgls_cones ,7}, {"cont",_("Draw contour lines"),"cont Zdat ['fmt']|Vdat Zdat ['fmt']|Xdat Ydat Zdat ['fmt']|Vdat Xdat Ydat Zdat ['fmt']|val Adat Xdat Ydat Zdat ['fmt']", mgls_cont ,8}, {"cont3",_("Draw contour lines for 3D data"),"cont3 Adat 'dir' [val 'fmt' num]|Vdat Adat 'dir' [val 'fmt']|Xdat Ydat Zdat Adat 'dir' [val 'fmt' num]|Vdat Xdat Ydat Zdar Adat 'dir' [val 'fmt']", mgls_cont3 ,9}, {"contd",_("Draw solid contours with manual colors"),"contd Zdat ['fmt']|Vdat Zdat ['fmt']|Xdat Ydat Zdat ['fmt']|Vdat Xdat Ydat Zdat ['fmt']", mgls_contd ,8}, {"contf",_("Draw solid contours"),"contf Zdat ['fmt']|Vdat Zdat ['fmt']|Xdat Ydat Zdat ['fmt']|Vdat Xdat Ydat Zdat ['fmt']|v1 v2 Adat Xdat Ydat Zdat ['fmt']", mgls_contf ,8}, {"contf3",_("Draw solid contour lines for 3D data"),"contf3 Adat 'dir' [val 'fmt' num]|Vdat Adat 'dir' [val 'fmt']|Xdat Ydat Zdat Adat 'dir' [val 'fmt' num]|Vdat Xdat Ydat Zdar Adat 'dir' [val 'fmt']", mgls_contf3 ,9}, {"contfx",_("Draw solid contour lines at x-slice (or x-plane)"),"contfx Dat ['fmt' pos num]", mgls_contfx ,0}, {"contfy",_("Draw solid contour lines at y-slice (or y-plane)"),"contfy Dat ['fmt' pos num]", mgls_contfy ,0}, {"contfz",_("Draw solid contour lines at z-slice (or z-plane)"),"contfz Dat ['fmt' pos num]", mgls_contfz ,0}, {"contp",_("Draw contour lines on parametric surface"),"contp Xdat Ydat Zdat Adat ['fmt' num zpos]|Vdat Xdat Ydat Zdat Adat ['fmt' zpos]", mgls_contp ,8}, {"contv",_("Draw contour tubes"),"contv Zdat ['fmt' num zpos]|Vdat Zdat ['fmt' zpos]|Xdat Ydat Zdat ['fmt' num zpos]|Vdat Xdat Ydat Zdat ['fmt' zpos]", mgls_contv ,0}, {"contx",_("Draw contour lines at x-slice (or x-plane)"),"contx Dat ['fmt' pos num]", mgls_contx ,0}, {"conty",_("Draw contour lines at y-slice (or y-plane)"),"conty Dat ['fmt' pos num]", mgls_conty ,0}, {"contz",_("Draw contour lines at z-slice (or z-plane)"),"contz Dat ['fmt' pos num]", mgls_contz ,0}, {"crust",_("Draw reconstructed surface for arbitrary data points"),"crust Xdat Ydat Zdat ['fmt']", mgls_crust ,0}, {"dens",_("Draw density plot"),"dens Zdat ['fmt' zpos]|Xdat Ydat Zdat ['fmt' zpos]", mgls_dens ,8}, {"dens3",_("Draw density plot at slices of 3D data"),"dens3 Adat 'dir' [pos 'fmt']|Xdat Ydat Zdat Adat 'dir' [pos 'fmt']", mgls_dens3 ,9}, {"densx",_("Draw density plot at x-slice (or x-plane)"),"densx Dat ['fmt' pos]", mgls_densx ,0}, {"densy",_("Draw density plot at y-slice (or y-plane)"),"densy Dat ['fmt' pos]", mgls_densy ,0}, {"densz",_("Draw density plot at z-slice (or z-plane)"),"densz Dat ['fmt' pos]", mgls_densz ,0}, {"dew",_("Draw dew plot"),"dew Udat Vdat ['fmt']|Xdat Ydat Udat Vdat ['fmt']", mgls_dew ,11}, {"dots",_("Draw dots for arbitrary data points"),"dots Xdat Ydat Zdat ['fmt']|Xdat Ydat Zdat Adat ['fmt']|Xdat Ydat Zdat Cdat Adat ['fmt']", mgls_dots ,9}, {"error",_("Draw error boxes"),"error Ydat Yerr ['fmt']|Xdat Ydat Yerr ['fmt']|Xdat Ydat Xerr Yerr ['fmt']", mgls_error ,7}, {"fall",_("Draw waterfalls"),"fall Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_fall ,8}, {"flow",_("Draw flow threads for vector field"),"flow Udat Vdat ['fmt']|Xdat Ydat Udat Vdat ['fmt']|Udat Vdat Wdat ['fmt']|Xdat Ydat Zdat Udat Vdat Wdat ['fmt']|\ x0 y0 Udat Vdat ['fmt']|x0 y0 Xdat Ydat Udat Vdat ['fmt']|x0 y0 z0 Udat Vdat Wdat ['fmt']|x0 y0 z0 Xdat Ydat Zdat Udat Vdat Wdat ['fmt']", mgls_flow ,11}, {"flow3",_("Draw flow threads from plain for vector field"),"flow3 Udat Udat Vdat Wdat ['fmt' num]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' num]", mgls_flow3 ,11}, {"grad",_("Draw gradient lines for scalar field"),"grad Phi ['fmt' num]|Xdat Ydat Phi ['fmt' num]|Xdat Ydat Zdat Phi ['fmt' num]", mgls_grad ,8}, {"grid2",_("Draw grid for data array(s)"),"grid2 Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_grid2 ,8}, {"grid3",_("Draw grid at slices of 3D data"),"grid3 Adat 'dir' [pos 'fmt']|Xdat Ydat Zdat Adat 'dir' [pos 'fmt']", mgls_grid3 ,9}, {"iris",_("Draw Iris plots"),"iris Dats 'ids' ['fmt']|Dats Ranges 'ids' ['fmt']", mgls_iris,13}, {"label",_("Draw label at arbitrary position"),"label Ydat 'txt' ['fmt'='']|Xdat Ydat 'txt' ['fmt'='']|Xdat Ydat Zdat 'txt' ['fmt'='']", mgls_label ,7}, {"lamerey",_("Draw Lamerey diagram"),"lamerey x0 Func ['fmt']|x0 'func' ['fmt']", mgls_lamerey ,13}, {"map",_("Draw mapping plot"),"map Udat Vdat ['fmt']|Xdat Ydat Udat Vdat ['fmt']", mgls_map ,10}, {"mark",_("Draw mark plot for 1D data"),"mark Ydat Rdat ['fmt']|Xdat Ydat Rdat ['fmt']|Xdat Ydat Zdat Rdat ['fmt']", mgls_mark ,7}, {"mesh",_("Draw mesh surface"),"mesh Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_mesh ,8}, {"ohlc",_("Draw Open-High-Low-Close (OHLC) diagram"),"ohlc Odat Hdat Ldat Cdat ['fmt']|Xdat Odat Hdat Ldat Cdat ['fmt']", mgls_ohlc ,7}, {"pipe",_("Draw flow pipes for vector field"),"pipe Udat Vdat ['fmt' rad num]|Xdat Ydat Udat Vdat ['fmt' rad num]|Udat Vdat Wdat ['fmt' rad num]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' rad num]", mgls_pipe ,11}, {"plot",_("Draw usual plot for 1D data"),"plot Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_plot ,7}, {"pmap",_("Draw Poincare map"),"pmap Ydat Rdat ['fmt']|Xdat Ydat Rdat ['fmt']|Xdat Ydat Zdat Rdat ['fmt']", mgls_pmap ,7}, {"quadplot",_("Draw surface of quadrangles"),"quadplot Idat Xdat Ydat ['fmt']|Idat Xdat Ydat Zdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt'] ", mgls_quadplot ,0}, {"radar",_("Draw radar chart"),"radar Rdat ['fmt']", mgls_radar ,7}, {"region",_("Draw filled region (ribbon) between 2 curves"),"region Ydat1 Ydat2 ['fmt']|Xdat Ydat1 Ydat2 ['fmt']||Xdat1 Ydat1 Xdat2 Ydat2 ['fmt']|Xdat1 Ydat1 Zdat1 Xdat2 Ydat2 Zdat2 ['fmt']", mgls_region ,7}, {"stem",_("Draw stem plot for 1D data"),"stem Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_stem ,7}, {"step",_("Draw step plot for 1D data"),"step Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_step ,7}, {"stfa",_("Draw STFA diagram"),"stfa Udat Vdat dn ['fmt']|Xdat Ydat Udat Vdat dn ['fmt']", mgls_stfa ,10}, {"surf",_("Draw solid surface"),"surf Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_surf ,8}, {"surf3",_("Draw isosurface for 3D data"),"surf3 Adat ['fmt' num]|Xdat Ydat Zdat Adat ['fmt' num]|Adat val ['fmt']|Xdat Ydat Zdat Adat val ['fmt']", mgls_surf3 ,9}, {"surf3a",_("Draw isosurface for 3D data transpared by other data"),"surf3a Adat Cdat ['fmt' num]|Xdat Ydat Zdat Adat Cdat ['fmt' num]|Adat Cdat val ['fmt']|Xdat Ydat Zdat Adat Cdat val ['fmt']", mgls_surf3a ,10}, {"surf3c",_("Draw isosurface for 3D data colored by other data"),"surf3c Adat Cdat ['fmt' num]|Xdat Ydat Zdat Adat Cdat ['fmt' num]|Adat Cdat val ['fmt']|Xdat Ydat Zdat Adat Cdat val ['fmt']", mgls_surf3c ,10}, {"surf3ca",_("Draw isosurface for 3D data colored and transpared by other data"),"surf3c Adat Cdat Bdat ['fmt' num]|Xdat Ydat Zdat Adat Cdat Bdat ['fmt' num]|Adat Cdat Bdat val ['fmt']|Xdat Ydat Zdat Adat Cdat Bdat val ['fmt']", mgls_surf3ca ,10}, {"surfa",_("Draw solid surface transpared by other data"),"surfa Zdat Cdat ['fmt']|Xdat Ydat Zdat Cdat ['fmt']", mgls_surfa ,10}, {"surfc",_("Draw solid surface colored by other data"),"surfc Zdat Cdat ['fmt']|Xdat Ydat Zdat Cdat ['fmt']", mgls_surfc ,10}, {"surfca",_("Draw solid surface colored and transpared by other data"),"surfca Zdat Cdat Adat ['fmt']|Xdat Ydat Zdat Cdat Adat ['fmt']", mgls_surfca ,10}, {"table",_("Draw table with data values"),"table Dat ['txt' 'fmt']|x y Dat ['txt' 'fmt']", mgls_table ,7}, {"tape",_("Draw binormales for 1D data"),"tape Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_tape ,7}, {"tens",_("Draw tension plot for 1D data"),"tens Ydat Cdat ['fmt']|Xdat Ydat Cdat ['fmt']|Xdat Ydat Zdat Cdat ['fmt']", mgls_tens ,7}, {"textmark",_("Draw TeX mark at point position"),"textmark Ydat Rdat 'text' ['fmt']|Xdat Ydat Rdat 'text' ['fmt']|Xdat Ydat Zdat Rdat 'text' ['fmt']", mgls_textmark ,7}, {"tile",_("Draw horizontal tiles"),"tile Zdat ['fmt']|Xdat Ydat Zdat ['fmt']|Xdat Ydat Zdat Cdat ['fmt']", mgls_tile ,8}, {"tiles",_("Draw horizontal tiles with variable size"),"tiles Zdat Rdat ['fmt']|Xdat Ydat Zdat Rdat ['fmt']|Xdat Ydat Zdat Rdat Cdat ['fmt']", mgls_tiles ,10}, {"torus",_("Draw surface of curve rotation"),"torus Rdat ['fmt']|Zdat Rdat ['fmt']", mgls_torus ,7}, {"traj",_("Draw vectors along a curve"),"traj Xdat Ydat Udat Vdat ['fmt' len]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' len]", mgls_traj ,11}, {"tricont",_("Draw contour lines for surface of triangles"),"tricont Idat Xdat Ydat Cdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt']|Vdat Idat Xdat Ydat Cdat ['fmt']|Vdat Idat Xdat Ydat Zdat Cdat ['fmt']", mgls_tricont ,0}, {"tricontv",_("Draw contour tubes for surface of triangles"),"tricontv Idat Xdat Ydat Cdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt']|Vdat Idat Xdat Ydat Cdat ['fmt']|Vdat Idat Xdat Ydat Zdat Cdat ['fmt']", mgls_tricontv ,0}, {"triplot",_("Draw surface of triangles"),"triplot Idat Xdat Ydat ['fmt']|Idat Xdat Ydat Zdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt'] ", mgls_triplot ,0}, {"tube",_("Draw curve by tube"),"tube Ydat Rdat ['fmt']|Ydat rval ['fmt']|Xdat Ydat Rdat ['fmt']|Xdat Ydat rval ['fmt']|Xdat Ydat Zdat Rdat ['fmt']|Xdat Ydat Zdat rval ['fmt']", mgls_tube ,7}, {"vect",_("Draw vector field"),"vect Udat Vdat ['fmt']|Xdat Ydat Udat Vdat ['fmt']|Udat Vdat Wdat ['fmt']|Xdat Ydat Zdat Udat Vdat Wdat ['fmt']", mgls_vect ,11}, {"vect3",_("Draw vector field at slices of 3D data"),"vect Udat Vdat Wdat ['fmt' sval]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' sval]", mgls_vect3 ,11}, {"","","",NULL,0}}; //----------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/evalp.cpp��������������������������������������������������������������������������0000644�0001750�0001750�00000126071�13513030041�015556� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * evalp.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "mgl2/base.h" #include "mgl2/parser.h" #if MGL_HAVE_GSL #include #include #endif //----------------------------------------------------------------------------- std::wstring mgl_trim_ws(const std::wstring &str); HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring string, mglParser *arg, const std::vector &head); HADT MGL_NO_EXPORT mglFormulaCalcC(std::wstring string, mglParser *arg, const std::vector &head); //----------------------------------------------------------------------------- HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector &head) { std::wstring s; for(long i=0;str[i];i++) s.push_back(str[i]); return mglFormulaCalc(s,0,head); } //----------------------------------------------------------------------------- HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector &head) { std::wstring s; for(long i=0;str[i];i++) s.push_back(str[i]); return mglFormulaCalcC(s,0,head); } //----------------------------------------------------------------------------- HMDT mglApplyFunc(std::wstring str, mglParser *arg, const std::vector &head, double (*func)(double)) { HMDT d = mglFormulaCalc(str, arg, head); long n = d->GetNN(); mreal *dd=d->a; #pragma omp parallel for for(long i=0;i &head, double (*func)(double, gsl_mode_t)) { HMDT d = mglFormulaCalc(str, arg, head); long n = d->GetNN(); mreal *dd=d->a; #pragma omp parallel for for(long i=0;i &head, double (*func)(double,double)) { HMDT a = mglFormulaCalc(a1,arg,head), b = mglFormulaCalc(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } mreal va=a->a[0], vb=b->a[0], *aa=a->a, *bb=b->a, *cc=r->a; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HMDT a = mglFormulaCalc(a1,arg,head), b = mglFormulaCalc(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } mreal *aa=r->a, *bb=d->a, v=bb[0]; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HMDT a = mglFormulaCalc(a1,arg,head), b = mglFormulaCalc(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } mreal va=a->a[0], vb=b->a[0], *aa=a->a, *bb=b->a, *cc=r->a; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HMDT a = mglFormulaCalc(a1,arg,head), b = mglFormulaCalc(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } mreal *aa=r->a, *bb=d->a, v=bb[0]; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HMDT a = mglFormulaCalc(a1,arg,head), b = mglFormulaCalc(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } mreal va=a->a[0], vb=b->a[0], *aa=a->a, *bb=b->a, *cc=r->a; if(na==nb) #pragma omp parallel for for(long i=0;i &head, dual (*func)(dual)) { HADT d = mglFormulaCalcC(str, arg, head); long n = d->GetNN(); dual *dd=d->a; #pragma omp parallel for for(long i=0;i &head, dual (*func)(dual,dual)) { HADT a = mglFormulaCalcC(a1,arg,head), b = mglFormulaCalcC(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } dual va=a->a[0], vb=b->a[0], *aa=a->a, *bb=b->a, *cc=r->a; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HADT a = mglFormulaCalcC(a1,arg,head), b = mglFormulaCalcC(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } dual *aa=r->a, *bb=d->a, v=bb[0]; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HADT a = mglFormulaCalcC(a1,arg,head), b = mglFormulaCalcC(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } dual va=a->a[0], vb=b->a[0], *aa=a->a, *bb=b->a, *cc=r->a; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HADT a = mglFormulaCalcC(a1,arg,head), b = mglFormulaCalcC(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } dual *aa=r->a, *bb=d->a, v=bb[0]; if(na==nb) #pragma omp parallel for for(long i=0;i &head) { HADT a = mglFormulaCalcC(a1,arg,head), b = mglFormulaCalcC(a2,arg,head), r,d; long na = a->GetNN(), nb = b->GetNN(), nn; if(na!=1) { r=a; d=b; nn=na; } else { r=b; d=a; nn=nb; } dual va=a->a[0], vb=b->a[0], *aa=a->a, *bb=b->a, *cc=r->a; if(na==nb) #pragma omp parallel for for(long i=0;i=0;i--) { if(str[i]=='(') l++; if(str[i]==')') r++; if(l==r && strchr(lst,str[i])) return i; } return -1; } //----------------------------------------------------------------------------- double MGL_LOCAL_CONST cand(double a,double b);// {return a&&b?1:0;} double MGL_LOCAL_CONST cor(double a,double b);// {return a||b?1:0;} double MGL_LOCAL_CONST ceq(double a,double b);// {return a==b?1:0;} double MGL_LOCAL_CONST clt(double a,double b);// {return ab?1:0;} double MGL_LOCAL_CONST stp(double a);// {return a>0?1:0;} double MGL_LOCAL_CONST sgn(double a);// {return a>0?1:(a<0?-1:0);} double MGL_LOCAL_CONST ipw(double a,double b);// {return mgl_ipow(a,int(b));} double MGL_LOCAL_CONST llg(double a,double b);// {return log(a)/log(b);} //double MGL_LOCAL_CONST asinh(double x);// { return log(x+sqrt(x*x+1)); } //double MGL_LOCAL_CONST acosh(double x);// { return x>1 ? log(x+sqrt(x*x-1)) : NAN; } //double MGL_LOCAL_CONST atanh(double x);// { return fabs(x)<1 ? log((1+x)/(1-x))/2 : NAN; } double MGL_LOCAL_CONST gslEllE(double a,double b);// {return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslEllF(double a,double b);// {return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);} double MGL_LOCAL_CONST gslLegP(double a,double b);// {return gsl_sf_legendre_Pl(int(a),b);} double MGL_LOCAL_CONST mgl_asinh(double x); double MGL_LOCAL_CONST mgl_acosh(double x); double MGL_LOCAL_CONST mgl_atanh(double x); double MGL_LOCAL_CONST mgl_fmin(double a,double b); double MGL_LOCAL_CONST mgl_fmax(double a,double b); //----------------------------------------------------------------------------- // It seems that standard wcstombs() have a bug. So, I replace by my own. void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size) { int j; for(j=0;j &head, const std::wstring &name) { for(size_t i=0;iName()==name) return head[i]; return 0; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_wcslwr(wchar_t *str) { size_t l=mgl_wcslen(str); for(size_t k=0;k='A' && str[k]<='Z') ? str[k]+'a'-'A' : str[k]; } //----------------------------------------------------------------------------- mreal mgl_gettime(const std::wstring &s) { mreal t=NAN; tm a; memset(&a,0,sizeof(tm)); if(swscanf(s.c_str(),L"%u-%u-%u_%u.%u.%d", &a.tm_hour,&a.tm_min,&a.tm_sec, &a.tm_mday,&a.tm_mon,&a.tm_year)==6) { a.tm_year-=1900; a.tm_mon -= 1; if(a.tm_hour<24 && a.tm_min<60 && a.tm_sec<60 && a.tm_mday>0 && a.tm_mday<32 && a.tm_mon<12) t = mktime(&a); } else if(swscanf(s.c_str(),L"%d.%d.%d", &a.tm_mday,&a.tm_mon,&a.tm_year)==3) { a.tm_year-=1900; a.tm_mon -= 1; if(a.tm_mday>0 && a.tm_mday<32 && a.tm_mon<12) t = mktime(&a); } else if(swscanf(s.c_str(),L"%d-%d-%d", &a.tm_hour,&a.tm_min,&a.tm_sec)==3) { a.tm_mday=1; a.tm_mon=0; a.tm_year=70; if(a.tm_hour<24 && a.tm_min<60 && a.tm_sec<60) t = mktime(&a); } return t; } //----------------------------------------------------------------------------- /// Parse string and substitute the script argument // All numbers are presented as mglData(1). Do boundary checking. // NOTE: In any case where number is required the mglData::a[0] is used. // String flag is binary 0x1 -> 'x', 0x2 -> 'y', 0x4 -> 'z' HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std::vector &head) { #if MGL_HAVE_GSL gsl_set_error_handler_off(); #endif if(str.empty()) return new mglData; // nothing to parse str = mgl_trim_ws(str); mreal tval = mgl_gettime(str); if(mgl_isnum(tval)) { mglData *r=new mglData; r->a[0] = tval; return r; } long n,len=str.length(); if(str[0]=='(' && mglCheck(str.substr(1,len-2))) // remove braces { str = str.substr(1,len-2); len-=2; } if(str[0]==':' && str[1]!=0) // this data file { size_t l=str.length()+1; char *buf = new char[l]; memset(buf,0,l); for(size_t i=1;str[i]!=0 && str[i]!=':' && i0) br--; if(str[i]==',' && !br) { HMDT a1=mglFormulaCalc(str.substr(j,i-j), arg, head); if(j==1) { res = a1; ar = (a1->nx==1); mt = (a1->nx>1 && a1->ny==1); } else { if(ar) // res 1d array { k = res->nx; res->Insert('x',k); mgl_data_put_dat(res,a1,k,-1,-1); } else if(mt) // res 2d array { k = res->ny; res->Insert('y',k); mgl_data_put_dat(res,a1,-1,k,-1); } else // res 3d array { k = res->nz; res->Insert('z',k); mgl_data_put_dat(res,a1,-1,-1,k); } mgl_delete_data(a1); } j=i+1; } } HMDT a1=mglFormulaCalc(str.substr(j,i-j), arg, head); if(j==1) { res = a1; ar = (a1->nx==1); mt = (a1->nx>1 && a1->ny==1); } else { if(ar) // res 1d array { k = res->nx; res->Insert('x',k); mgl_data_put_dat(res,a1,k,-1,-1); } else if(mt) // res 2d array { k = res->ny; res->Insert('y',k); mgl_data_put_dat(res,a1,-1,k,-1); } else // res 3d array { k = res->nz; res->Insert('z',k); mgl_data_put_dat(res,a1,-1,-1,k); } mgl_delete_data(a1); } return res; } n=mglFindInText(str,"&|"); // lowest priority -- logical if(n>=0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, str[n]=='|'?cor:cand); n=mglFindInText(str,"<>="); // low priority -- conditions if(n>=0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, str[n]=='<'?clt:(str[n]=='>'?cgt:ceq)); n=mglFindInText(str,"+-"); // normal priority -- additions if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2])) )) return str[n]=='+'? mglApplyOperAdd(str.substr(0,n),str.substr(n+1),arg, head) : mglApplyOperSub(str.substr(0,n),str.substr(n+1),arg, head); n=mglFindInText(str,"*/%"); // high priority -- multiplications if(n>=0) return str[n]=='*'? mglApplyOperMul(str.substr(0,n),str.substr(n+1),arg, head) : (str[n]=='/'? mglApplyOperDiv(str.substr(0,n),str.substr(n+1),arg, head) : mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, fmod)); n=mglFindInText(str,"@"); // high priority -- combine if(n>=0) { HMDT a1 = mglFormulaCalc(str.substr(0,n),arg, head); HMDT a2 = mglFormulaCalc(str.substr(n+1),arg, head); HMDT res = mgl_data_combine(a1,a2); mgl_delete_data(a1); mgl_delete_data(a2); return res?res:new mglData; } n=mglFindInText(str,"^"); // highest priority -- power if(n>=0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, ipw); n=mglFindInText(str,":"); // highest priority -- array if(n>=0 && str.compare(L":")) { HMDT a1=mglFormulaCalc(str.substr(0,n), arg, head); HMDT a2=mglFormulaCalc(str.substr(n+1), arg, head); HMDT res = new mglData(abs(int(a2->a[0]+0.5)-int(a1->a[0]+0.5))+1); res->Fill(a1->a[0], a2->a[0]); mgl_delete_data(a1); mgl_delete_data(a2); return res; } n=mglFindInText(str,"."); // highest priority -- suffixes wchar_t c0 = str[n+1]; if(n>=0 && c0>='a' && c0!='e') { mreal x,y,z,k,v=NAN; HMDT d = mglFormulaCalc(str.substr(0,n), arg, head); long ns[3] = {d->nx-1, d->ny-1, d->nz-1}; const std::wstring &p=str.substr(n+1); wchar_t ch = p[1]; if(c0=='a') { if(ch==0) v = d->a[0]; else { d->Momentum(ch,x,y); if(ch=='a') v = x; else if(ch>='x' && ch<='z') v = x/ns[ch-'x']; } } else if(c0=='n') { if(ch>='x' && ch<='z') v = ns[p[1]-'x']+1; else if(!p.compare(L"nmax")) { v=d->MaximalNeg(); } else if(!p.compare(L"nmin")) { v=d->Minimal(); v = v<0?v:0; } } else if(c0=='k') { d->Momentum(ch,x,y,z,k); if(ch=='a') v = k; else if(ch>='x' && ch<='z') v = k/ns[ch-'x']; } else if(c0=='w') { d->Momentum(ch,x,y); if(ch=='a') v = y; else if(ch>='x' && ch<='z') v = y/ns[ch-'x']; } else if(c0=='m') { if(ch=='a' && p[2]=='x') v = d->Maximal(); else if(ch=='i' && p[2]=='n') v = d->Minimal(); else if(ch=='x' && p[2]=='f') v = d->Maximal('x',0)/mreal(ns[0]); else if(ch=='x' && p[2]=='l') v = d->Maximal('x',-1)/mreal(ns[0]); else if(ch=='x') { d->Maximal(x,y,z); v = x/ns[0]; } else if(ch=='y' && p[2]=='f') v = d->Maximal('y',0)/mreal(ns[1]); else if(ch=='y' && p[2]=='l') v = d->Maximal('y',-1)/mreal(ns[1]); else if(ch=='y') { d->Maximal(x,y,z); v = y/ns[1]; } else if(ch=='z' && p[2]=='f') v = d->Maximal('z',0)/mreal(ns[2]); else if(ch=='z' && p[2]=='l') v = d->Maximal('z',-1)/mreal(ns[2]); else if(ch=='z') { d->Maximal(x,y,z); v = z/ns[2]; } } else if(c0=='s') { if(ch=='u' && p[2]=='m') v = d->Momentum('x',x,y); else if(ch=='a') { d->Momentum(ch,x,y,z,k); v = z; } else if(ch>='x' && ch<='z') { d->Momentum(ch,x,y,z,k); v = z/ns[ch-'x']; } } else if(!p.compare(L"fst")) { long i=-1,j=-1,l=-1; v = d->Find(0,i,j,l); } else if(!p.compare(L"lst")) { long i=-1,j=-1,l=-1; v = d->Last(0,i,j,l); } else if(!p.compare(L"pmax")) { v=d->Maximal(); v = v>0?v:0; } else if(!p.compare(L"pmin")) { v=d->MinimalPos(); } delete d; // if this is valid suffix when finish parsing (it can be mreal number) if(mgl_isfin(v)) { HMDT res = new mglData; res->a[0]=v; return res; } } if(str[0]=='`') { HMDT res = mglFormulaCalc(str.substr(1), arg, head); res->Transpose(); return res; } for(n=0;n=len) // this is number or variable { HCDT v = (str!=L"#$mgl")?FindVar(head, str):0; if(v) return new mglData(v); const mglNum *f = arg?arg->FindNum(str.c_str()):0; if(f) { HMDT res = new mglData; res->a[0] = f->d; return res; } else if(!str.compare(L"rnd")) { v=FindVar(head, L"#$mgl"); HMDT res = v?new mglData(v->GetNx(),v->GetNy(),v->GetNz()) : new mglData; for(long i=0;iGetNN();i++) res->a[i] = mgl_rnd(); return res; } else { HMDT res = new mglData; wchar_t ch = str[0]; if(ch<':') res->a[0] = wcstod(str.c_str(),0); // this is number else if(!str.compare(L"pi")) res->a[0] = M_PI; else if(ch==':') res->a[0] = -1; else if(!str.compare(L"nan")) res->a[0] = NAN; else if(!str.compare(L"inf")) res->a[0] = INFINITY; return res; } } else { std::wstring nm = str.substr(0,n); str = str.substr(n+1,len-n-2); len -= n+2; HCDT v = FindVar(head, nm); HMDT tmp = 0; // mglVar *v = arg->FindVar(nm.c_str()); if(!v && !nm.compare(0,7,L"jacobi_")) nm = nm.substr(7); if(!v && nm.empty()) { long m=mglFindInText(str,")"); if(m>1) { nm = str.substr(0,m); str = str.substr(m+2); tmp = mglFormulaCalc(nm,arg,head); v = tmp; } } n = mglFindInText(str,","); if(v) // subdata { if(str[0]=='\'' && str[len-1]=='\'') // this is column call { char *buf = new char[len]; mgl_wcstombs(buf, str.substr(1).c_str(), len-1); buf[len-1]=0; HMDT res = mgl_data_column(v,buf); if(tmp) mgl_delete_data(tmp); delete []buf; return res?res:new mglData; } else { HMDT a1=0, a2=0, a3=0; if(n>0) { long m=mglFindInText(str.substr(0,n),","); if(m>0) { str[m]=0; a1 = mglFormulaCalc(str.substr(0,m), arg, head); a2 = mglFormulaCalc(str.substr(m+1,n-m-1), arg, head); a3 = mglFormulaCalc(str.substr(n+1), arg, head); } else { a1 = mglFormulaCalc(str.substr(0,n), arg, head); a2 = mglFormulaCalc(str.substr(n+1), arg, head); } } else a1 = mglFormulaCalc(str, arg, head); HMDT res = mgl_data_subdata_ext(v,a1,a2,a3); if(tmp) mgl_delete_data(tmp); mgl_delete_data(a1); mgl_delete_data(a2); mgl_delete_data(a3); return res?res:new mglData; } if(tmp) mgl_delete_data(tmp); } else if(nm[0]=='a') // function { if(!nm.compare(L"asin")) return mglApplyFunc(str, arg, head, asin); else if(!nm.compare(L"acos")) return mglApplyFunc(str, arg, head, acos); else if(!nm.compare(L"atan")) return mglApplyFunc(str, arg, head, atan); else if(!nm.compare(L"asinh")) return mglApplyFunc(str, arg, head, mgl_asinh); else if(!nm.compare(L"acosh")) return mglApplyFunc(str, arg, head, mgl_acosh); else if(!nm.compare(L"atanh")) return mglApplyFunc(str, arg, head, mgl_atanh); else if(!nm.compare(L"arg")) { if(n>0) return mglApplyOper(str.substr(n+1),str.substr(0,n),arg, head, atan2); else { HADT a1 = mglFormulaCalcC(str, arg, head); HMDT res = mgl_datac_arg(a1); mgl_delete_datac(a1); return res; } } else if(!nm.compare(L"abs")) { if(n>0) return mglApplyOper(str.substr(n+1),str.substr(0,n),arg, head, hypot); else { HADT a1 = mglFormulaCalcC(str, arg, head); HMDT res = mgl_datac_abs(a1); mgl_delete_datac(a1); return res; } } #if MGL_HAVE_GSL else if(!nm.compare(L"ai") || !nm.compare(L"airy_ai")) return mglApplyFuncGSL(str, arg, head, gsl_sf_airy_Ai); else if(!nm.compare(L"airy_dai")) return mglApplyFuncGSL(str, arg, head, gsl_sf_airy_Ai_deriv); else if(!nm.compare(L"airy_bi")) return mglApplyFuncGSL(str, arg, head, gsl_sf_airy_Bi); else if(!nm.compare(L"airy_dbi")) return mglApplyFuncGSL(str, arg, head, gsl_sf_airy_Bi_deriv); } else if(nm[0]=='b') { if(!nm.compare(L"beta") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_beta); else if(!nm.compare(L"bi")) return mglApplyFuncGSL(str, arg, head, gsl_sf_airy_Bi); else if(!nm.compare(L"bessel_i") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Inu); else if(!nm.compare(L"bessel_j") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Jnu); else if(!nm.compare(L"bessel_k") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Knu); else if(!nm.compare(L"bessel_y") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Ynu); #endif } else if(nm[0]=='c') { if(!nm.compare(L"cos")) return mglApplyFunc(str, arg, head, cos); else if(!nm.compare(L"cosh") || !nm.compare(L"ch")) return mglApplyFunc(str, arg, head, cosh); else if(!nm.compare(L"conj")) { HADT a1 = mglFormulaCalcC(str, arg, head); HMDT res = mgl_datac_real(a1); mgl_delete_datac(a1); return res; } #if MGL_HAVE_GSL else if(!nm.compare(L"ci")) return mglApplyFunc(str, arg, head, gsl_sf_Ci); #endif } else if(nm[0]=='e') { if(!nm.compare(L"exp")) return mglApplyFunc(str, arg, head, exp); #if MGL_HAVE_GSL else if(!nm.compare(L"erf")) return mglApplyFunc(str, arg, head, gsl_sf_erf); else if(!nm.compare(L"ee") || !nm.compare(L"elliptic_ec")) return mglApplyFuncGSL(str, arg, head, gsl_sf_ellint_Ecomp); else if(!nm.compare(L"ek") || !nm.compare(L"elliptic_kc")) return mglApplyFuncGSL(str, arg, head, gsl_sf_ellint_Kcomp); else if((!nm.compare(L"e") || !nm.compare(L"elliptic_e")) && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gslEllE); else if(!nm.compare(L"elliptic_f")) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gslEllF); else if(!nm.compare(L"ei")) return mglApplyFunc(str, arg, head, gsl_sf_expint_Ei); else if(!nm.compare(L"e1")) return mglApplyFunc(str, arg, head, gsl_sf_expint_E1); else if(!nm.compare(L"e2")) return mglApplyFunc(str, arg, head, gsl_sf_expint_E2); else if(!nm.compare(L"eta")) return mglApplyFunc(str, arg, head, gsl_sf_eta); else if(!nm.compare(L"ei3")) return mglApplyFunc(str, arg, head, gsl_sf_expint_3); #endif } else if(nm[0]=='l') { if(!nm.compare(L"log") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, llg); else if(!nm.compare(L"lg")) return mglApplyFunc(str, arg, head, log10); else if(!nm.compare(L"ln")) return mglApplyFunc(str, arg, head, log); #if MGL_HAVE_GSL else if(!nm.compare(L"li2")) return mglApplyFunc(str, arg, head, gsl_sf_dilog); else if(!nm.compare(L"legendre") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gslLegP); #endif } else if(nm[0]=='s') { if(!nm.compare(L"sqrt")) return mglApplyFunc(str, arg, head, sqrt); else if(!nm.compare(L"sin")) return mglApplyFunc(str, arg, head, sin); else if(!nm.compare(L"step")) return mglApplyFunc(str, arg, head, stp); else if(!nm.compare(L"sign")) return mglApplyFunc(str, arg, head, sgn); else if(!nm.compare(L"sinh") || !nm.compare(L"sh")) return mglApplyFunc(str, arg, head, sinh); #if MGL_HAVE_GSL else if(!nm.compare(L"si")) return mglApplyFunc(str, arg, head, gsl_sf_Si); else if(!nm.compare(L"sinc")) return mglApplyFunc(str, arg, head, gsl_sf_sinc); #endif } else if(nm[0]=='t') { if(!nm.compare(L"tg") || !nm.compare(L"tan")) return mglApplyFunc(str, arg, head, tan); else if(!nm.compare(L"tanh") || !nm.compare(L"th")) return mglApplyFunc(str, arg, head, tanh); } else if(!nm.compare(L"pow") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, pow); else if(nm[0]=='m') { if(!nm.compare(L"mod") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, fmod); else if(!nm.compare(L"min") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, mgl_fmin); else if(!nm.compare(L"max") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, mgl_fmax); } else if(!nm.compare(L"int")) return mglApplyFunc(str, arg, head, floor); else if(!nm.compare(L"random")) { HMDT res=mglFormulaCalc(str, arg, head); mreal *a = res->a; for(long i=0;iGetNN();i++) a[i] = mgl_rnd(); return res; } else if(!nm.compare(L"real")) { HADT a1 = mglFormulaCalcC(str, arg, head); HMDT res = mgl_datac_real(a1); mgl_delete_datac(a1); return res; } else if(!nm.compare(L"imag")) { HADT a1 = mglFormulaCalcC(str, arg, head); HMDT res = mgl_datac_imag(a1); mgl_delete_datac(a1); return res; } else if(!nm.compare(L"norm")) { HADT a1 = mglFormulaCalcC(str, arg, head); HMDT res = mgl_datac_norm(a1); mgl_delete_datac(a1); return res; } #if MGL_HAVE_GSL else if(!nm.compare(L"i") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Inu); else if(!nm.compare(L"j") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Jnu); else if(!nm.compare(L"k") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Knu); else if(!nm.compare(L"y") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_bessel_Ynu); else if(!nm.compare(L"f") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gslEllF); else if(!nm.compare(L"hypot") && n>0) return mglApplyOper(str.substr(n+1),str.substr(0,n),arg, head, hypot); else if(!nm.compare(L"gamma")) return mglApplyFunc(str, arg, head, gsl_sf_gamma); else if(!nm.compare(L"gamma_inc") && n>0) return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_gamma_inc); else if(!nm.compare(L"w0")) return mglApplyFunc(str, arg, head, gsl_sf_lambert_W0); else if(!nm.compare(L"w1")) return mglApplyFunc(str, arg, head, gsl_sf_lambert_Wm1); else if(!nm.compare(L"psi")) return mglApplyFunc(str, arg, head, gsl_sf_psi); else if(!nm.compare(L"zeta")) return mglApplyFunc(str, arg, head, gsl_sf_zeta); else if(!nm.compare(L"z")) return mglApplyFunc(str, arg, head, gsl_sf_dawson); #endif } HMDT res = new mglData; res->a[0]=NAN; return res; } //----------------------------------------------------------------------------- dual MGL_LOCAL_CONST ceqc(dual a,dual b); //{return a==b?1:0;} dual MGL_LOCAL_CONST cltc(dual a,dual b); //{return real(a-b)<0?1:0;} dual MGL_LOCAL_CONST cgtc(dual a,dual b); //{return real(a-b)>0?1:0;} dual MGL_LOCAL_CONST ipwc(dual a,dual b); //{return mgl_ipowc(a,int(b.real()));} dual MGL_LOCAL_CONST powc(dual a,dual b); //{return exp(b*log(a)); } dual MGL_LOCAL_CONST llgc(dual a,dual b); //{return log(a)/log(b); } dual MGL_LOCAL_CONST cmplxc(dual a,dual b); //{return a+dual(0,1)*b; } dual MGL_LOCAL_CONST expi(dual a); //{ return exp(dual(0,1)*a); } dual MGL_LOCAL_CONST expi(double a); //{ return dual(cos(a),sin(a)); } //----------------------------------------------------------------------------- dual MGL_LOCAL_CONST hypotc(dual x, dual y); //{ return sqrt(x*x+y*y); } dual MGL_LOCAL_CONST asinhc(dual x); //{ return log(x+sqrt(x*x+mreal(1))); } dual MGL_LOCAL_CONST acoshc(dual x); //{ return log(x+sqrt(x*x-mreal(1))); } dual MGL_LOCAL_CONST atanhc(dual x); //{ return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); } dual MGL_LOCAL_CONST conjc(dual x); //{ return dual(real(x),-imag(x)); } dual MGL_LOCAL_CONST sinc(dual x); //{ return sin(x); } dual MGL_LOCAL_CONST cosc(dual x); //{ return cos(x); } dual MGL_LOCAL_CONST tanc(dual x); //{ return tan(x); } dual MGL_LOCAL_CONST sinhc(dual x); //{ return sinh(x); } dual MGL_LOCAL_CONST coshc(dual x); //{ return cosh(x); } dual MGL_LOCAL_CONST tanhc(dual x); //{ return tanh(x); } dual MGL_LOCAL_CONST asinc(dual x); //{ return log(ic*x+sqrt(mreal(1)-x*x))/ic; } dual MGL_LOCAL_CONST acosc(dual x); //{ return log(x+sqrt(x*x-mreal(1)))/ic; } dual MGL_LOCAL_CONST atanc(dual x); //{ return log((ic-x)/(ic+x))/(mreal(2)*ic); } dual MGL_LOCAL_CONST expc(dual x); //{ return exp(x); } dual MGL_LOCAL_CONST sqrtc(dual x); //{ return sqrt(x); } dual MGL_LOCAL_CONST logc(dual x); //{ return log(x); } dual MGL_LOCAL_CONST absc(dual x); //{ return abs(x); } dual MGL_LOCAL_CONST argc(dual x); //{ return arg(x); } dual MGL_LOCAL_CONST lgc(dual x); //{ return log10(x);} dual MGL_LOCAL_CONST realc(dual x); //{ return real(x); } dual MGL_LOCAL_CONST imagc(dual x); //{ return imag(x); } dual MGL_LOCAL_CONST normc(dual x); //{ return norm(x); } //----------------------------------------------------------------------------- /// Parse string and substitute the script argument // All numbers are presented as mglData(1). Do boundary checking. // NOTE: In any case where number is required the mglData::a[0] is used. // String flag is binary 0x1 -> 'x', 0x2 -> 'y', 0x4 -> 'z' HADT MGL_NO_EXPORT mglFormulaCalcC(std::wstring str, mglParser *arg, const std::vector &head) { #if MGL_HAVE_GSL gsl_set_error_handler_off(); #endif if(str.empty()) return new mglDataC; // nothing to parse str = mgl_trim_ws(str); mreal tval = mgl_gettime(str); if(mgl_isnum(tval)) { mglDataC *r=new mglDataC; r->a[0] = tval; return r; } long n,len=str.length(); if(str[0]=='(' && mglCheck(str.substr(1,len-2))) // remove braces { str = str.substr(1,len-2); len-=2; } if(str[0]=='[') // this is manual subdata { long i, j, br=0,k; bool ar=true,mt=false; HADT res=0; for(i=1,j=1;i0) br--; if(str[i]==',' && !br) { HADT a1=mglFormulaCalcC(str.substr(j,i-j), arg, head); if(j==1) { res = a1; ar = (a1->nx==1); mt = (a1->nx>1 && a1->ny==1); } else { if(ar) // res 1d array { k = res->nx; res->Insert('x',k); mgl_datac_put_dat(res,a1,k,-1,-1); } else if(mt) // res 2d array { k = res->ny; res->Insert('y',k); mgl_datac_put_dat(res,a1,-1,k,-1); } else // res 3d array { k = res->nz; res->Insert('z',k); mgl_datac_put_dat(res,a1,-1,-1,k); } mgl_delete_datac(a1); } j=i+1; } } HADT a1=mglFormulaCalcC(str.substr(j,i-j), arg, head); if(j==1) { res = a1; ar = (a1->nx==1); mt = (a1->nx>1 && a1->ny==1); } else { if(ar) // res 1d array { k = res->nx; res->Insert('x',k); mgl_datac_put_dat(res,a1,k,-1,-1); } else if(mt) // res 2d array { k = res->ny; res->Insert('y',k); mgl_datac_put_dat(res,a1,-1,k,-1); } else // res 3d array { k = res->nz; res->Insert('z',k); mgl_datac_put_dat(res,a1,-1,-1,k); } mgl_delete_datac(a1); } return res; } n=mglFindInText(str,"<>="); // low priority -- conditions if(n>=0) return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, str[n]=='<'?cltc:(str[n]=='>'?cgtc:ceqc)); n=mglFindInText(str,"+-"); // normal priority -- additions if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2])))) return str[n]=='+'? mglApplyOperAddC(str.substr(0,n),str.substr(n+1),arg, head) : mglApplyOperSubC(str.substr(0,n),str.substr(n+1),arg, head); n=mglFindInText(str,"*/"); // high priority -- multiplications if(n>=0) return str[n]=='*'? mglApplyOperMulC(str.substr(0,n),str.substr(n+1),arg, head) : mglApplyOperDivC(str.substr(0,n),str.substr(n+1),arg, head); n=mglFindInText(str,"@"); // high priority -- combine if(n>=0) { HADT a1 = mglFormulaCalcC(str.substr(0,n),arg, head); HADT a2 = mglFormulaCalcC(str.substr(n+1),arg, head); HADT res = mgl_datac_combine(a1,a2); mgl_delete_datac(a1); mgl_delete_datac(a2); return res?res:new mglDataC; } n=mglFindInText(str,"^"); // highest priority -- power if(n>=0) return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, ipwc); n=mglFindInText(str,":"); // highest priority -- array if(n>=0 && str.compare(L":")) { HMDT a1=mglFormulaCalc(str.substr(0,n), arg, head); HMDT a2=mglFormulaCalc(str.substr(n+1), arg, head); HADT res = new mglDataC(abs(int(a2->a[0]+0.5)-int(a1->a[0]+0.5))+1); res->Fill(a1->a[0], a2->a[0]); mgl_delete_data(a1); mgl_delete_data(a2); return res; } n=mglFindInText(str,"."); // highest priority -- suffixes wchar_t c0 = str[n+1]; if(n>=0 && c0>='a' && c0!='e') { dual v=NAN; HADT d = mglFormulaCalcC(str.substr(0,n), arg, head); long ns[3] = {d->nx-1, d->ny-1, d->nz-1}; const std::wstring &p=str.substr(n+1); wchar_t ch = p[1]; if(c0=='a') { if(ch==0) v = d->a[0]; else { mreal x,y; d->Momentum(ch,x,y); if(ch=='a') v = x; else if(ch>='x' && ch<='z') v = x/ns[ch-'x']; } } else if(c0=='n' && ch>='x' && ch<='z') v = ns[ch-'x']+1; else if(c0=='k') { mreal x,y,z,k; d->Momentum(ch,x,y,z,k); if(ch=='a') v = k; else if(ch>='x' && ch<='z') v = k/ns[ch-'x']; } else if(c0=='w') { mreal x,y; d->Momentum(ch,x,y); if(ch=='a') v = y; else if(ch>='x' && ch<='z') v = y/ns[ch-'x']; } else if(c0=='m') { mreal x,y,z; if(ch=='a' && p[2]=='x') v = d->Maximal(); else if(ch=='i' && p[2]=='n') v = d->Minimal(); else if(ch=='x' && p[2]=='f') v = d->Maximal('x',0)/mreal(ns[0]); else if(ch=='x' && p[2]=='l') v = d->Maximal('x',-1)/mreal(ns[0]); else if(ch=='x') { d->Maximal(x,y,z); v = x/ns[0]; } else if(ch=='y' && p[2]=='f') v = d->Maximal('y',0)/mreal(ns[1]); else if(ch=='y' && p[2]=='l') v = d->Maximal('y',-1)/mreal(ns[1]); else if(ch=='y') { d->Maximal(x,y,z); v = y/ns[1]; } else if(ch=='z' && p[2]=='f') v = d->Maximal('z',0)/mreal(ns[2]); else if(ch=='z' && p[2]=='l') v = d->Maximal('z',-1)/mreal(ns[2]); else if(ch=='z') { d->Maximal(x,y,z); v = z/ns[2]; } } else if(c0=='s') { mreal x,y,z,k; if(ch=='u' && p[2]=='m') v = d->Momentum('x',x,y); else if(ch=='a') { d->Momentum(ch,x,y,z,k); v = z; } else if(ch>='x' && ch<='z') { d->Momentum(ch,x,y,z,k); v = z/ns[ch-'x']; } } else if(!p.compare(L"fst")) { long i=-1,j=-1,l=-1; v = d->Find(0,i,j,l); } else if(!p.compare(L"lst")) { long i=-1,j=-1,l=-1; v = d->Last(0,i,j,l); } delete d; // if this is valid suffix when finish parsing (it can be mreal number) if(mgl_isfin(v)) { HADT res = new mglDataC; res->a[0]=v; return res; } } if(str[0]=='`') { HADT res = mglFormulaCalcC(str.substr(1), arg, head); res->Transpose(); return res; } for(n=0;n=len) // this is number or variable { HCDT v = (str!=L"#$mgl")?FindVar(head, str):0; if(v) return new mglDataC(v); const mglNum *f = arg?arg->FindNum(str.c_str()):0; if(f) { HADT res = new mglDataC; res->a[0] = f->c; return res; } else if(!str.compare(L"rnd")) { v=FindVar(head, L"#$mgl"); HADT res = v?new mglDataC(v->GetNx(),v->GetNy(),v->GetNz()) : new mglDataC; for(long i=0;iGetNN();i++) res->a[i] = dual(mgl_rnd(), mgl_rnd()); return res; } else { HADT res = new mglDataC; wchar_t ch = str[0]; if(ch<':') // this is real number res->a[0] = (str[str.length()-1]=='i') ? dual(0,wcstod(str.c_str(),0)) : mreal(wcstod(str.c_str(),0)); else if(ch=='i') // this is imaginary number res->a[0] = dual(0,(str[1]>='0' && str[1]<='9')?wcstod(str.c_str()+1,0):1); else if(!str.compare(L"pi")) res->a[0] = M_PI; else if(ch==':') res->a[0] = -1; else if(!str.compare(L"nan")) res->a[0] = NAN; else if(!str.compare(L"inf")) res->a[0] = INFINITY; return res; } } else { std::wstring nm = str.substr(0,n); str = str.substr(n+1,len-n-2); len -= n+2; HCDT v = FindVar(head, nm); HADT tmp = 0; // mglVar *v = arg->FindVar(nm.c_str()); if(!v && !nm.compare(0,7,L"jacobi_")) nm = nm.substr(7); if(!v && nm.empty()) { long m=mglFindInText(nm,")"); if(m>1) { nm = str.substr(0,m); str = str.substr(m+2); tmp = mglFormulaCalcC(nm,arg,head); v = tmp; } } n = mglFindInText(str,","); if(v) // subdata { if(str[0]=='\'' && str[len-1]=='\'') // this is column call { char *buf = new char[len]; mgl_wcstombs(buf, str.substr(1).c_str(), len-1); buf[len-1]=0; HADT res = mgl_datac_column(v,buf); if(tmp) mgl_delete_datac(tmp); delete []buf; return res?res:new mglDataC; } else { HMDT a1=0, a2=0, a3=0; if(n>0) { long m=mglFindInText(str.substr(0,n),","); if(m>0) { str[m]=0; a1 = mglFormulaCalc(str.substr(0,m), arg, head); a2 = mglFormulaCalc(str.substr(m+1,n-m-1), arg, head); a3 = mglFormulaCalc(str.substr(n+1), arg, head); } else { a1 = mglFormulaCalc(str.substr(0,n), arg, head); a2 = mglFormulaCalc(str.substr(n+1), arg, head); } } else a1 = mglFormulaCalc(str, arg, head); HADT res = mgl_datac_subdata_ext(v,a1,a2,a3); if(tmp) mgl_delete_datac(tmp); mgl_delete_data(a1); mgl_delete_data(a2); mgl_delete_data(a3); return res?res:new mglDataC; } if(tmp) mgl_delete_datac(tmp); } else if(nm[0]=='a') // function { if(!nm.compare(L"asin")) return mglApplyFuncC(str, arg, head, asinc); else if(!nm.compare(L"acos")) return mglApplyFuncC(str, arg, head, acosc); else if(!nm.compare(L"atan")) return mglApplyFuncC(str, arg, head, atanc); else if(!nm.compare(L"asinh")) return mglApplyFuncC(str, arg, head, asinhc); else if(!nm.compare(L"acosh")) return mglApplyFuncC(str, arg, head, acoshc); else if(!nm.compare(L"atanh")) return mglApplyFuncC(str, arg, head, atanhc); else if(!nm.compare(L"arg")) return mglApplyFuncC(str, arg, head, argc); else if(!nm.compare(L"abs")) return mglApplyFuncC(str, arg, head, absc); } else if(nm[0]=='c') { if(!nm.compare(L"cos")) return mglApplyFuncC(str, arg, head, cosc); else if(!nm.compare(L"cosh") || !nm.compare(L"ch")) return mglApplyFuncC(str, arg, head, coshc); else if(!nm.compare(L"conj")) return mglApplyFuncC(str, arg, head, conjc); else if(!nm.compare(L"cmplx") && n>0) return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, cmplxc); } else if(!nm.compare(L"exp")) return mglApplyFuncC(str, arg, head, expc); else if(nm[0]=='l') { if(!nm.compare(L"log") || !nm.compare(L"ln")) return mglApplyFuncC(str, arg, head, logc); else if(!nm.compare(L"lg")) return mglApplyFuncC(str, arg, head, lgc); } else if(nm[0]=='s') { if(!nm.compare(L"sqrt")) return mglApplyFuncC(str, arg, head, sqrtc); else if(!nm.compare(L"sin")) return mglApplyFuncC(str, arg, head, sinc); else if(!nm.compare(L"sinh") || !nm.compare(L"sh")) return mglApplyFuncC(str, arg, head, sinhc); } else if(nm[0]=='t') { if(!nm.compare(L"tg") || !nm.compare(L"tan")) return mglApplyFuncC(str, arg, head, tanc); else if(!nm.compare(L"tanh") || !nm.compare(L"th")) return mglApplyFuncC(str, arg, head, tanhc); } else if(!nm.compare(L"pow") && n>0) return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, powc); else if(!nm.compare(L"random")) { HADT res=mglFormulaCalcC(str, arg, head); dual *a = res->a; for(long i=0;iGetNN();i++) a[i] = dual(mgl_rnd(), mgl_rnd()); return res; } else if(!nm.compare(L"hypot")) return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, hypotc); else if(!nm.compare(L"real")) return mglApplyFuncC(str, arg, head, realc); else if(!nm.compare(L"imag")) return mglApplyFuncC(str, arg, head, imagc); else if(!nm.compare(L"norm")) return mglApplyFuncC(str, arg, head, normc); } HADT res = new mglDataC; res->a[0]=NAN; return res; } //----------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/complex.cpp������������������������������������������������������������������������0000644�0001750�0001750�00000143656�13513030041�016126� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * complex.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/datac.h" #include "mgl2/evalc.h" #include "mgl2/thread.h" #include "interp.hpp" #define mgl2 mreal(2) #define mgl3 mreal(3) #define mgl4 mreal(4) //----------------------------------------------------------------------------- void MGL_EXPORT mglStartThreadC(void *(*func)(void *), void (*post)(mglThreadC *,dual *), long n, dual *a, const dual *b, const dual *c, const long *p, const void *v, const dual *d, const dual *e, const char *s) { if(!func) return; #if MGL_HAVE_PTHREAD if(mglNumThr<1) mgl_set_num_thr(0); if(mglNumThr>1) { pthread_t *tmp=new pthread_t[mglNumThr]; mglThreadC *par=new mglThreadC[mglNumThr]; for(long i=0;i1) { pthread_t *tmp=new pthread_t[mglNumThr]; mglThreadV *par=new mglThreadV[mglNumThr]; for(long i=0;ip[0], kind=t->p[2]; dual *b=t->a; const dual *a=t->b; if(kind>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) if(mgl_isnum(a[i])) // bypass NAN values { long j = i%nx, nk = 2*kind+1; for(long k=-kind;k<=kind;k++) if(j+k>=0 && j+kid;in;i+=mglNumThr) { long j = i%nx; if(j>1 && jp[0],ny=t->p[1], kind=t->p[2]; dual *b=t->a; const dual *a=t->b; if(kind>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) if(mgl_isnum(a[i])) // bypass NAN values { long j = (i/nx)%ny, nk = 2*kind+1; for(long k=-kind;k<=kind;k++) if(j+k>=0 && j+kid;in;i+=mglNumThr) { long j = (i/nx)%ny; if(j>1 && jp[0]*t->p[1], nz=t->n/nn, kind=t->p[2]; dual *b=t->a; const dual *a=t->b; if(kind>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) if(mgl_isnum(a[i])) // bypass NAN values { long j = i/nn, nk = 2*kind+1; for(long k=-kind;k<=kind;k++) if(j+k>=0 && j+kid;in;i+=mglNumThr) { long j = i/nn; if(j>1 && jnx,ny=d->ny,nz=d->nz; // if(Type == SMOOTH_NONE) return; long p[3]={nx,ny,Type}; dual *b = new dual[nx*ny*nz]; memset(b,0,nx*ny*nz*sizeof(dual)); if(nx>4 && xdir) { mglStartThreadC(mgl_csmth_x,0,nx*ny*nz,b,d->a,0,p); memcpy(d->a,b,nx*ny*nz*sizeof(dual)); memset(b,0,nx*ny*nz*sizeof(dual)); } if(ny>4 && ydir) { mglStartThreadC(mgl_csmth_y,0,nx*ny*nz,b,d->a,0,p); memcpy(d->a,b,nx*ny*nz*sizeof(dual)); memset(b,0,nx*ny*nz*sizeof(dual)); } if(nz>4 && zdir) { mglStartThreadC(mgl_csmth_z,0,nx*ny*nz,b,d->a,0,p); memcpy(d->a,b,nx*ny*nz*sizeof(dual)); } delete []b; } void MGL_EXPORT mgl_datac_smooth_(uintptr_t *d, const char *dir, mreal *delta,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_smooth(_DC_,s,*delta); delete []s; } //----------------------------------------------------------------------------- static void *mgl_ccsum_z(void *par) { mglThreadC *t=(mglThreadC *)par; long nz=t->p[2], nn=t->n; dual *b=t->a; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; dual *b=t->a; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; dual *b=t->a; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; dual *b = new dual[nn]; memcpy(b,d->a,nn*sizeof(dual)); if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_ccsum_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_ccsum_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_ccsum_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } delete []b; } void MGL_EXPORT mgl_datac_cumsum_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_cumsum(_DC_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_cint_z(void *par) { mglThreadC *t=(mglThreadC *)par; long nz=t->p[2], nn=t->n; dual *b=t->a, dd=0.5/nz; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; dual *b=t->a, dd=0.5/ny; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; dual *b=t->a, dd=0.5/nx; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; dual *b = new dual[nn]; memcpy(b,d->a,nn*sizeof(dual)); if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_cint_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_cint_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_cint_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } delete []b; } void MGL_EXPORT mgl_datac_integral_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_integral(_DC_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_cdif_z(void *par) { mglThreadC *t=(mglThreadC *)par; long nz=t->p[2], nn=t->n; dual *b=t->a, dd=0.5*nz; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; dual *b=t->a, dd=0.5*ny; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; dual *b=t->a, dd=0.5*nx; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; dual *b = new dual[nn]; if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_cdif_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_cdif_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_cdif_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } delete []b; } void MGL_EXPORT mgl_datac_diff_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_diff(_DC_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_cdif2_z(void *par) { mglThreadC *t=(mglThreadC *)par; long nz=t->p[2], nn=t->n; dual *b=t->a, dd=0.5*nz*nz; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; dual *b=t->a, dd=0.5*ny*ny; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; dual *b=t->a, dd=0.5*nx*nx; const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; dual *b = new dual[nn]; if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_cdif2_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_cdif2_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_cdif2_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(dual)); } delete []b; } void MGL_EXPORT mgl_datac_diff2_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_diff2(_DC_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_swap(HADT d, const char *dir) { if(!dir || *dir==0) return; if(strchr(dir,'z') && d->nz>1) mgl_datac_roll(d,'z',d->nz/2); if(strchr(dir,'y') && d->ny>1) mgl_datac_roll(d,'y',d->ny/2); if(strchr(dir,'x') && d->nx>1) mgl_datac_roll(d,'x',d->nx/2); } void MGL_EXPORT mgl_datac_swap_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_datac_swap(_DC_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_roll(HADT dd, char dir, long num) { long nx=dd->nx,ny=dd->ny,nz=dd->nz, d; dual *b,*a=dd->a; if(dir=='z' && nz>1) { d = num>0 ? num%nz : (num+nz*(1-num/nz))%nz; if(d==0) return; // nothing to do b = new dual[nx*ny*nz]; memcpy(b,a+nx*ny*d,nx*ny*(nz-d)*sizeof(dual)); memcpy(b+nx*ny*(nz-d),a,nx*ny*d*sizeof(dual)); memcpy(a,b,nx*ny*nz*sizeof(dual)); delete []b; } if(dir=='y' && ny>1) { d = num>0 ? num%ny : (num+ny*(1-num/ny))%ny; if(d==0) return; // nothing to do b = new dual[nx*ny*nz]; memcpy(b,a+nx*d,(nx*ny*nz-nx*d)*sizeof(dual)); #pragma omp parallel for for(long i=0;i1) { d = num>0 ? num%nx : (num+nx*(1-num/nx))%nx; if(d==0) return; // nothing to do b = new dual[nx*ny*nz]; memcpy(b,a+d,(nx*ny*nz-d)*sizeof(dual)); #pragma omp parallel for for(long i=0;inx,ny=d->ny,nz=d->nz; dual *a=d->a; if(strchr(dir,'z') && nz>1) { #pragma omp parallel for collapse(2) for(long j=0;j1) { #pragma omp parallel for collapse(2) for(long j=0;j1) { #pragma omp parallel for collapse(2) for(long j=0;j(a,nx,ny,nz,x,y,z); } //----------------------------------------------------------------------------- dual MGL_EXPORT mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx, dual *dy, dual *dz) { return mglSpline3t(a,nx,ny,nz,x,y,z,dx,dy,dz); } //----------------------------------------------------------------------------- dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z) { return mglLineart(a,nx,ny,nz,x,y,z); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_datac_spline(HCDT d, mreal x,mreal y,mreal z) { const mglDataC *dd=dynamic_cast(d); return mdual(dd ? mglSpline3st(dd->a,dd->nx,dd->ny,dd->nz,x,y,z) : d->value(x,y,z)); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_datac_spline_ext(HCDT d, mreal x,mreal y,mreal z, mdual *dx,mdual *dy,mdual *dz) { const mglDataC *dd=dynamic_cast(d); if(!dd) { mreal rx=0,ry=0,rz=0,res; res=d->valueD(x,y,z,&rx,&ry,&rz); if(dx) *dx=rx; if(dy) *dy=ry; if(dz) *dz=rz; return mdual(res); } dual xx,yy,zz, res = mglSpline3t(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,&xx,&yy,&zz); if(dx) *dx=xx; if(dy) *dy=yy; if(dz) *dz=zz; return mdual(res); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_datac_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z) { return mgl_datac_spline(_DA_(d),*x,*y,*z); } cmdual MGL_EXPORT mgl_datac_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mdual *dx,mdual *dy,mdual *dz) { return mgl_datac_spline_ext(_DA_(d),*x,*y,*z,dx,dy,dz); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, mdual *dx,mdual *dy,mdual *dz) { long kx=long(x), ky=long(y), kz=long(z); dual b0,b1; const mglDataC *dd=dynamic_cast(d); if(!dd) { mreal rx=0,ry=0,rz=0,res; res=mgl_data_linear_ext(d,x,y,z,&rx,&ry,&rz); if(dx) *dx=rx; if(dy) *dy=ry; if(dz) *dz=rz; return mdual(res); } long nx=dd->nx, ny=dd->ny, nz=dd->nz, dn=ny>1?nx:0; kx = kx>=0 ? kx:0; kx = kx=0 ? ky:0; ky = ky=0 ? kz:0; kz = kza, *bb; if(kz>=0) { aa=dd->a+kx+nx*(ky+ny*kz); bb = aa+nx*ny; b0 = aa[0]*(1-x-y+x*y) + x*(1-y)*aa[1] + y*(1-x)*aa[dn] + x*y*aa[1+dn]; b1 = bb[0]*(1-x-y+x*y) + x*(1-y)*bb[1] + y*(1-x)*bb[dn] + x*y*bb[1+dn]; } else { z=0; if(ky>=0) { aa=dd->a+kx+nx*ky; b0 = b1 = aa[0]*(1-x-y+x*y) + x*(1-y)*aa[1] + y*(1-x)*aa[dn] + x*y*aa[1+dn]; } else if(kx>=0) { aa=dd->a+kx; b0 = b1 = aa[0]*(1-x) + x*aa[1]; } else b0 = b1 = dd->a[0]; } if(dx) *dx = kx>=0?aa[1]-aa[0]:0; if(dy) *dy = ky>=0?aa[dn]-aa[0]:0; if(dz) *dz = b1-b0; return mdual(b0 + z*(b1-b0)); } cmdual MGL_EXPORT mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z) { return mgl_datac_linear_ext(d, x,y,z, 0,0,0); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z) { return mgl_datac_linear(_DA_(d),*x,*y,*z); } cmdual MGL_EXPORT mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mdual *dx,mdual *dy,mdual *dz) { return mgl_datac_linear_ext(_DA_(d),*x,*y,*z,dx,dy,dz); } //----------------------------------------------------------------------------- long MGL_NO_EXPORT mgl_powers(long N, const char *how); void MGL_EXPORT mgl_datac_crop_opt(HADT d, const char *how) { const char *h = "235"; if(mglchr(how,'2') || mglchr(how,'3') || mglchr(how,'5')) h = how; if(mglchr(how,'x')) mgl_datac_crop(d, 0, mgl_powers(d->nx, h), 'x'); if(mglchr(how,'y')) mgl_datac_crop(d, 0, mgl_powers(d->ny, h), 'y'); if(mglchr(how,'z')) mgl_datac_crop(d, 0, mgl_powers(d->nz, h), 'z'); } void MGL_EXPORT mgl_datac_crop_opt_(uintptr_t *d, const char *how, int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; mgl_datac_crop_opt(_DC_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_crop(HADT d, long n1, long n2, char dir) { long nx=d->nx,ny=d->ny,nz=d->nz, nn; dual *b; if(n1<0) n1=0; switch(dir) { case 'x': if(n1>=nx) break; n2 = n2>0 ? n2 : nx+n2; if(n2<0 || n2>=nx || n2a+nx*i+n1,nn*sizeof(dual)); d->nx = nn; if(!d->link) delete []d->a; d->a = b; d->link=false; d->NewId(); break; case 'y': if(n1>=ny) break; n2 = n2>0 ? n2 : ny+n2; if(n2<0 || n2>=ny || n2a+nx*(n1+i+ny*j),nx*sizeof(dual)); d->ny = nn; if(!d->link) delete []d->a; d->a = b; d->link=false; break; case 'z': if(n1>=nz) break; n2 = n2>0 ? n2 : nz+n2; if(n2<0 || n2>=nz || n2a+nx*ny*n1,nn*nx*ny*sizeof(dual)); d->nz = nn; if(!d->link) delete []d->a; d->a = b; d->link=false; break; } } void MGL_EXPORT mgl_datac_crop_(uintptr_t *d, int *n1, int *n2, const char *dir,int) { mgl_datac_crop(_DC_,*n1,*n2,*dir); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_insert(HADT d, char dir, long at, long num) { if(num<1) return; at = at<0 ? 0:at; long nx=d->nx, ny=d->ny, nz=d->nz, nn; mglDataC b; if(dir=='x') { if(at>nx) at=nx; nn=nx+num; b.Create(nn,ny,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(dual)); if(ata+at+nx*k,(nx-at)*sizeof(dual)); for(long i=0;ia[nx*k+at]; // copy values } d->Set(b); nx+=num; } if(dir=='y') { if(at>ny) at=ny; nn=num+ny; b.Create(nx,nn,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nx*nn*k, d->a+nx*ny*k,at*nx*sizeof(dual)); if(ata+nx*(at+ny*k),(ny-at)*nx*sizeof(dual)); for(long i=0;ia+nx*(ny*k+at),nx*sizeof(dual)); } d->Set(b); ny+=num; } if(dir=='z') { if(at>nz) at=nz; b.Create(nx,ny,nz+num); if(at>0) memcpy(b.a, d->a,at*nx*ny*sizeof(dual)); if(ata+nx*ny*at,(nz-at)*nx*ny*sizeof(dual)); #pragma omp parallel for for(long i=0;ia+nx*ny*at,nx*ny*sizeof(dual)); d->Set(b); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_delete(HADT d, char dir, long at, long num) { if(num<1 || at<0) return; mglDataC b; long nx=d->nx, ny=d->ny, nz=d->nz, nn; if(dir=='x') { if(at+num>=nx) return; nn=nx-num; b.Create(nn,ny,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(dual)); memcpy(b.a+at+nn*k, d->a+at+num+nx*k,(nx-at-num)*sizeof(dual)); } d->Set(b); nx-=num; } if(dir=='y') { if(at+num>=ny) return; nn=ny-num; b.Create(nx,nn,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nx*nn*k, d->a+nx*ny*k,at*nx*sizeof(dual)); memcpy(b.a+nx*(at+nn*k), d->a+nx*(at+num+ny*k),(ny-at-num)*nx*sizeof(dual)); } d->Set(b); ny-=num; } if(dir=='z') { if(at+num>=nz) return; b.Create(nx,ny,nz-num); if(at>0) memcpy(b.a, d->a,at*nx*ny*sizeof(dual)); memcpy(b.a+nx*ny*at, d->a+nx*ny*(at+num),(nz-at-num)*nx*ny*sizeof(dual)); d->Set(b); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_insert_(uintptr_t *d, const char *dir, int *at, int *num, int) { mgl_datac_insert(_DC_,*dir,*at,*num); } void MGL_EXPORT mgl_datac_delete_(uintptr_t *d, const char *dir, int *at, int *num, int) { mgl_datac_delete(_DC_,*dir,*at,*num); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_value(HADT dat, mdual v, long i, long j, long k) { if(i>=0 && inx && j>=0 && jny && k>=0 && knz) dat->a[i+dat->nx*(j+dat->ny*k)]=v; } void MGL_EXPORT mgl_datac_set_value_(uintptr_t *d, mdual *v, int *i, int *j, int *k) { mgl_datac_set_value(_DC_,*v,*i,*j,*k); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k) { long nx=dat->GetNx(), ny=dat->GetNy(), i0=i+nx*(j+ny*k); if(i<0 || i>=nx || j<0 || j>=ny || k<0 || k>=dat->GetNz()) return mdual(NAN); const mglDataC *d = dynamic_cast(dat); return mdual(d ? d->a[i0] : dual(dat->vthr(i0),0)); } cmdual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k) { return mgl_datac_get_value(_DA_(d),*i,*j,*k); } //----------------------------------------------------------------------------- MGL_EXPORT_PURE mdual *mgl_datac_data(HADT dat) { return reinterpret_cast(dat->a); } //----------------------------------------------------------------------------- MGL_EXPORT mdual *mgl_datac_value(HADT dat, long i,long j,long k) { long ii=i*dat->nx*(j+dat->ny*k); return ii>=0 && iiGetNN() ? reinterpret_cast(dat->a+ii) : 0; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_join(HADT d, HCDT v) { long nx=d->nx, ny=d->ny, nz=d->nz, k=nx*ny*nz; const mglDataC *mv = dynamic_cast(v); long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(), m = vx*vy*vz; if(nx==vx && ny==vy && ny>1) d->nz += vz; else { ny *= nz; vy *= vz; if(nx==vx && nx>1) { d->nz = 1; d->ny = ny+vy; } else { d->ny = d->nz = 1; d->nx = k+m; } } dual *b = new dual[k+m]; memcpy(b,d->a,k*sizeof(dual)); if(mv) memcpy(b+k,mv->a,m*sizeof(dual)); else #pragma omp parallel for for(long i=0;ivthr(i); if(!d->link) delete []d->a; d->a = b; d->link=false; d->NewId(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_join_(uintptr_t *d, uintptr_t *val) { mgl_datac_join(_DC_,_DA_(val)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_put_val(HADT d, mdual val, long xx, long yy, long zz) { long nx=d->nx, ny=d->ny, nz=d->nz; if(xx>=nx || yy>=ny || zz>=nz) return; dual *a=d->a; if(xx>=0 && yy>=0 && zz>=0) a[xx+nx*(yy+zz*ny)] = val; else if(xx<0 && yy<0 && zz<0) #pragma omp parallel for for(long i=0;inx, ny=d->ny, nz=d->nz; if(xx>=nx || yy>=ny || zz>=nz) return; const mglDataC *mv = dynamic_cast(v); dual *a=d->a, vv=v->v(0); const dual *b = mv?mv->a:0; long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(); if(xx<0 && yy<0 && zz<0) // whole array { if(vx>=nx && vy>=ny && vz>=nz) #pragma omp parallel for for(long ii=0;iiv(i,j,k); } else if(vx>=nx && vy>=ny) #pragma omp parallel for for(long ii=0;iiv(i,j); } else if(vx>=nx) #pragma omp parallel for for(long ii=0;iiv(i); } else #pragma omp parallel for for(long ii=0;ii=nx && vy>=ny) #pragma omp parallel for for(long ii=0;iiv(i,j); } else if(vx>=nx) #pragma omp parallel for for(long ii=0;iiv(i); } else #pragma omp parallel for for(long ii=0;ii=ny && vy>=nz) #pragma omp parallel for for(long ii=0;iiv(i,j); } else if(vx>=ny) #pragma omp parallel for for(long ii=0;iiv(i); } else #pragma omp parallel for for(long ii=0;ii=nx && vy>=nz) #pragma omp parallel for for(long ii=0;iiv(i,j); } else if(vx>=nx) #pragma omp parallel for for(long ii=0;iiv(i); } else #pragma omp parallel for for(long ii=0;ii=nx) #pragma omp parallel for for(long i=0;iv(i); else #pragma omp parallel for for(long i=0;i=ny) #pragma omp parallel for for(long i=0;iv(i); else #pragma omp parallel for for(long i=0;i=nz) #pragma omp parallel for for(long i=0;iv(i); else #pragma omp parallel for for(long i=0;ip[0], st=t->p[1], bord=t->p[3], nn=t->n; dual *b=t->a, q = *(t->b); #if !MGL_HAVE_PTHREAD #pragma omp parallel #endif { dual *tmp = new dual[2*n]; if(t->p[2]) #if !MGL_HAVE_PTHREAD #pragma omp for #endif for(long i=t->id;iid;inx,ny=d->ny,nz=d->nz; long p[4]={0,0,0,0}; dual qq=q; if(mglchr(how,'e')) p[3]=-1; if(mglchr(how,'g')) p[3]=-2; if(mglchr(how,'1')) p[3]=1; if(mglchr(how,'2')) p[3]=2; if(mglchr(how,'3')) p[3]=3; bool axial = mglchr(how,'r')||mglchr(how,'a'); if(mglchr(how,'z') && nz>1) { p[0]=nz; p[1]=nx*ny; p[2]=0; mglStartThreadC(mgl_difr,0,nx*ny,d->a,&qq,0,p); } if(mglchr(how,'y') && ny>1 && !axial) { p[0]=ny; p[1]=nx; p[2]=0; mglStartThreadC(mgl_difr,0,nx*nz,d->a,&qq,0,p); } if(mglchr(how,'x') && nx>1 && !axial) { p[0]=nx; p[1]=1; p[2]=0; mglStartThreadC(mgl_difr,0,ny*nz,d->a,&qq,0,p); } if(axial && nx>1) { p[0]=nx; p[1]=1; p[2]=1; mglStartThreadC(mgl_difr,0,ny*nz,0,&qq,0,p); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_diffr_(uintptr_t *d, const char *how, double q,int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; mgl_datac_diffr(_DC_,s,q); delete []s; } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_gsplinec_init(HCDT x, HCDT v) { long n = v->GetNx(); if(!x || x->GetNx()!=n) return 0; mglDataC *res = new mglDataC(5*(n-1)); mreal *xx=0; dual *vv=0; const mglData *dx = dynamic_cast(x); if(!dx) { xx = new mreal[n]; for(long i=0;iv(i); } const mglDataC *dv = dynamic_cast(v); if(!dv) { vv = new dual[n]; for(long i=0;iv(i); } mgl_gspline_init(n,dx?dx->a:xx,dv?dv->a:vv,res->a); if(xx) delete []xx; if(vv) delete []vv; return res; } uintptr_t MGL_EXPORT mgl_gsplinec_init_(uintptr_t *x, uintptr_t *v) { return uintptr_t(mgl_gspline_init(_DA_(x),_DA_(v))); } //----------------------------------------------------------------------------- cmdual MGL_EXPORT mgl_gsplinec(HCDT c, mreal dx, mdual *d1, mdual *d2) { long i=0, n = c->GetNx(); if(n%5) return mdual(NAN); // not the table of coefficients while(dx>c->v(5*i) && iv(5*i); i++; } dual res; const mglDataC *d = dynamic_cast(c); if(d) { const dual *a = d->a+5*i; if(d1) *d1 = a[2]+dx*(mreal(2)*a[3]+(3*dx)*a[4]); if(d2) *d2 = mreal(2)*a[3]+(6*dx)*a[4]; res = a[1]+dx*(a[2]+dx*(a[3]+dx*a[4])); } else { if(d1) *d1 = c->v(5*i+2)+dx*(2*c->v(5*i+3)+3*dx*c->v(5*i+4)); if(d2) *d2 = 2*c->v(5*i+3)+6*dx*c->v(5*i+4); res = c->v(5*i+1)+dx*(c->v(5*i+2)+dx*(c->v(5*i+3)+dx*c->v(5*i+4))); } return mdual(res); } cmdual MGL_EXPORT mgl_gsplinec_(uintptr_t *c, mreal *dx, mdual *d1, mdual *d2) { return mgl_gsplinec(_DA_(c),*dx,d1,d2); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_refill_gs(HADT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl) { HADT coef = mgl_gsplinec_init(xdat, vdat); if(!coef) return; // incompatible dimensions const long nx = dat->nx, nn=dat->ny*dat->nz; mreal x0 = x1-xdat->v(0), dx = (x2-x1)/(nx-1); #pragma omp parallel for for(long i=0;ia[i+j*nx] = d; else dat->a[i+sl*nx] = d; } mgl_delete_datac(coef); } //----------------------------------------------------------------------------- mreal MGL_NO_EXPORT mgl_index_1(mreal v, HCDT dat); void MGL_EXPORT mgl_datac_refill_x(HADT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl) { long nx=dat->nx,mx=vdat->GetNx(),nn=dat->ny*dat->nz; if(mx!=xdat->GetNx()) return; // incompatible dimensions mreal dx = (x2-x1)/(nx-1); #pragma omp parallel for for(long i=0;ia[i+j*nx] = d; else dat->a[i+sl*nx] = d; } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_refill_xy(HADT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl) { long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),nn=nx*ny; bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN()); if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my)) return; // incompatible dimensions mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1); if(both) { #pragma omp parallel for for(long i=0;ia[i]=NAN; #pragma omp parallel for collapse(2) for(long j=0;jvthr(i0)-x1)/dx, vy0 = (ydat->vthr(i0)-y1)/dy; mreal vx1 = (xdat->vthr(i0+1)-x1)/dx, vy1 = (ydat->vthr(i0+1)-y1)/dy; mreal vx2 = (xdat->vthr(i0+mx)-x1)/dx, vy2 = (ydat->vthr(i0+mx)-y1)/dy; mreal vx3 = (xdat->vthr(i0+mx+1)-x1)/dx, vy3 = (ydat->vthr(i0+mx+1)-y1)/dy; long xx1 = long(mgl_min( mgl_min(vx0,vx1), mgl_min(vx2,vx3) )); // bounding box long yy1 = long(mgl_min( mgl_min(vy0,vy1), mgl_min(vy2,vy3) )); long xx2 = long(mgl_max( mgl_max(vx0,vx1), mgl_max(vx2,vx3) )); long yy2 = long(mgl_max( mgl_max(vy0,vy1), mgl_max(vy2,vy3) )); xx1=mgl_imax(xx1,0); xx2=mgl_imin(xx2,nx-1); yy1=mgl_imax(yy1,0); yy2=mgl_imin(yy2,ny-1); if(xx1>xx2 || yy1>yy2) continue; mreal d1x = vx1-vx0, d1y = vy1-vy0; mreal d2x = vx2-vx0, d2y = vy2-vy0; mreal d3x = vx3+vx0-vx1-vx2, d3y = vy3+vy0-vy1-vy2; mreal dd = d1x*d2y-d1y*d2x; mreal dsx =-4*(d2y*d3x - d2x*d3y)*d1y; mreal dsy = 4*(d2y*d3x - d2x*d3y)*d1x; for(long jj=yy1;jj<=yy2;jj++) for(long ii=xx1;ii<=xx2;ii++) { mreal xx = (ii-vx0), yy = (jj-vy0); mreal s = dsx*xx + dsy*yy + (dd+d3y*xx-d3x*yy)*(dd+d3y*xx-d3x*yy); if(s>=0) { s = sqrt(s); mreal qu = d3x*yy - d3y*xx + dd + s; mreal qv = d3y*xx - d3x*yy + dd + s; mreal u = 2.f*(d2y*xx - d2x*yy)/qu; mreal v = 2.f*(d1x*yy - d1y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad { qu = d3x*yy - d3y*xx + dd - s; qv = d3y*xx - d3x*yy + dd - s; u = 2.f*(d2y*xx - d2x*yy)/qu; v = 2.f*(d1x*yy - d1y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad } i0 = ii+nx*jj; s = vdat->value(i+u,j+v,0); if(sl<0) for(long k=0;ka[i0+k*nn] = s; else dat->a[i0+sl*nn] = s; } } } } else { mglData u(nx), v(ny); #pragma omp parallel for for(long i=0;ia[i0+k*nn] = d; else dat->a[i0+sl*nn] = d; } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_refill_xyz(HADT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2) { if(!dat || !xdat || !ydat || !zdat || !vdat) return; long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),mz=vdat->GetNz(); bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN() && zdat->GetNN()==vdat->GetNN()); if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my || zdat->GetNx()!=mz)) return; // incompatible dimensions const mreal acx=1e-6*fabs(x2-x1), acy=1e-6*fabs(y2-y1), acz=1e-6*fabs(z2-z1); if(both) #pragma omp parallel for collapse(3) for(long k=0;kvalueD(dx,dy,dz,&dxx,&dxy,&dxz); vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz); vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz); long count=0; do // use Newton method to find root { if(count>50) { dx=NAN; break; } count++; dd = -dxx*dyy*dzz+dxy*dyx*dzz+dxx*dyz*dzy-dxz*dyx*dzy-dxy*dyz*dzx+dxz*dyy*dzx; dx += ((dyz*dzy-dyy*dzz)*(xx-vx)+(dxy*dzz-dxz*dzy)*(yy-vy)+(dxz*dyy-dxy*dyz)*(zz-vz))/dd; dy += ((dyx*dzz-dyz*dzx)*(xx-vx)+(dxz*dzx-dxx*dzz)*(yy-vy)+(dxx*dyz-dxz*dyx)*(zz-vz))/dd; dz += ((dyy*dzx-dyx*dzy)*(xx-vx)+(dxx*dzy-dxy*dzx)*(yy-vy)+(dxy*dyx-dxx*dyy)*(zz-vz))/dd; vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz); vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz); vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz); } while(fabs(xx-vx)>acx && fabs(yy-vy)>acy && fabs(zz-vz)>acz); // this valid for linear interpolation dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:vdat->value(dx,dy,dz); } else { mglData u(nx), v(ny), w(nz); mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1), dz = (z2-z1)/(nz-1); #pragma omp parallel for for(long i=0;ia[i+nx*(j+ny*k)] = mgl_datac_spline(vdat,u.a[i],v.a[j],w.a[k]); } } //----------------------------------------------------------------------------- static void *mgl_diffc_3(void *par) { mglThreadC *t=(mglThreadC *)par; long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n, n2=nx*ny; dual *b=t->a,au,av,aw; HCDT x=(HCDT)(t->c),y=(HCDT)(t->d),z=(HCDT)(t->e); const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for private(au,av,aw) #endif for(long i0=t->id;i0vthr(i0)-4*x->vthr(i0+1)+x->vthr(i0+2); yu = 3*y->vthr(i0)-4*y->vthr(i0+1)+y->vthr(i0+2); zu = 3*z->vthr(i0)-4*z->vthr(i0+1)+z->vthr(i0+2); } else if(i==nx-1) { au = mreal(3)*a[i0]-mreal(4)*a[i0-1]+a[i0-2]; xu = 3*x->vthr(i0)-4*x->vthr(i0-1)+x->vthr(i0-2); yu = 3*y->vthr(i0)-4*y->vthr(i0-1)+y->vthr(i0-2); zu = 3*z->vthr(i0)-4*z->vthr(i0-1)+z->vthr(i0-2); } else { au = a[i0+1]-a[i0-1]; xu = x->vthr(i0+1)-x->vthr(i0-1); yu = y->vthr(i0+1)-y->vthr(i0-1); zu = z->vthr(i0+1)-z->vthr(i0-1); } if(j==0) { av = mreal(3)*a[i0]-mreal(4)*a[i0+nx]+a[i0+2*nx]; xv = 3*x->vthr(i0)-4*x->vthr(i0+nx)+x->vthr(i0+2*nx); yv = 3*y->vthr(i0)-4*y->vthr(i0+nx)+y->vthr(i0+2*nx); zv = 3*z->vthr(i0)-4*z->vthr(i0+nx)+z->vthr(i0+2*nx); } else if(j==ny-1) { av = mreal(3)*a[i0]-mreal(4)*a[i0-nx]+a[i0+(ny-3)*nx]; xv = 3*x->vthr(i0)-4*x->vthr(i0-nx)+x->vthr(i0-2*nx); yv = 3*y->vthr(i0)-4*y->vthr(i0-nx)+y->vthr(i0-2*nx); zv = 3*z->vthr(i0)-4*z->vthr(i0-nx)+z->vthr(i0-2*nx); } else { av = a[i0+nx]-a[i0-nx]; xv = x->vthr(i0+nx)-x->vthr(i0-nx); yv = y->vthr(i0+nx)-y->vthr(i0-nx); zv = z->vthr(i0+nx)-z->vthr(i0-nx); } if(k==0) { aw = mreal(3)*a[i0]-mreal(4)*a[i0+n2]+a[i0+2*n2]; xw = 3*x->vthr(i0)-4*x->vthr(i0+n2)+x->vthr(i0+2*n2); yw = 3*y->vthr(i0)-4*y->vthr(i0+n2)+y->vthr(i0+2*n2); zw = 3*z->vthr(i0)-4*z->vthr(i0+n2)+z->vthr(i0+2*n2); } else if(k==nz-1) { aw = mreal(3)*a[i0]-mreal(4)*a[i0-n2]+a[i0-2*n2]; xw = 3*x->vthr(i0)-4*x->vthr(i0-n2)+x->vthr(i0-2*n2); yw = 3*y->vthr(i0)-4*y->vthr(i0-n2)+y->vthr(i0-2*n2); zw = 3*z->vthr(i0)-4*z->vthr(i0-n2)+z->vthr(i0-2*n2); } else { aw = a[i0+n2]-a[i0-n2]; xw = x->vthr(i0+n2)-x->vthr(i0-n2); yw = y->vthr(i0+n2)-y->vthr(i0-n2); zw = z->vthr(i0+n2)-z->vthr(i0-n2); } b[i0] = (au*yv*zw-av*yu*zw-au*yw*zv+aw*yu*zv+av*yw*zu-aw*yv*zu) / (xu*yv*zw-xv*yu*zw-xu*yw*zv+xw*yu*zv+xv*yw*zu-xw*yv*zu); } return 0; } static void *mgl_diffc_2(void *par) { mglThreadC *t=(mglThreadC *)par; long nx=t->p[0], ny=t->p[1], nn=t->n, same=t->p[2]; dual *b=t->a,au,av; HCDT x=(HCDT)(t->c),y=(HCDT)(t->d); const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for private(au,av) #endif for(long i0=t->id;i0vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2); yu = 3*y->vthr(i1)-4*y->vthr(i1+1)+y->vthr(i1+2); } else if(i==nx-1) { au = mreal(3)*a[i0]-mreal(4)*a[i0-1]+a[i0-2]; xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2); yu = 3*y->vthr(i1)-4*y->vthr(i1-1)+y->vthr(i1-2); } else { au = a[i0+1]-a[i0-1]; xu = x->vthr(i1+1)-x->vthr(i1-1); yu = y->vthr(i1+1)-y->vthr(i1-1); } if(j==0) { av = mreal(3)*a[i0]-mreal(4)*a[i0+nx]+a[i0+2*nx]; xv = 3*x->vthr(i1)-4*x->vthr(i1+nx)+x->vthr(i1+2*nx); yv = 3*y->vthr(i1)-4*y->vthr(i1+nx)+y->vthr(i1+2*nx); } else if(j==ny-1) { av = mreal(3)*a[i0]-mreal(4)*a[i0-nx]+a[i0-2*nx]; xv = 3*x->vthr(i1)-4*x->vthr(i1-nx)+x->vthr(i1-2*nx); yv = 3*y->vthr(i1)-4*y->vthr(i1-nx)+y->vthr(i1-2*nx); } else { av = a[i0+nx]-a[i0-nx]; xv = x->vthr(i1+nx)-x->vthr(i1-nx); yv = y->vthr(i1+nx)-y->vthr(i1-nx); } b[i0] = (av*yu-au*yv)/(xv*yu-xu*yv); } return 0; } static void *mgl_diffc_1(void *par) { mglThreadC *t=(mglThreadC *)par; long nx=t->p[0], nn=t->n, same=t->p[1]; dual *b=t->a,au; HCDT x=(HCDT)(t->c); const dual *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for private(au) #endif for(long i0=t->id;i0vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2); } else if(i==nx-1) { au = mreal(3)*a[i0]-mreal(4)*a[i0-1]+a[i0-2]; xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2); } else { au = a[i0+1]-a[i0-1]; xu = x->vthr(i1+1)-x->vthr(i1-1); } b[i0] = au/xu; } return 0; } void MGL_EXPORT mgl_datac_diff_par(HADT d, HCDT x, HCDT y, HCDT z) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), nn=nx*ny*nz; if(nx<2 || ny<2) return; dual *b = new dual[nn]; memset(b,0,nn*sizeof(dual)); long p[3]={nx,ny,nz}; if(x&&y&&z && x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn) mglStartThreadC(mgl_diffc_3,0,nn,b,d->a,(const dual *)x,p,0,(const dual *)y,(const dual *)z); else if(x&&y && x->GetNx()*x->GetNy()==nx*ny && y->GetNx()*y->GetNy()==nx*ny) { p[2]=(x->GetNz()==nz && y->GetNz()==nz); mglStartThreadC(mgl_diffc_2,0,nn,b,d->a,(const dual *)x,p,0,(const dual *)y); } else if(x && x->GetNx()==nx) { p[1]=(x->GetNy()*x->GetNz()==ny*nz); mglStartThreadC(mgl_diffc_1,0,nn,b,d->a,(const dual *)x,p,0,0); } memcpy(d->a,b,nn*sizeof(dual)); delete []b; } void MGL_EXPORT mgl_datac_diff_par_(uintptr_t *d, uintptr_t *v1, uintptr_t *v2, uintptr_t *v3) { mgl_datac_diff_par(_DC_,_DA_(v1),_DA_(v2),_DA_(v3)); } //----------------------------------------------------------------------------- ����������������������������������������������������������������������������������mathgl-2.4.4/src/interp.hpp�������������������������������������������������������������������������0000644�0001750�0001750�00000022100�13513030041�015741� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//----------------------------------------------------------------------------- template Treal mglLineart(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z) { if(!a || nx<1 || ny<1 || nz<1) return 0; Treal b=0,dx,dy,dz,b1,b0; if(x<0 || y<0 || z<0 || x>nx-1 || y>ny-1 || z>nz-1) return 0; if(nz>1 && z!=floor(z)) // 3d interpolation { long kx=long(x), ky=long(y), kz=long(z); dx = x-mreal(kx); dy = y-mreal(ky); dz = z-mreal(kz); long i0 = kx+nx*(ky+ny*kz); b0 = a[i0]*(mreal(1)-dx-dy+dx*dy) + dx*(mreal(1)-dy)*a[i0+1] + dy*(mreal(1)-dx)*a[i0+nx] + dx*dy*a[i0+nx+1]; i0 = kx+nx*(ky+ny*(kz+1)); b1 = a[i0]*(mreal(1)-dx-dy+dx*dy) + dx*(mreal(1)-dy)*a[i0+1] + dy*(mreal(1)-dx)*a[i0+nx] + dx*dy*a[i0+nx+1]; b = b0 + dz*(b1-b0); } else if(ny>1 && y!=floor(y)) // 2d interpolation { long kx=long(x), ky=long(y); dx = x-kx; dy=y-ky; long i0 = kx+nx*ky; b = a[i0]*(mreal(1)-dx-dy+dx*dy) + dx*(mreal(1)-dy)*a[i0+1] + dy*(mreal(1)-dx)*a[i0+nx] + dx*dy*a[i0+nx+1]; } else if(nx>1 && x!=floor(x)) // 1d interpolation { long kx = long(x); b = a[kx] + (x-kx)*(a[kx+1]-a[kx]); } else // no interpolation b = a[long(x+nx*(y+ny*z))]; return b; } //----------------------------------------------------------------------------- template Treal mgl_spline3t(const Treal y[4], long n, mreal dx, Treal &dy) { Treal d[3]; d[0] = -(y[2]-mreal(4)*y[1]+mreal(3)*y[0])/mreal(2); d[1] = (y[2]-y[0])/mreal(2); d[2] = (y[3]-y[1])/mreal(2); Treal t0 = (y[2]+y[0])/mreal(2)-y[1]; Treal t1 = (y[3]+y[1])/mreal(2)-y[2]; Treal f0 = y[n], d0 = d[n], res = 0; if(n==1) { Treal df = y[2]-f0, d1 = d[2]; Treal b3 = mreal(10)*df+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0; Treal b4 = mreal(-15)*df-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0; Treal b5 = mreal(6)*df+t1-t0-mreal(3)*d1-mreal(3)*d0; dy = d0 + dx*(mreal(2)*t0+dx*(mreal(3)*b3+dx*(mreal(4)*b4+dx*mreal(5)*b5))); // d2y = mreal(2)*t0 + dx*(mreal(6)*b3+dx*(mreal(12)*b4+dx*mreal(20)*b5)); // 2nd derivative for future res = f0 + dx*(d0+dx*(t0+dx*(b3+dx*(b4+dx*b5)))); } else if(n<1) { res = f0 + dx*(d0+dx*t0); dy = d0+dx*t0*mreal(2); } else { res = f0 + dx*(d0+dx*t1); dy = d0+dx*t1*mreal(2); } return res; } //----------------------------------------------------------------------------- template Treal mgl_spline3st(const Treal y[4], long n, mreal dx) { Treal d[3]; d[0] = -(y[2]-mreal(4)*y[1]+mreal(3)*y[0])/mreal(2); d[1] = (y[2]-y[0])/mreal(2); d[2] = (y[3]-y[1])/mreal(2); Treal f0 = y[n], d0 = d[n], res; Treal t0 = (y[2]+y[0])/mreal(2)-y[1]; Treal t1 = (y[3]+y[1])/mreal(2)-y[2]; if(n==1) { Treal df = y[2]-f0, d1 = d[2]; Treal b3 = mreal(10)*df+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0; Treal b4 = mreal(-15)*df-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0; Treal b5 = mreal(6)*df+t1-t0-mreal(3)*d1-mreal(3)*d0; res = f0 + dx*(d0+dx*(t0+dx*(b3+dx*(b4+dx*b5)))); } else res = f0 + dx*(d0+dx*(n<1?t0:t1)); return res; } //----------------------------------------------------------------------------- template Treal mglSpline1t(const Treal *a, long nx, mreal x, Treal *dx=0) { Treal r,d; if(nx>3) { long k = long(x); if(k>0 && k(a+k-1, 1, x-k, d); else if(k<1) r = mgl_spline3t(a, 0, x, d); else r = mgl_spline3t(a+nx-4, 2, x+2-nx, d); } else if(nx<2) { d=0; r = a[0]; } else if(nx==2) { d=a[1]-a[0]; r = a[0]+(a[1]-a[0])*x; } else // nx==3 { Treal b1=-(a[2]-mreal(4)*a[1]+mreal(3)*a[0])/mreal(2), b2=(a[2]-mreal(2)*a[1]+a[0])/mreal(2); d = b1+mreal(2)*b2*x; r = a[0]+x*(b1+b2*x); } if(dx) *dx=d; return r; } //----------------------------------------------------------------------------- template Treal mglSpline1st(const Treal *a, long nx, mreal x) { Treal r; if(nx>3) { long k = long(x); if(k>0 && k(a+k-1, 1, x-k); else if(k<1) r = mgl_spline3st(a, 0, x); else r = mgl_spline3st(a+nx-4, 2, x+2-nx); } else if(nx<2) r = a[0]; else if(nx==2) r = a[0]+(a[1]-a[0])*x; else // nx==3 { Treal b1=-(a[2]-mreal(4)*a[1]+mreal(3)*a[0])/mreal(2), b2=(a[2]-mreal(2)*a[1]+a[0])/mreal(2); r = a[0]+x*(b1+b2*x); } return r; } //----------------------------------------------------------------------------- template Treal mglSpline3t(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z, Treal *dx=0, Treal *dy=0, Treal *dz=0) { // if(!a || nx<1 || ny<1 || nz<1) return 0; // NOTE remove this line because this should already checked Treal gx=0,gy=0,gz=0; x = x>0 ?(x0 ?(y0 ?(z1) // 3d interpolation { Treal tz[4], yz[4], xz[4]; long kz=long(z)-1, mz, k=long(y)-1, m; if(nz>3) { mz = 4; kz = kz>=0?kz:0; if(kz>nz-4) kz = nz-4; } else { mz = nz; kz=0; } if(ny>3) { m = 4; k = k>=0?k:0; if(k>ny-4) k = ny-4; } else { m = ny; k=0; } for(long j=0;j(a+nx*(i+k+ny*(j+kz)),nx,x,d+i); tz[j] = mglSpline1t(t,m,y-k,yz+j); xz[j] = mglSpline1t(d,m,y-k,0); } b = mglSpline1t(tz,mz,z-kz,&gz); gx = mglSpline1t(xz,mz,z-kz,0); gy = mglSpline1t(yz,mz,z-kz,0); } else if(ny>1) // 2d interpolation { Treal t[4], d[4]; long k = long(y)-1, m; if(ny>3) { m = 4; k = k>=0?k:0; if(k>ny-4) k = ny-4; } else { m = ny; k=0; } for(long i=0;i(a+nx*(i+k),nx,x,d+i); b = mglSpline1t(t,m,y-k,&gy); gx = mglSpline1t(d,m,y-k,0); } else // 1d interpolation b = mglSpline1t(a,nx,x,&gx); if(dx) *dx=gx; if(dy) *dy=gy; if(dz) *dz=gz; return b; } //----------------------------------------------------------------------------- template Treal mglSpline3st(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z) { // if(!a || nx<1 || ny<1 || nz<1) return 0; // NOTE remove this line because this should already checked x = x>0 ?(x0 ?(y0 ?(z1) // 3d interpolation { Treal tz[4], t[4]; long kz=long(z)-1, mz, k=long(y)-1, m; if(nz>3) { mz = 4; kz = kz>=0?kz:0; if(kz>nz-4) kz = nz-4; } else { mz = nz; kz=0; } if(ny>3) { m = 4; k = k>=0?k:0; if(k>ny-4) k = ny-4; } else { m = ny; k=0; } for(long j=0;j(a+nx*(i+k+ny*(j+kz)),nx,x); tz[j] = mglSpline1st(t,m,y-k); } b = mglSpline1st(tz,mz,z-kz); } else if(ny>1) // 2d interpolation { Treal t[4]; long k = long(y)-1, m; if(ny>3) { m = 4; k = k>=0?k:0; if(k>ny-4) k = ny-4; } else { m = ny; k=0; } for(long i=0;i(a+nx*(i+k),nx,x); b = mglSpline1st(t,m,y-k); } else // 1d interpolation b = mglSpline1st(a,nx,x); return b; } //----------------------------------------------------------------------------- template void mgl_gspline_init(long n, const mreal *x, const Treal *v, Treal *c) { // c must have size 5*(n-1) !!! // if(n<2) return; // NOTE remove this line because this should already checked Treal *a = new Treal[n], *b = new Treal[n]; for(long i=0;i=0;i--) b[i] += a[i]*b[i+1]; // no spline coefficients for(long i=0;i str; HAEX *eqC; HMEX *eqR; const char *var; mglEqTxT(const char *vars=0):eqC(0),eqR(0),var(vars) {} ~mglEqTxT() { if(eqR) { for(size_t i=0;i * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/data.h" #include "mgl2/datac.h" #include "mgl2/eval.h" #include "mgl2/thread.h" #include "mgl2/base.h" #include "interp.hpp" const double GAMMA=0.1; ///< value for damping HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector &head); //----------------------------------------------------------------------------- // // Advanced PDE series in 2D case // //----------------------------------------------------------------------------- void static mgl_operator_exp(long n, const dual *h, dual *a, dual *f) { memset(f,0,2*n*sizeof(dual)); const long i1=n/2, i2=3*n/2-1; #pragma omp parallel for for(long j=0;jn-1) ii=n-1; double kk=M_PI*2*i/n; for(long j=0;jn-1) ii=n-1; const dual *ie1=iexp+2*n*i; // double kk=M_PI*2*i/n; for(long j=0;j list, const mreal dd) { HADT ham = mglFormulaCalcC(func, list); mgl_datac_mul_num(ham,dd); const long nx = ham->nx; if(old) { mreal hh = ham->Imag().Minimal(); if(hh>0) hh=0; #pragma omp parallel for for(long i=0;ia[i] = sqrt(imag(ham->a[i])-hh); // non-additive term ham->a[i] = dual(real(ham->a[i]),hh); // additive terms } } else { mglData xIm(nx), pIm(nx); #pragma omp parallel for for(long i=0;ia+i, *ay=ham->a+i*nx; mreal mx=imag(ax[0]), my=imag(ay[0]); for(long j=1;ja[i0] = sqrt(fabs(imag(ham->a[i0])-hh)); // non-additive term. NOTE: fabs() guarantee absence of negative values due to rounding error ham->a[i0] = dual(real(ham->a[i0]),hh); // additive terms } } return ham; } //----------------------------------------------------------------------------- // Solve equation dx/dy = func(p,x,y,|u|)[u] where p=d/dx. There are no assumptions about form of func(). HADT MGL_EXPORT mgl_pde_adv_c(HMGL gr, const char *func, HCDT ini_re, HCDT ini_im, mreal dt, mreal k0, const char *opt) { mreal gamma = gr->SaveState(opt); if(mgl_isnan(gamma)) gamma = 20; const mglPoint &Min=gr->Min, &Max=gr->Max; const long nx=ini_re->GetNx(), nt = long((Max.y-Min.y)/dt)+1; if(nx<2 || nt<2 || Max.x==Min.x){ gr->SetWarn(mglWarnLow,"PDE"); return 0; } // Too small data if(ini_im->GetNx() != nx) { gr->SetWarn(mglWarnDim,"PDE"); return 0; } // Wrong dimensions mglDataC *res=new mglDataC(nx, nt); mglData hIm(nx,nx); // for advanced damping calculation mglDataC u(nx); u.Name(L"u"); mglDataV x(nx,nx), y(nx,nx), r(nx,nx); mglDataW p(nx,nx); p.Name(L"p"); bool old = func[0]==';'; if(old) func=func+1; x.Name(L"x"); y.Name(L"y"); r.Name(L"#$mgl"); const mreal dp = 2*M_PI/(Max.x-Min.x), dd = k0*dt/2; x.Fill(Min.x,Max.x,'x'); p.Freq(dp/k0,'y'); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&p); list.push_back(&r); list.push_back(&u); dual *a = new dual[2*nx]; memset(a,0,2*nx*sizeof(dual)); // Add "damping" area dual *f = new dual[6*nx], *g=f+2*nx, *s=f+4*nx; #pragma omp parallel for for(long i=0;iv(i), ini_im->v(i)); double *dmp = new double[2*nx]; memset(dmp,0,2*nx*sizeof(double)); #pragma omp parallel for for(long i=0;i<2*nx;i++) // dumping { if(i3*nx/2) dmp[i] += gamma*mgl_ipow((i-3*nx/2-1)/mreal(nx/2),2); } bool have_y = mglchr(func,'y'); HADT ham; if(!have_y) ham = mgl_apde_calc_ham(&hIm, old, func, list, dd); dual *iexp = new dual[4*nx*nx]; #pragma omp parallel for collapse(2) for(long j=0;j<2*nx;j++) for(long i=0;i<2*nx;i++) iexp[i+2*nx*j] = exp(dual(0,(M_PI*i*j)/nx)); for(long k=0;ka+k*nx,a+nx/2,nx*sizeof(dual)); if(have_y) { y.Fill(k*dt); ham = mgl_apde_calc_ham(&hIm, old, func, list, dd); } mgl_operator_exp(nx,ham->a,a,f); mgl_operator_lin(nx,hIm.a,a,f,g,s,iexp); mgl_operator_lin(nx,hIm.a,s,f,g,s,iexp); #pragma omp parallel for for(long i=0;i<2*nx;i++) a[i] = (a[i]-s[i]/mreal(8*nx*nx))*mreal(exp(-dmp[i]*dt)/2/nx); if(have_y) delete ham; } delete []a; delete []f; delete []dmp; delete []iexp; if(!have_y) delete ham; gr->LoadState(); return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_pde_adv(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt) { HADT res = mgl_pde_adv_c(gr,ham,ini_re,ini_im,dz,k0,opt); HMDT out = mgl_datac_abs(res); delete res; return out; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_pde_adv_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t res = uintptr_t(mgl_pde_adv_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o)); delete []o; delete []s; return res; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_pde_adv_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t res = uintptr_t(mgl_pde_adv(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o)); delete []o; delete []s; return res; } //----------------------------------------------------------------------------- // // Simplified PDE series // //----------------------------------------------------------------------------- struct mgl_pde_ham { dual *a,*hxy,*hxv,*huv,*huy; const char *eqs; long nx,ny; double xx,yy,xs,ys,dx,dy,dq,dp,zz; double dd; }; void static mgl_pde_hprep(const mgl_pde_ham *f) { const long nx = f->nx, ny = f->ny; mglDataV x(nx,ny), y(nx,ny), z, r(nx,ny); mglDataW p(nx,ny), q(nx,ny); x.Name(L"x"); y.Name(L"y"); p.Name(L"p"); q.Name(L"q"); r.Name(L"#$mgl"); z.Name(L"z"); z.Fill(f->zz); dual dd(0,f->dd); mglData u(nx,ny); u.Name(L"u"); #pragma omp parallel for for(long i=0;ia[i]); std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&p); list.push_back(&q); list.push_back(&u); x.Fill(f->xx,f->xx+f->dx*(nx-1),'x'); p.Freq(0,'x'); y.Fill(f->yy,f->yy+f->dy*(ny-1),'y'); q.Freq(0,'y'); HADT res = mglFormulaCalcC(f->eqs, list); #pragma omp parallel for for(long i=0;ihxy[i] = res->a[i]*dd; delete res; if(ny>2) { x.Fill(f->xs); p.Freq(f->dp,'x'); res = mglFormulaCalcC(f->eqs, list); #pragma omp parallel for for(long i=0;ihuy[i] = res->a[i]*dd; delete res; } x.Fill(f->xs); p.Freq(f->dp,'x'); y.Fill(f->ys); q.Freq(f->dq,'y'); res = mglFormulaCalcC(f->eqs, list); #pragma omp parallel for for(long i=0;ihuv[i] = res->a[i]*dd; delete res; if(ny>2) { x.Fill(f->xx,f->xx+f->dx*(nx-1),'x'); p.Freq(0,'x'); res = mglFormulaCalcC(f->eqs, list); #pragma omp parallel for for(long i=0;ihxv[i] = res->a[i]*dd; delete res; } } //----------------------------------------------------------------------------- // Solve equation dx/dz = func(p,q,x,y,z,|u|)[u] where p=d/dx, q=d/dy. At this moment simplified form of ham is supported: ham = f(p,q,z) + g(x,y,z,'u'), where variable 'u'=|u| (for allowing solve nonlinear problems). You may specify imaginary part like ham = p^2 + 1i*x*(x>0). HADT MGL_EXPORT mgl_pde_solve_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt) { mreal gamma = gr->SaveState(opt); if(mgl_isnan(gamma)) gamma = GAMMA; mglPoint Min=gr->Min, Max=gr->Max; long nx=ini_re->GetNx(), ny=ini_re->GetNy(), nz = long((Max.z-Min.z)/dz)+1; if(nx<2 || nz<2 || Max.x==Min.x) // Too small data { gr->SetWarn(mglWarnLow,"PDE"); return 0; } if(ini_im->GetNx()*ini_im->GetNy() != nx*ny)// Wrong dimensions { gr->SetWarn(mglWarnDim,"PDE"); return 0; } mglDataC *res=new mglDataC(nz, nx, ny); dual *a = new dual[4*nx*ny], hh0; // Add "damping" area dual *hxy = new dual[4*nx*ny], *hxv = new dual[4*nx*ny]; dual *huy = new dual[4*nx*ny], *huv = new dual[4*nx*ny]; dual *hx = new dual[2*nx], *hv = new dual[2*ny]; dual *hy = new dual[2*ny], *hu = new dual[2*nx]; double *dmp = new double[4*nx*ny]; memset(a,0,4*nx*ny*sizeof(dual)); memset(dmp,0,4*nx*ny*sizeof(double)); #pragma omp parallel for collapse(2) for(long j=0;jv(i,j), ini_im->v(i,j)); res->a[nz*(i+nx*j)] = a[i0]; } #pragma omp parallel for collapse(2) for(long j=0;j<2*ny;j++) for(long i=0;i<2*nx;i++) // step 1 { long i0 = i+2*nx*j; if(i3*nx/2) dmp[i0] += gamma*mgl_ipow((i-3*nx/2-1)/(nx/2.),2); if(j3*ny/2) dmp[i0] += gamma*mgl_ipow((j-3*ny/2-1)/(ny/2.),2); } mreal dx = (Max.x-Min.x)/(nx-1), dy = ny>1?(Max.y-Min.y)/(ny-1):0; mreal dp = M_PI/(Max.x-Min.x)/k0, dq = M_PI/(Max.y-Min.y)/k0; mreal xs=(Min.x+Max.x)/2, ys=(Min.y+Max.y)/2; double dd = k0*dz; mgl_pde_ham tmp;tmp.eqs = ham; tmp.nx = 2*nx; tmp.ny = 2*ny; tmp.dd = dd; tmp.a=a; tmp.hxy=hxy; tmp.hxv=hxv; tmp.huy=huy; tmp.huv=huv; tmp.xx = Min.x-dx*(nx/2); tmp.xs = xs; tmp.dx = dx; tmp.dp = dp; tmp.yy = Min.y-dy*(ny/2); tmp.ys = ys; tmp.dy = dy; tmp.dq = dq; // prepare fft. NOTE: slow procedures due to unknown nx, ny. void *wtx = mgl_fft_alloc(2*nx,0,0); void *wty = mgl_fft_alloc(2*ny,0,0); for(long k=1;kNeedStop()) break; tmp.zz = Min.z+dz*k; memset(hxy,0,4*nx*ny*sizeof(dual)); memset(hxv,0,4*nx*ny*sizeof(dual)); memset(huv,0,4*nx*ny*sizeof(dual)); memset(huy,0,4*nx*ny*sizeof(dual)); mgl_pde_hprep(&tmp); for(long i=0;i<2*nx;i++) { hx[i] = hxv[i]; hu[i] = huv[i]; } for(long j=0;j<2*ny;j++) { hy[j] = huy[2*nx*j]; hv[j] = huv[2*nx*j];} // rearrange arrays hh0=hu[0]; if(ny>1) #pragma omp parallel for collapse(2) for(long j=0;j<2*ny;j++) for(long i=0;i<2*nx;i++) { long i0 = i+2*nx*j; huv[i0] -= hh0; hxv[i0] -= hx[i]+hv[j]-hh0; huy[i0] -= hu[i]+hy[j]-hh0; } else #pragma omp parallel for for(long i=0;i<4*nx*ny;i++) huv[i] -= hh0; // solve equation if(ny>1) #pragma omp parallel { void *wsx = mgl_fft_alloc_thr(2*nx), *wsy = mgl_fft_alloc_thr(2*ny); #pragma omp for for(long i=0;i<4*nx*ny;i++) a[i] *= exp(hxy[i]-double(dmp[i]*dz)); #pragma omp for for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, false); #pragma omp for for(long i=0;i<4*nx*ny;i++) a[i] *= exp(huy[i]); #pragma omp for for(long i=0;i<2*nx;i++) mgl_fft((double *)(a+i), 2*nx, 2*ny, wty, wsy, false); #pragma omp for for(long i=0;i<4*nx*ny;i++) a[i] *= exp(huv[i]); #pragma omp for for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+2*i*nx), 1, 2*nx, wtx, wsx, true); #pragma omp for for(long i=0;i<4*nx*ny;i++) a[i] *= exp(hxv[i]); #pragma omp for for(long i=0;i<2*nx;i++) mgl_fft((double *)(a+i), 2*nx, 2*ny, wty, wsy, true); mgl_fft_free_thr(wsx); mgl_fft_free_thr(wsy); } else #pragma omp parallel { void *wsx = mgl_fft_alloc_thr(2*nx); #pragma omp for for(long i=0;i<4*nx*ny;i++) a[i] *= exp(hxy[i]-double(dmp[i]*dz)); #pragma omp for for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, false); #pragma omp for for(long i=0;i<4*nx*ny;i++) a[i] *= exp(huv[i]); #pragma omp for for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+2*i*nx), 1, 2*nx, wtx, wsx, true); mgl_fft_free_thr(wsx); } #pragma omp parallel for collapse(2) for(long j=0;ja[k+nz*(i+nx*j)] = a[i+nx/2+2*nx*(j+ny/2)]; } mgl_fft_free(wtx,0,0); mgl_fft_free(wty,0,0); delete []a; delete []dmp; delete []hxy; delete []hxv; delete []huy; delete []huv; delete []hx; delete []hy; delete []hu; delete []hv; gr->LoadState(); return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt) { HADT res = mgl_pde_solve_c(gr,ham,ini_re,ini_im,dz,k0,opt); HMDT out = mgl_datac_abs(res); delete res; return out; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_pde_solve_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t res = uintptr_t(mgl_pde_solve_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o)); delete []o; delete []s; return res; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t res = uintptr_t(mgl_pde_solve(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o)); delete []o; delete []s; return res; } //----------------------------------------------------------------------------- // // ODE series // //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_txt_func(const mreal *x, mreal *dx, void *par) { mglEqTxT *p=(mglEqTxT *)par; mreal vars[MGL_VS]; size_t n = p->str.size(); for(size_t i=0;ivar[i]; if(ch>='a' && ch<='z') vars[ch-'a']=x[i]; } #pragma omp parallel for for(long i=0;ieqR[i], vars); } HMDT MGL_EXPORT mgl_ode_solve_str(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax) { if(!var || !(*var) || !func) return 0; mglEqTxT par; par.var=var; par.FillReal(func); size_t n = par.str.size(); mreal *xx = new mreal[n]; for(size_t i=0;ivthr(i):0; HMDT res = mgl_ode_solve_ex(mgl_txt_func,n,xx,dt,tmax,&par,NULL); delete []xx; return res; } //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_txt_funcC(const mreal *x, mreal *dx, void *par) { mglEqTxT *p=(mglEqTxT *)par; mdual vars[MGL_VS]; size_t n = p->str.size(); for(size_t i=0;ivar[i]; if(ch>='a' && ch<='z') vars[ch-'a']=dual(x[2*i],x[2*i+1]); } #pragma omp parallel for for(long i=0;ieqC[i], vars); dx[2*i] = real(r); dx[2*i+1] = imag(r); } } HADT MGL_EXPORT mgl_ode_solve_str_c(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax) { if(!var || !(*var) || !func) return 0; mglEqTxT par; par.var=var; par.var=var; par.FillCmplx(func); size_t n = par.str.size(); mreal *xx = new mreal[2*n]; const mglDataC *c = dynamic_cast(x0); for(size_t i=0;ia[i]); xx[2*i+1]=imag(c->a[i]); } else { xx[2*i] = x0?x0->vthr(i):0; xx[2*i+1]=0; } } HMDT res = mgl_ode_solve_ex(mgl_txt_funcC,2*n,xx,dt,tmax,&par,NULL); delete []xx; const long nn=n, nt=res->ny; mglDataC *out = new mglDataC(nn, nt); #pragma omp parallel for for(long i=0;ia[i] = dual(res->a[2*i],res->a[2*i+1]); delete res; return out; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par) { return mgl_ode_solve_ex(func,n,x0,dt,tmax,par,0); } HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par, void (*bord)(mreal *x, const mreal *xp, void *par)) { if(tmaxa[i] = x0[i]; // Runge Kutta scheme of 4th order bool good=true; long k; for(k=1;ka+n*(k-1),par); for(long i=0;ia[i+n*k] = x[i]; if(mgl_isbad(x[i])) good=false; } } delete []x; delete []k1; delete []k2; delete []k3; delete []v; res->Crop(0,k,'y'); return res; } //----------------------------------------------------------------------------- // // Common functions for quasioptical calculations // //----------------------------------------------------------------------------- void static mgl_ray3d(const mreal *in, mreal *out, void *par) { mglFormula *eqs = (mglFormula *)par; const char *v="xyzpqvt"; mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal)); for(int i=0;i<7;i++) var[v[i]-'a'] = in[i]; out[0] = eqs->CalcD(var,'p'); out[3] = -eqs->CalcD(var,'x'); out[1] = eqs->CalcD(var,'q'); out[4] = -eqs->CalcD(var,'y'); out[2] = eqs->CalcD(var,'v'); out[5] = -eqs->CalcD(var,'z'); out[7] = eqs->CalcD(var,'i'); out[6] = 1; } // Solve GO ray equation like dr/dt = d ham/dp, dp/dt = -d ham/dr where ham = ham(x,y,z,p,q,v,t) and px=p, py=q, pz=v. The starting point (at t=0) is r0, p0. Result is array of {x,y,z,p,q,v,t} HMDT MGL_EXPORT mgl_ray_trace(const char *ham, mreal x0, mreal y0, mreal z0, mreal px, mreal py, mreal pz, mreal dt, mreal tmax) { mglFormula eqs(ham); mreal in[8]={x0,y0,z0,px,py,pz,0,0}; HMDT res = mgl_ode_solve(mgl_ray3d,8,in,dt,tmax,&eqs); mgl_data_set_id(res,"xyzpqvti"); return res; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int l) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; uintptr_t res = uintptr_t(mgl_ray_trace(s, *x0,*y0,*z0, *px,*py,*pz, *dt,*tmax)); delete []s; return res; } //----------------------------------------------------------------------------- struct mgl_ap { double x0,y0,z0,x1,y1,z1,x2,y2,z2; // vectors {l, g1, g2} double t1,t2,ch,q1,q2,pt,dt,d1,d2; // theta_{1,2}, chi, q_{1,2}, p_t, dtau, dq_{1,2} mgl_ap() { memset(this,0,sizeof(mgl_ap)); } }; //----------------------------------------------------------------------------- void static mgl_init_ra(long n, int n7, const mreal *r, mgl_ap *ra) // prepare some intermediate data for QO (3d case) { double tt = hypot(r[n7]-r[0], r[n7+1]-r[1]); if(tt) { ra[0].x1 = (r[n7+1]-r[1])/tt; ra[0].y1 = (r[0]-r[n7])/tt; ra[0].z1 = 0; } else { ra[0].x1 = ra[0].y1 = 0; ra[0].z1 = 1; } ra[0].x0 = r[n7] - r[0]; ra[0].y0 = r[n7+1] - r[1]; ra[0].z0 = r[n7+2] - r[2]; tt = sqrt(ra[0].x0*ra[0].x0 + ra[0].y0*ra[0].y0 + ra[0].z0*ra[0].z0); ra[0].x0 /= tt; ra[0].y0 /= tt; ra[0].z0 /= tt; ra[0].x2 = ra[0].y1*ra[0].z0 - ra[0].y0*ra[0].z1; // vector g_2 ra[0].y2 = ra[0].z1*ra[0].x0 - ra[0].z0*ra[0].x1; ra[0].z2 = ra[0].x1*ra[0].y0 - ra[0].x0*ra[0].y1; for(long i=1;idt = rr[6] - rr[6-n7]; ri->x0 = rr[0] - rr[-n7]; // NOTE: very rough formulas ri->y0 = rr[1] - rr[1-n7]; // for corresponding with dt one ri->z0 = rr[2] - rr[2-n7]; // for corresponding with dt one double ch = sqrt(ri->x0*ri->x0 + ri->y0*ri->y0 + ri->z0*ri->z0); ri->x0 /= ch; ri->y0 /= ch; ri->z0 /= ch; ri->ch = ch/ri->dt; ri->pt = rr[3]*ri->x0 + rr[4]*ri->y0 + rr[5]*ri->z0; ri->q1 = rr[3]*ri->x1 + rr[4]*ri->y1 + rr[5]*ri->z1; ri->q2 = rr[3]*ri->x2 + rr[4]*ri->y2 + rr[5]*ri->z2; // NOTE previous point is used here! tt = ri->x0*rp->x1 + ri->y0*rp->y1 + ri->z0*rp->z1; ri->x1 = rp->x1 - tt*ri->x0; // vector g_1 ri->y1 = rp->y1 - tt*ri->y0; ri->z1 = rp->z1 - tt*ri->z0; ri->t1 = tt/ch; tt = sqrt(ri->x1*ri->x1 + ri->y1*ri->y1 + ri->z1*ri->z1); ri->x1 /= tt; ri->y1 /= tt; ri->z1 /= tt; // norm for reducing numeric error ri->x2 = ri->y1*ri->z0 - ri->y0*ri->z1; // vector g_2 ri->y2 = ri->z1*ri->x0 - ri->z0*ri->x1; ri->z2 = ri->x1*ri->y0 - ri->x0*ri->y1; tt = ri->x0*rp->x2 + ri->y0*rp->y2 + ri->z0*rp->z2; ri->t2 = tt/ch; ri->d1 = (ri->q1-rp->q1)/ch; ri->d2 = (ri->q2-rp->q2)/ch; } memcpy(ra,ra+1,sizeof(mgl_ap)); // setup zero point ra[0].pt = r[3]*ra[0].x0 + r[4]*ra[0].y0 + r[5]*ra[0].z0; ra[0].q1 = r[3]*ra[0].x1 + r[4]*ra[0].y1 + r[5]*ra[0].z1; ra[0].q2 = r[3]*ra[0].x2 + r[4]*ra[0].y2 + r[5]*ra[0].z2; } //----------------------------------------------------------------------------- // // QO2d series // //----------------------------------------------------------------------------- struct mgl_qo2d_ham { dual *hx, *hu, *a, h0; double *dmp, dr, dk; mreal *r; mgl_ap *ra; mdual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par); void *par; }; //----------------------------------------------------------------------------- static void *mgl_qo2d_hprep(void *par) { mglThreadD *t=(mglThreadD *)par; mgl_qo2d_ham *f = (mgl_qo2d_ham *)t->v; mgl_ap *ra = f->ra; const mreal *r = f->r; const long nx=t->n; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;idr, hh = 1 - ra->t1*x1; hh = sqrt(sqrt(0.041+hh*hh*hh*hh)); mreal tt = (ra->pt + ra->d1*x1)/hh - ra->pt; dual tmp = f->ham(abs(f->a[i]), r[0]+ra->x1*x1, r[1]+ra->y1*x1, r[3]+ra->x0*tt, r[4]+ra->y0*tt, f->par); f->hx[i] = tmp - f->h0/2.; // u-y terms x1 = f->dk/2*(iham(0, r[0], r[1], r[3]+ra->x1*x1, r[4]+ra->y1*x1, f->par); f->hu[i] = tmp - f->h0/2.; if(imag(f->hx[i])>0) f->hx[i] = f->hx[i].real(); if(imag(f->hu[i])>0) f->hu[i] = f->hu[i].real(); // add boundary conditions for x-direction f->hx[i] -= dual(0,f->dmp[i]); } return 0; } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_qo2d_func_c(mdual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy) { const mglData *ray=dynamic_cast(ray_dat); // NOTE: Ray must be mglData! if(!ray) return 0; const long nx=ini_re->GetNx(), nt=ray->ny, n7=ray->nx; if(nx<2 || ini_im->GetNx()!=nx || nt<2) return 0; mglDataC *res=new mglDataC(nx,nt,1); dual *a=new dual[2*nx], *hu=new dual[2*nx], *hx=new dual[2*nx]; double *dmp=new double[2*nx]; mgl_ap *ra = new mgl_ap[nt]; mgl_init_ra(nt, n7, ray->a, ra); // ray mreal dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx); memset(dmp,0,2*nx*sizeof(double)); for(long i=0;iv(i),ini_im->v(i)); // init void *wsx, *wtx = mgl_fft_alloc(2*nx,&wsx,1); if(xx && yy) { xx->Create(nx,nt); yy->Create(nx,nt); } mgl_qo2d_ham tmp; // parameters for Hamiltonian calculation tmp.hx=hx; tmp.hu=hu; tmp.dmp=dmp; tmp.par=par; tmp.dr=dr; tmp.dk=dk; tmp.ham=ham; tmp.a=a; // start calculation for(long k=0;ka[i+k*nx]=a[i+nx/2]*sqrt(ra[0].ch/ra[k].ch); if(xx && yy) for(long i=0;ia[i+k*nx] = ray->a[n7*k] + ra[k].x1*x1; // new coordinates yy->a[i+k*nx] = ray->a[n7*k+1] + ra[k].y1*x1; } tmp.r=ray->a+n7*k; tmp.ra=ra+k; mreal hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1); // 0.041=0.45^4 -- minimal value of h tmp.h0 = ham(0, tmp.r[0], tmp.r[1], tmp.r[3]+ra[k].x0*hh, tmp.r[4]+ra[k].x0*hh, par); mglStartThread(mgl_qo2d_hprep,0,2*nx,0,0,0,0,&tmp); // Step for field dual dt = dual(0, -ra[k].dt*k0); for(long i=0;i<2*nx;i++) a[i] *= exp(hx[i]*dt); mgl_fft((double *)a, 1, 2*nx, wtx, wsx, false); for(long i=0;i<2*nx;i++) a[i] *= exp(hu[i]*dt); mgl_fft((double *)a, 1, 2*nx, wtx, wsx, true); /* // Calculate B1 // TODO make more general scheme later!!! hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1); var['x'-'a'] = ray->a[n7*k]; // new coordiantes var['y'-'a'] = ray->a[n7*k+1]; var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh; tt = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1; var['x'-'a'] = ray->a[n7*k] + ra[k].x1*dr; // new coordiantes var['y'-'a'] = ray->a[n7*k+1] + ra[k].y1*dr; hh = 1 - ra[k].t1*dr; hh = sqrt(sqrt(0.041+hh*hh*hh*hh)); hh = (ra[k].ch*ra[k].pt + ra[k].d1*dr)/(hh*ra[k].ch) - ra[k].pt; var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh; B1 = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1; B1 = (B1-tt)/dr; double a1=0, a2=0; for(i=0;i<2*nx;i++) a1 += norm(a[i]); hx[0] = hx[2*nx-1] = 0.; for(i=1;i<2*nx-1;i++) hx[i] = (B1*ra[k].dt*(i-nx))*(a[i+1]-a[i-1]); for(i=0;i<2*nx;i++) { a[i] += hx[i]; a2 += norm(a[i]); } a1 = sqrt(a1/a2); for(i=0;i<2*nx;i++) a[i] *= a1;*/ } mgl_fft_free(wtx,&wsx,1); delete []a; delete []hu; delete []hx; delete []ra; delete []dmp; return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_qo2d_func(mdual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy) { HADT res = mgl_qo2d_func_c(ham,par,ini_re,ini_im,ray_dat,r,k0,xx,yy); HMDT out = mgl_datac_abs(res); delete res; return out; } //----------------------------------------------------------------------------- mdual static mgl_ham2d(mreal u, mreal x, mreal y, mreal px, mreal py, void *par) { mglFormula *h = (mglFormula *)par; mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal)); var['x'-'a'] = x; var['y'-'a'] = y; var['u'-'a'] = u; var['p'-'a'] = px; var['q'-'a'] = py; return mdual(h->Calc(var), -h->CalcD(var,'i')); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_qo2d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy) { mglFormula h(ham); return mgl_qo2d_func_c(mgl_ham2d, &h, ini_re, ini_im, ray_dat, r, k0, xx, yy); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy) { HADT res = mgl_qo2d_solve_c(ham,ini_re,ini_im,ray_dat,r,k0,xx,yy); HMDT out = mgl_datac_abs(res); delete res; return out; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int l) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; uintptr_t res = uintptr_t(mgl_qo2d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy))); delete []s; return res; } //----------------------------------------------------------------------------- // // QO3d series // //----------------------------------------------------------------------------- struct mgl_qo3d_ham { dual *hxy, *huv, *hxv, *huy, *a; dual *hx, *hy, *hu, *hv, h0; double *dmp, dr, dk; mreal *r; mgl_ap *ra; mdual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par); void *par; }; //----------------------------------------------------------------------------- static void *mgl_qo3d_hprep(void *par) { mglThreadD *t=(mglThreadD *)par; mgl_qo3d_ham *f = (mgl_qo3d_ham *)t->v; mgl_ap *ra = f->ra; const mreal *r = f->r; const long nx=t->n; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long ii=t->id;iidr, x2 = (2*j-nx+1)*f->dr, hh = 1-ra->t1*x1-ra->t2*x2; hh = sqrt(sqrt(0.041+hh*hh*hh*hh)); mreal tt = (ra->pt + ra->d1*x1 + ra->d2*x2)/hh - ra->pt; f->hxy[ii] = f->ham(abs(f->a[i]), r[0]+ra->x1*x1+ra->x2*x2, r[1]+ra->y1*x1+ra->y2*x2, r[2]+ra->z1*x1+ra->z2*x2, r[3]+ra->x0*tt, r[4]+ra->y0*tt, r[5]+ra->z0*tt, f->par); // x-v terms x1 = (2*i-nx+1)*f->dr; x2 = f->dk/2*(jt1*x1; hh = sqrt(sqrt(0.041+hh*hh*hh*hh)); tt = (ra->pt + ra->d1*x1)/hh - ra->pt; f->hxv[ii] = f->ham(0, r[0]+ra->x1*x1, r[1]+ra->y1*x1, r[2]+ra->z1*x1, r[3]+ra->x0*tt+ra->x2*x2, r[4]+ra->y0*tt+ra->y2*x2, r[5]+ra->z0*tt+ra->z2*x2, f->par); // u-y terms x1 = f->dk/2*(idr; hh = 1-ra->t2*x2; hh = sqrt(sqrt(0.041+hh*hh*hh*hh)); tt = (ra->pt + ra->d2*x2)/hh - ra->pt; f->huy[ii] = f->ham(0, r[0]+ra->x2*x2, r[1]+ra->y2*x2, r[2]+ra->z2*x2, r[3]+ra->x1*x1+ra->x0*tt, r[4]+ra->y1*x1+ra->y0*tt, r[5]+ra->z1*x1+ra->z0*tt, f->par); // u-y terms x1 = f->dk/2*(idk/2*(jhuv[ii] = f->ham(0, r[0], r[1], r[2], r[3]+ra->x1*x1+ra->x2*x2, r[4]+ra->y1*x1+ra->y2*x2, r[5]+ra->z1*x1+ra->z2*x2, f->par); } return 0; } //----------------------------------------------------------------------------- static void *mgl_qo3d_post(void *par) { mglThreadD *t=(mglThreadD *)par; mgl_qo3d_ham *f = (mgl_qo3d_ham *)t->v; const long nx=t->n; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long ii=t->id;iihxy[ii] -= (f->hx[i]+f->hy[j]-f->h0/2.)/2.; if(imag(f->hxy[ii])>0) f->hxy[ii] = f->hxy[ii].real(); f->hxv[ii] -= (f->hx[i]+f->hv[j]-f->h0/2.)/2.; if(imag(f->hxv[ii])>0) f->hxv[ii] = f->hxv[ii].real(); f->huy[ii] -= (f->hu[i]+f->hy[j]-f->h0/2.)/2.; if(imag(f->huy[ii])>0) f->huy[ii] = f->huy[ii].real(); f->huv[ii] -= (f->hu[i]+f->hv[j]-f->h0/2.)/2.; if(imag(f->huv[ii])>0) f->huv[ii] = f->huv[ii].real(); // add boundary conditions for x-direction f->hxy[ii] -= dual(0,f->dmp[ii]); } return 0; } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_qo3d_func_c(mdual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz) { const mglData *ray=dynamic_cast(ray_dat); // NOTE: Ray must be mglData! if(!ray) return 0; const long nx=ini_re->GetNx(), nt=ray->ny, n7=ray->nx; // NOTE: only square grids are supported now (for simplicity) if(nx<2 || ini_re->GetNx()!=nx || ini_im->GetNx()*ini_im->GetNy()!=nx*nx || nt<2) return 0; mglDataC *res=new mglDataC(nx,nx,nt); dual *a=new dual[4*nx*nx], *huv=new dual[4*nx*nx], *hxy=new dual[4*nx*nx], *huy=new dual[4*nx*nx], *hxv=new dual[4*nx*nx]; dual *hu=new dual[2*nx], *hx=new dual[2*nx], *hy=new dual[2*nx], *hv=new dual[2*nx]; double *dmp=new double[4*nx*nx]; mgl_ap *ra = new mgl_ap[nt]; mgl_init_ra(nt, n7, ray->a, ra); // prepare ray double dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx); memset(dmp,0,4*nx*nx*sizeof(double)); #pragma omp parallel for collapse(2) for(long i=0;iv(i,j),ini_im->v(i,j)); void *wtx = mgl_fft_alloc(2*nx,0,0); if(xx && yy && zz) { xx->Create(nx,nx,nt); yy->Create(nx,nx,nt); zz->Create(nx,nx,nt); } mgl_qo3d_ham tmp; // parameters for Hamiltonian calculation tmp.hxy=hxy; tmp.hx=hx; tmp.huv=huv; tmp.hu=hu; tmp.huy=huy; tmp.hy=hy; tmp.hxv=hxv; tmp.hv=hv; tmp.dmp=dmp; tmp.par=par; tmp.dr=dr; tmp.dk=dk; tmp.ham=ham; tmp.a=a; // start calculation for(long k=0;ka[i+nx*(j+k*nx)]=a[i+nx/2+2*nx*(j+nx/2)]*sqrt(ra[0].ch/ra[k].ch); if(xx && yy && zz) #pragma omp parallel for collapse(2) for(long i=0;ia[i+nx*(j+k*nx)] = ray->a[n7*k] + ra[k].x1*x1 + ra[k].x2*x2; // new coordinates yy->a[i+nx*(j+k*nx)] = ray->a[n7*k+1] + ra[k].y1*x1 + ra[k].y2*x2; zz->a[i+nx*(j+k*nx)] = ray->a[n7*k+2] + ra[k].z1*x1 + ra[k].z2*x2; } tmp.r=ray->a+n7*k; tmp.ra=ra+k; mglStartThread(mgl_qo3d_hprep,0,2*nx,0,0,0,0,&tmp); tmp.h0 = huv[0]; for(long i=0;i<2*nx;i++) // fill intermediate arrays { tmp.hx[i] = hxv[i]; tmp.hy[i] = huy[i*2*nx]; tmp.hv[i] = huv[i]; tmp.hu[i] = huv[i*2*nx]; } mglStartThread(mgl_qo3d_post,0,2*nx,0,0,0,0,&tmp); // Step for field dual dt = dual(0, -ra[k].dt*k0); #pragma omp parallel { void *wsx = mgl_fft_alloc_thr(2*nx); #pragma omp for for(long i=0;i<4*nx*nx;i++) a[i] *= exp(hxy[i]*dt); // x-y #pragma omp for for(long i=0;i<2*nx;i++) // x->u mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, false); #pragma omp for for(long i=0;i<4*nx*nx;i++) a[i] *= exp(huy[i]*dt); // u-y #pragma omp for for(long i=0;i<2*nx;i++) // y->v mgl_fft((double *)(a+i), 2*nx, 2*nx, wtx, wsx, false); #pragma omp for for(long i=0;i<4*nx*nx;i++) a[i] *= exp(huv[i]*dt); // u-v #pragma omp for for(long i=0;i<2*nx;i++) // u->x mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, true); #pragma omp for for(long i=0;i<4*nx*nx;i++) a[i] *= exp(hxv[i]*dt); // x-v #pragma omp for for(long i=0;i<2*nx;i++) // v->y mgl_fft((double *)(a+i), 2*nx, 2*nx, wtx, wsx, true); mgl_fft_free_thr(wsx); } /* // Calculate B1 // TODO make more general scheme later!!! hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1); var['x'-'a'] = ray->a[n7*k]; // new coordiantes var['y'-'a'] = ray->a[n7*k+1]; var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh; tt = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1; var['x'-'a'] = ray->a[n7*k] + ra[k].x1*dr; // new coordiantes var['y'-'a'] = ray->a[n7*k+1] + ra[k].y1*dr; hh = 1 - ra[k].t1*dr; hh = sqrt(sqrt(0.041+hh*hh*hh*hh)); hh = (ra[k].ch*ra[k].pt + ra[k].d1*dr)/(hh*ra[k].ch) - ra[k].pt; var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh; B1 = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1; B1 = (B1-tt)/dr; double a1=0, a2=0; for(i=0;i<2*nx;i++) a1 += norm(a[i]); hx[0] = hx[2*nx-1] = 0.; for(i=1;i<2*nx-1;i++) hx[i] = (B1*ra[k].dt*(i-nx))*(a[i+1]-a[i-1]); for(i=0;i<2*nx;i++) { a[i] += hx[i]; a2 += norm(a[i]); } a1 = sqrt(a1/a2); for(i=0;i<2*nx;i++) a[i] *= a1;*/ } mgl_fft_free(wtx,0,0); delete []a; delete []ra; delete []dmp; delete []huv; delete []hxy; delete []hxv; delete []huy; delete []hu; delete []hx; delete []hv; delete []hy; return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_qo3d_func(mdual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz) { HADT res = mgl_qo3d_func_c(ham,par,ini_re,ini_im,ray_dat,r,k0,xx,yy,zz); HMDT out = mgl_datac_abs(res); delete res; return out; } //----------------------------------------------------------------------------- mdual static mgl_ham3d(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par) { mglFormula *h = (mglFormula *)par; mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal)); var['x'-'a'] = x; var['y'-'a'] = y; var['z'-'a'] = z; var['u'-'a'] = u; var['p'-'a'] = px; var['q'-'a'] = py; var['v'-'a'] = pz; return mdual(h->Calc(var), -h->CalcD(var,'i')); } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_qo3d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz) { mglFormula h(ham); return mgl_qo3d_func_c(mgl_ham3d, &h, ini_re, ini_im, ray_dat, r, k0, xx, yy, zz); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_qo3d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz) { HADT res = mgl_qo3d_solve_c(ham,ini_re,ini_im,ray_dat,r,k0,xx,yy,zz); HMDT out = mgl_datac_abs(res); delete res; return out; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int l) { char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0; uintptr_t res = uintptr_t(mgl_qo3d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy), _DM_(zz))); delete []s; return res; } //----------------------------------------------------------------------------- // // mglJacobian series // //----------------------------------------------------------------------------- static void *mgl_jacob2(void *par) { mglThreadD *t=(mglThreadD *)par; const long nx=t->p[0], ny=t->p[1]; mreal *r=t->a; const mreal *x=t->b, *y=t->c; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { long i=i0%nx, j=i0/nx; long ip = i0 ? -1:0, jm = j>0 ? -nx:0; r[i0] = (x[i0+ip]-x[i0+im])*(y[i0+jp]-y[i0+jm]) - (y[i0+ip]-y[i0+im])*(x[i0+jp]-x[i0+jm]); r[i0] *= mreal((nx-1)*(ny-1)) / mreal((ip-im)*(jp-jm)); } return 0; } HMDT MGL_EXPORT mgl_jacobian_2d(HCDT x, HCDT y) { const long nx = x->GetNx(), ny=x->GetNy(); if(nx!=y->GetNx() || ny!=y->GetNy() || nx<2 || ny<2) return 0; mglData *r=new mglData(nx,ny,1); const mglData *xx=dynamic_cast(x); const mglData *yy=dynamic_cast(y); if(xx && yy) { long p[2]={nx,ny}; mglStartThread(mgl_jacob2,0,nx*ny,r->a,xx->a,yy->a,p); } else // slow variant { #pragma omp parallel for collapse(2) for(long j=0;j0 ? i-1:i, ip = i0 ? j-1:j, jp = ja[i+nx*j] = (x->v(ip,j)-x->v(im,j))*(y->v(i,jp)-y->v(i,jm)) - (y->v(ip,j)-y->v(im,j))*(x->v(i,jp)-x->v(i,jm)); r->a[i+nx*j] *= mreal((nx-1)*(ny-1)) / mreal((ip-im)*(jp-jm)); } } return r; } //----------------------------------------------------------------------------- static void *mgl_jacob3(void *par) { mglThreadD *t=(mglThreadD *)par; const long nx=t->p[0], ny=t->p[1], nz=t->p[2]; mreal *r=t->a; const mreal *x=t->b, *y=t->c, *z=t->d; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { long i=i0%nx, j=(i0/nx)%ny, k=i0/(nx*ny); long ip = i0 ? -1:0, jm = j>0 ? -nx:0, km = k>0 ? -nx*ny:0; r[i0] = (x[i0+ip]-x[i0+im])*(y[i0+jp]-y[i0+jm])*(z[i0+kp]-z[i0+km]) - (x[i0+ip]-x[i0+im])*(y[i0+kp]-y[i0+km])*(z[i0+jp]-z[i0+jm]) - (x[i0+jp]-x[i0+jm])*(y[i0+ip]-y[i0+im])*(z[i0+kp]-z[i0+km]) + (x[i0+jp]-x[i0+jm])*(y[i0+kp]-y[i0+km])*(z[i0+ip]-z[i0+im]) + (x[i0+kp]-x[i0+km])*(y[i0+ip]-y[i0+im])*(z[i0+jp]-z[i0+jm]) - (x[i0+kp]-x[i0+km])*(y[i0+jp]-y[i0+jm])*(z[i0+ip]-z[i0+im]); r[i0] *= mreal((nx-1)*(ny-1)*(nz-1)) / mreal((ip-im)*(jp-jm)*(kp-km)); } return 0; } HMDT MGL_EXPORT mgl_jacobian_3d(HCDT x, HCDT y, HCDT z) { const long nx = x->GetNx(), ny=x->GetNy(), nz=x->GetNz(), nn = nx*ny*nz; if(nx<2 || ny<2 || nz<2) return 0; if(nn!=y->GetNN() || nn!=z->GetNN()) return 0; mglData *r=new mglData(nx,ny,nz); const mglData *xx=dynamic_cast(x); const mglData *yy=dynamic_cast(y); const mglData *zz=dynamic_cast(z); if(xx && yy && zz) { long p[3]={nx,ny,nz}; mglStartThread(mgl_jacob3,0,nx*ny*nz,r->a,xx->a,yy->a,p,0,zz->a); } else // slow variant { #pragma omp parallel for collapse(3) for(long k=0;k0 ? i-1:i, ip = i0 ? j-1:j, jp = j0 ? k-1:k, kp = ka[i0] = (x->v(ip,j,k)-x->v(im,j,k))*(y->v(i,jp,k)-y->v(i,jm,k))*(z->v(i,j,kp)-z->v(i,j,km)) - (x->v(ip,j,k)-x->v(im,j,k))*(y->v(i,j,kp)-y->v(i,j,km))*(z->v(i,jp,k)-z->v(i,jm,k)) - (x->v(i,jp,k)-x->v(i,jm,k))*(y->v(ip,j,k)-y->v(im,j,k))*(z->v(i,j,kp)-z->v(i,j,km)) + (x->v(i,jp,k)-x->v(i,jm,k))*(y->v(i,j,kp)-y->v(i,j,km))*(z->v(ip,j,k)-z->v(im,j,k)) + (x->v(i,j,kp)-x->v(i,j,km))*(y->v(ip,j,k)-y->v(im,j,k))*(z->v(i,jp,k)-z->v(i,jm,k)) - (x->v(i,j,kp)-x->v(i,j,km))*(y->v(i,jp,k)-y->v(i,jm,k))*(z->v(ip,j,k)-z->v(im,j,k)); r->a[i0] *= mreal((nx-1)*(ny-1)*(nz-1)) / mreal((ip-im)*(jp-jm)*(kp-km)); } } return r; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_jacobian_2d_(uintptr_t* x, uintptr_t* y) { return uintptr_t(mgl_jacobian_2d(_DA_(x), _DA_(y))); } uintptr_t MGL_EXPORT mgl_jacobian_3d_(uintptr_t* x, uintptr_t* y, uintptr_t* z) { return uintptr_t(mgl_jacobian_3d(_DA_(x), _DA_(y), _DA_(z))); } //----------------------------------------------------------------------------- // // Progonka // //----------------------------------------------------------------------------- void static mgl_progonka_sr(HCDT A, HCDT B, HCDT C, HCDT D, mreal *dat, long n, long id, long i0, long di, bool difr) { mreal *aa=dat, *bb=dat+n, *uu=dat+2*n; mreal b0=B->vthr(i0), c0=C->vthr(i0), d0=D->vthr(id); if(difr) d0 = (2.-b0)*d0-c0*D->vthr(id+di); aa[0] = -c0/b0; bb[0] = d0/b0; for(long i=1;ivthr(ii), b=B->vthr(ii), c=C->vthr(ii); mreal d=difr?-a*D->vthr(dd-di)+(2.-b)*D->vthr(dd)-c*D->vthr(tt):D->vthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); } uu[n-1] = bb[n-1]; for(long i=n-2;i>=0;i--) uu[i] = bb[i]+aa[i]*uu[i+1]; } void static mgl_progonka_pr(HCDT A, HCDT B, HCDT C, HCDT D, mreal *dat, long n, long id, long i0, long di, bool difr) { mreal *aa=dat, *bb=dat+n, *gg=dat+2*n, *uu=dat+3*n; mreal a0=A->vthr(i0), b0=B->vthr(i0), c0=C->vthr(i0), d0=D->vthr(id); if(difr) d0 = -a0*D->vthr(id+di*(n-1))+(2.-b0)*d0-c0*D->vthr(id+di); aa[0] =-c0/b0; bb[0] = d0/b0; gg[0] =-a0/b0; for(long i=1;ivthr(ii), b=B->vthr(ii), c=C->vthr(ii); mreal d=difr?-a*D->vthr(dd-di)+(2.-b)*D->vthr(dd)-c*D->vthr(il):D->vthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); gg[i] = -a*gg[i-1]/(b+a*aa[i-1]); } mreal P=bb[n-1]/(1.-gg[n-1]), Q=aa[n-1]/(1.-gg[n-1]); aa[n-1] = Q; bb[n-1] = P; for(long i=n-2;i>=0;i--) { bb[i] += aa[i]*bb[i+1]+gg[i]*P; aa[i] = aa[i]*aa[i+1]+gg[i]*Q; } mreal u0 = bb[0]/(1.-aa[0]); for(long i=0;ivthr(i0), c0=C->vthr(i0), d0=D->vthr(id); uu[0] = d0/b0*(difr?(2.-b0):1.); b0=B->vthr(i0+n*n-1); d0=D->vthr(id+n*n-1); uu[n*n-1] = d0/b0*(difr?(2.-b0):1.); long di = n-1, i1 = i0+n*(n-1), d1 = id+n*(n-1); // suppose the square grid! for(long j=1;jvthr(i0+j); c0=C->vthr(i0+j); d0=D->vthr(id+j); if(difr) d0 = (2.-b0)*d0-c0*D->vthr(id+j+di); aa[0] = -c0/b0; bb[0] = d0/b0; for(long i=1;i<=j;i++) { long ii=i0+j+di*i, dd=id+j+di*i; mreal a=A->vthr(ii),b=B->vthr(ii),c=C->vthr(ii); mreal d=difr?-a*D->vthr(dd-di)+(2.-b)*D->vthr(dd)-c*D->vthr(dd+di):D->vthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); } uu[j+di*(j-1)] = bb[j]; for(long i=j-1;i>=0;i--) uu[j+di*i] = bb[i]+aa[i]*uu[j+di*i+di]; // next top-right triangle long j1=n-1-j; b0=B->vthr(i1+j1); c0=C->vthr(i1+j1); d0=D->vthr(d1+j1); if(difr) d0 = (2.-b0)*d0-c0*D->vthr(d1+j1-di); aa[0] = -c0/b0; bb[0] = d0/b0; for(long i=1;i<=j;i++) { long ii=i1+j1-di*i, dd=d1+j1-di*i; mreal a=A->vthr(ii),b=B->vthr(ii),c=C->vthr(ii); mreal d=difr?-a*D->vthr(dd+di)+(2.-b)*D->vthr(dd)-c*D->vthr(dd-di):D->vthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); } uu[j1+n*(n-1)-di*(j-1)] = bb[j]; for(long i=j-1;i>=0;i--) uu[j1+n*(n-1)-di*i] = bb[i]+aa[i]*uu[j1+n*(n-1)-di*i-di]; } } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how) { const long nx=D->GetNx(),ny=D->GetNy(),nz=D->GetNz(); const long nn=nx*ny*nz, np=nx*ny, na=A->GetNN(); if(B->GetNN()!=na || C->GetNN()!=na) return 0; mglData *r = new mglData(nx,ny,nz); bool per = mglchr(how,'c'); bool difr = mglchr(how,'d'); if(mglchr(how,'x') && (na==nn || na==np || na==nx)) #pragma omp parallel { mglData T(nx,4); mreal *uu=T.a+(per?3:2)*nx; #pragma omp for collapse(2) for(long k=0;ka[i+i0] = uu[i]; } } else if(mglchr(how,'y') && (na==nn || na==np || na==ny)) #pragma omp parallel { mglData T(ny,4); mreal *uu=T.a+(per?3:2)*ny; #pragma omp for collapse(2) for(long k=0;ka[j*nx+i0] = uu[j]; } } else if(mglchr(how,'z') && (na==nn || na==nz)) #pragma omp parallel { mglData T(nz,4); mreal *uu=T.a+(per?3:2)*nz; #pragma omp for collapse(2) for(long j=0;ja[k*np+i0] = uu[k]; } } else if(mglchr(how,'h') && ny==nx && (na==nn || na==np) && nx>1) #pragma omp parallel { mglData T(np,2); #pragma omp for for(long k=0;ka+k*np, T.a+np, np*sizeof(mreal)); } } else { delete r; r=0; } return r; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_data_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; uintptr_t r = uintptr_t(mgl_data_tridmat(_DA_(A),_DA_(B),_DA_(C),_DA_(D),s)); delete []s; return r; } //----------------------------------------------------------------------------- void static mgl_progonka_sc(HCDT A, HCDT B, HCDT C, HCDT D, dual *dat, long n, long id, long i0, long di, bool difr) { dual *aa=dat, *bb=dat+n, *uu=dat+2*n; dual b0=B->vcthr(i0), c0=C->vcthr(i0), d0=D->vcthr(id); if(difr) d0 = (mreal(2)-b0)*d0-c0*D->vcthr(id+di); aa[0] = -c0/b0; bb[0] = d0/b0; for(long i=1;ivcthr(ii), b=B->vcthr(ii), c=C->vcthr(ii); dual d=difr?-a*D->vcthr(dd-di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(tt):D->vcthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); } uu[n-1] = bb[n-1]; for(long i=n-2;i>=0;i--) uu[i] = bb[i]+aa[i]*uu[i+1]; } void static mgl_progonka_pc(HCDT A, HCDT B, HCDT C, HCDT D, dual *dat, long n, long id, long i0, long di, bool difr) { dual *aa=dat, *bb=dat+n, *gg=dat+2*n, *uu=dat+3*n; dual a0=A->vcthr(i0), b0=B->vcthr(i0), c0=C->vcthr(i0), d0=D->vcthr(id); if(difr) d0 = -a0*D->vcthr(id+di*(n-1))+(mreal(2)-b0)*d0-c0*D->vcthr(id+di); aa[0] =-c0/b0; bb[0] = d0/b0; gg[0] =-a0/b0; for(long i=1;ivcthr(ii), b=B->vcthr(ii), c=C->vcthr(ii); dual d=difr?-a*D->vcthr(dd-di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(il):D->vcthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); gg[i] = -a*gg[i-1]/(b+a*aa[i-1]); } dual P=bb[n-1]/(mreal(1)-gg[n-1]), Q=aa[n-1]/(mreal(1)-gg[n-1]); aa[n-1] = Q; bb[n-1] = P; for(long i=n-2;i>=0;i--) { bb[i] += aa[i]*bb[i+1]+gg[i]*P; aa[i] = aa[i]*aa[i+1]+gg[i]*Q; } dual u0 = bb[0]/(mreal(1)-aa[0]); for(long i=0;ivcthr(i0), c0=C->vcthr(i0), d0=D->vcthr(id); uu[0] = d0/b0*(difr?(mreal(2)-b0):mreal(1)); b0=B->vcthr(i0+n*n-1); d0=D->vcthr(id+n*n-1); uu[n*n-1] = d0/b0*(difr?(mreal(2)-b0):mreal(1)); long di = n-1, i1 = i0+n*(n-1), d1 = id+n*(n-1); // suppose the square grid! for(long j=1;jvcthr(i0+j); c0=C->vcthr(i0+j); d0=D->vcthr(id+j); if(difr) d0 = (mreal(2)-b0)*d0-c0*D->vcthr(id+j+di); aa[0] = -c0/b0; bb[0] = d0/b0; for(long i=1;i<=j;i++) { long ii=i0+j+di*i, dd=id+j+di*i; dual a=A->vcthr(ii),b=B->vcthr(ii),c=C->vcthr(ii); dual d=difr?-a*D->vcthr(dd-di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(dd+di):D->vcthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); } uu[j+di*(j-1)] = bb[j]; for(long i=j-1;i>=0;i--) uu[j+di*i] = bb[i]+aa[i]*uu[j+di*i+di]; // next top-right triangle long j1=n-1-j; b0=B->vcthr(i1+j1); c0=C->vcthr(i1+j1); d0=D->vcthr(d1+j1); if(difr) d0 = (mreal(2)-b0)*d0-c0*D->vcthr(d1+j1-di); aa[0] = -c0/b0; bb[0] = d0/b0; for(long i=1;i<=j;i++) { long ii=i1+j1-di*i, dd=d1+j1-di*i; dual a=A->vcthr(ii),b=B->vcthr(ii),c=C->vcthr(ii); dual d=difr?-a*D->vcthr(dd+di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(dd-di):D->vcthr(dd); aa[i] = -c/(b+a*aa[i-1]); bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]); } uu[j1+n*(n-1)-di*(j-1)] = bb[j]; for(long i=j-1;i>=0;i--) uu[j1+n*(n-1)-di*i] = bb[i]+aa[i]*uu[j1+n*(n-1)-di*i-di]; } } //----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how) { const long nx=D->GetNx(),ny=D->GetNy(),nz=D->GetNz(); const long nn=nx*ny*nz, np=nx*ny, na=A->GetNN(); if(B->GetNN()!=na || C->GetNN()!=na) return 0; mglDataC *r = new mglDataC(nx,ny,nz); bool per = mglchr(how,'c'); bool difr = mglchr(how,'d'); if(mglchr(how,'x') && (na==nn || na==np || na==nx)) #pragma omp parallel { mglDataC T(nx,4); dual *uu=T.a+(per?3:2)*nx; #pragma omp for collapse(2) for(long k=0;ka[i+i1] = uu[i]; } } else if(mglchr(how,'y') && (na==nn || na==np || na==ny)) #pragma omp parallel { mglDataC T(ny,4); dual *uu=T.a+(per?3:2)*ny; #pragma omp for collapse(2) for(long k=0;ka[j*nx+i0] = uu[j]; } } else if(mglchr(how,'z') && (na==nn || na==nz)) #pragma omp parallel { mglDataC T(nz,4); dual *uu=T.a+(per?3:2)*nz; #pragma omp for collapse(2) for(long j=0;ja[k*np+i1] = uu[k]; } } else if(mglchr(how,'h') && ny==nx && (na==nn || na==np) && nx>1) #pragma omp parallel { mglDataC T(np,2); #pragma omp for for(long k=0;ka+k*np, T.a+np, np*sizeof(dual)); } } else { delete r; r=0; } return r; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_datac_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; uintptr_t r = uintptr_t(mgl_datac_tridmat(_DA_(A),_DA_(B),_DA_(C),_DA_(D),s)); delete []s; return r; } //----------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/crust.cpp��������������������������������������������������������������������������0000644�0001750�0001750�00000103343�13513030041�015604� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * crust.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include "mgl2/other.h" #include "mgl2/data.h" #include "mgl2/thread.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- // // TriPlot series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { long n = x->GetNN(), m = nums->GetNy(); if(mgl_check_trig(gr,nums,x,y,z,a,"TriPlot")) return; long ss=gr->AddTexture(sch); gr->SaveState(opt); gr->SetPenPal("-"); static int cgid=1; gr->StartGroup("TriPlot",cgid++); bool wire = mglchr(sch,'#'); long nc = a->GetNN(); if(nc!=n && nc>=m) // colors per triangle { mglPoint p1,p2,p3,q; long kq = gr->AllocPnts(m*3); #pragma omp parallel for for(long i=0;iv(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0) { long k1 = long(nums->v(0,i)+0.5); mglPoint p1(x->v(k1), y->v(k1), z->v(k1)); long k2 = long(nums->v(1,i)+0.5); mglPoint p2(x->v(k2), y->v(k2), z->v(k2)); long k3 = long(nums->v(2,i)+0.5); mglPoint p3(x->v(k3), y->v(k3), z->v(k3)); mglPoint q(wire ? mglPoint(NAN,NAN) : (p2-p1) ^ (p3-p1)); mreal cc = a->v(i); gr->AddPntQ(kq+3*i,p1,gr->GetC(ss,cc),q); gr->AddPntQ(kq+3*i+1,p2,gr->GetC(ss,cc),q); gr->AddPntQ(kq+3*i+2,p3,gr->GetC(ss,cc),q); } else { gr->SetPntOff(kq+3*i); gr->SetPntOff(kq+3*i+1); gr->SetPntOff(kq+3*i+2); } } if(wire) for(long i=0;iline_plot(kq+3*i,kq+3*i+1); gr->line_plot(kq+3*i+1,kq+3*i+2); gr->line_plot(kq+3*i+2,kq+3*i); } else for(long i=0;itrig_plot(kq+3*i,kq+3*i+1,kq+3*i+2); } else if(nc>=n) // colors per point { mglPoint *pp = new mglPoint[n]; for(long i=0;iv(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0) // add averaged normales { long k1 = long(nums->v(0,i)+0.5); long k2 = long(nums->v(1,i)+0.5); long k3 = long(nums->v(2,i)+0.5); if(!wire) { mglPoint q(mglPoint(x->v(k2)-x->v(k1), y->v(k2)-y->v(k1), z->v(k2)-z->v(k1)) ^ mglPoint(x->v(k3)-x->v(k1), y->v(k3)-y->v(k1), z->v(k3)-z->v(k1))); q.Normalize(); // try be sure that in the same direction ... if(q.z<0) q *= -1; pp[k1] += q; pp[k2] += q; pp[k3] += q; } else pp[k1]=pp[k2]=pp[k3]=mglPoint(NAN,NAN); } long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;iAddPntQ(kq+i, mglPoint(x->v(i), y->v(i), z->v(i)), gr->GetC(ss,a->v(i)), pp[i]); for(long i=0;iv(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0) // draw triangles { long k1 = long(nums->v(0,i)+0.5); long k2 = long(nums->v(1,i)+0.5); long k3 = long(nums->v(2,i)+0.5); if(wire) { gr->line_plot(kq+k1,kq+k2); gr->line_plot(kq+k1,kq+k3); gr->line_plot(kq+k3,kq+k2); } else gr->trig_plot(kq+k1,kq+k2,kq+k3); } delete []pp; } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xyz(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_triplot_xyzc(gr,nums,x,y,z,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt) { gr->SaveState(opt); mglData z(x->GetNN()); mreal zm = gr->AdjustZMin(); z.Fill(zm,zm); mgl_triplot_xyzc(gr,nums,x,y,&z,&z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_triplot_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xyz_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_triplot_xyz(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_triplot_xy(_GR_, _DA_(nums), _DA_(x), _DA_(y), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // QuadPlot series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { long n = x->GetNN(), m = nums->GetNy(); if(mgl_check_trig(gr,nums,x,y,z,a,"QuadPlot",4)) return; long ss=gr->AddTexture(sch); gr->SaveState(opt); gr->SetPenPal("-"); static int cgid=1; gr->StartGroup("QuadPlot",cgid++); mglPoint p1,p2,p3,p4; long nc = a->GetNN(); bool wire = mglchr(sch,'#'); if(nc!=n && nc>=m) // colors per triangle { long kq = gr->AllocPnts(m*4); #pragma omp parallel for for(long i=0;iv(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0 && nums->v(3,i)>=0) { long k1 = long(nums->v(0,i)+0.5); p1.Set(x->v(k1), y->v(k1), z->v(k1)); long k2 = long(nums->v(1,i)+0.5); p2.Set(x->v(k2), y->v(k2), z->v(k2)); long k3 = long(nums->v(2,i)+0.5); p3.Set(x->v(k3), y->v(k3), z->v(k3)); long k4 = long(nums->v(3,i)+0.5); p4.Set(x->v(k4), y->v(k4), z->v(k4)); mglPoint q = wire ? mglPoint(NAN,NAN):(p2-p1) ^ (p3-p1); mreal cc = a->v(i); gr->AddPntQ(kq+4*i,p1,gr->GetC(ss,cc),q); gr->AddPntQ(kq+4*i+1,p2,gr->GetC(ss,cc),q); gr->AddPntQ(kq+4*i+2,p3,gr->GetC(ss,cc),q); gr->AddPntQ(kq+4*i+3,p4,gr->GetC(ss,cc),q); } else { gr->SetPntOff(kq+4*i); gr->SetPntOff(kq+4*i+1); gr->SetPntOff(kq+4*i+1); gr->SetPntOff(kq+4*i+3); } } if(wire) for(long i=0;iline_plot(kq+3*i,kq+3*i+1); gr->line_plot(kq+3*i+1,kq+3*i+2); gr->line_plot(kq+3*i+2,kq+3*i); } else for(long i=0;iquad_plot(kq+4*i,kq+4*i+1,kq+4*i+2,kq+4*i+3); } else if(nc>=n) // colors per point { long *kk = new long[n]; mglPoint *pp = new mglPoint[n]; for(long i=0;iv(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0 && nums->v(3,i)>=0) { // add averaged normales long k1 = long(nums->v(0,i)+0.5); p1.Set(x->v(k1), y->v(k1), z->v(k1)); long k2 = long(nums->v(1,i)+0.5); p2.Set(x->v(k2), y->v(k2), z->v(k2)); long k3 = long(nums->v(2,i)+0.5); p3.Set(x->v(k3), y->v(k3), z->v(k3)); long k4 = long(nums->v(3,i)+0.5); p4.Set(x->v(k4), y->v(k4), z->v(k4)); if(wire) pp[k1]=pp[k2]=pp[k3]=pp[k4]=mglPoint(NAN,NAN); else { mglPoint q1 = (p2-p1) ^ (p3-p1); if(q1.z<0) q1*=-1; mglPoint q2 = (p2-p4) ^ (p3-p4); if(q2.z<0) q2*=-1; mglPoint q3 = (p1-p2) ^ (p4-p2); if(q3.z<0) q3*=-1; mglPoint q4 = (p1-p4) ^ (p4-p3); if(q4.z<0) q4*=-1; pp[k1] += q1; pp[k2] += q2; pp[k3] += q3; pp[k4] += q4; } } long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;iAddPntQ(kq+i, mglPoint(x->v(i), y->v(i), z->v(i)),gr->GetC(ss,a->v(i)), pp[i]); for(long i=0;iv(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0 && nums->v(3,i)>=0) { // draw quads long k1 = long(nums->v(0,i)+0.5); long k2 = long(nums->v(1,i)+0.5); long k3 = long(nums->v(2,i)+0.5); long k4 = long(nums->v(3,i)+0.5); if(wire) { gr->line_plot(kq+k1,kq+k2); gr->line_plot(kq+k1,kq+k3); gr->line_plot(kq+k4,kq+k2); gr->line_plot(kq+k4,kq+k3); } else gr->quad_plot(kq+k1,kq+k2,kq+k3,kq+k4); } delete []kk; delete []pp; } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xyz(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_quadplot_xyzc(gr,nums,x,y,z,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt) { gr->SaveState(opt); mglData z(x->GetNN()); z.Fill(gr->Min.z,gr->Min.z); mgl_quadplot_xyzc(gr,nums,x,y,&z,&z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_quadplot_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s;} //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xyz_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_quadplot_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(z), s, o); delete []o; delete []s;} //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_quadplot_xy(_GR_, _DA_(nums), _DA_(x), _DA_(y), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // TriCont series // //----------------------------------------------------------------------------- #include "cont.hpp" //----------------------------------------------------------------------------- std::vector MGL_NO_EXPORT mgl_tri_lines(mreal val, HCDT nums, HCDT a, HCDT x, HCDT y, HCDT z) { long n = x->GetNN(), m = nums->GetNy(); std::vector lines; for(long i=0;iv(0,i)+0.5), k2 = long(nums->v(1,i)+0.5), k3 = long(nums->v(2,i)+0.5); if(k1<0 || k1>=n || k2<0 || k2>=n || k3<0 || k3>=n) continue; mreal v1 = a->v(k1), v2 = a->v(k2), v3 = a->v(k3); mreal d1 = mgl_d(val,v1,v2), d2 = mgl_d(val,v1,v3), d3 = mgl_d(val,v2,v3); mglSegment line; if(d1>=0 && d1<=1 && d2>=0 && d2<=1) { line.p1.Set(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1); line.p2.Set(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2); } else if(d1>=0 && d1<=1 && d3>=0 && d3<=1) { line.p1.Set(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1); line.p2.Set(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3); } else if(d3>=0 && d3<=1 && d2>=0 && d2<=1) { line.p1.Set(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2); line.p2.Set(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3); } if(line.p1!=line.p2) lines.push_back(line); } return lines; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mglDataV zz(x->GetNN()); if(!z) z = &zz; if(mgl_check_trig(gr,nums,x,y,z,a,"TriCont")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TriCont",cgid++); int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); for(long k=0;kGetNx();k++) { mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0); mgl_draw_curvs(gr,v0,gr->GetC(s,v0),text,mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z))); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(n); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(n+1); mgl_tricont_xyzcv(gr,&v,nums,x,y,z,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_tricont_xyzc(gr,nums,x,y,0,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_tricont_xyzcv(gr,v,nums,x,y,0,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricont_xyzcv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricont_xycv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricont_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricont_xyc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // TriContV series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mglDataV zz(x->GetNN()); if(!z) z = &zz; if(mgl_check_trig(gr,nums,x,y,z,a,"TriContV")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TriContV",cgid++); bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); for(long k=0;kGetNx();k++) { mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0); mreal dv = (gr->Max.c-gr->Min.c)/8, c = gr->GetC(s,v0); if(k>0) dv = v->v(k-1)-v->v(k); else if(kGetNx()-1) dv = v->v(k)-v->v(k+1); if(fixed) dv=-dv; const std::vector curvs = mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z)); for(size_t i=0;i &pp=curvs[i].pp; long f2=-1,g2=-1; for(std::list::const_iterator it=pp.begin(); it != pp.end(); ++it) { mglPoint p=*it,q(p.y,-p.x); long f1 = f2; f2 = gr->AddPnt(p,c,q); p.z+=dv; long g1 = g2; g2 = gr->AddPnt(p,c,q); gr->quad_plot(f1,g1,f2,g2); } } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(n); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(n+1); mgl_tricontv_xyzcv(gr,&v,nums,x,y,z,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_tricontv_xyzc(gr,nums,x,y,0,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_tricontv_xyzcv(gr,v,nums,x,y,0,z,sch,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricontv_xyzcv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricontv_xycv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricontv_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt, int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_tricontv_xyc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Dots series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_ca(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt) { long n = x->GetNN(), d, k=1; if(x->GetNz()>1) k=3; else if(x->GetNy()>1) k=2; if(y->GetNN()!=n || z->GetNN()!=n || c->GetNN()!=n || (a && a->GetNN()!=n)) { gr->SetWarn(mglWarnDim,"Dots"); return; } gr->SaveState(opt); d = gr->MeshNum>0 ? mgl_ipow(gr->MeshNum+1,k) : n; d = n>d ? n/d:1; static int cgid=1; gr->StartGroup("Dots",cgid++); char mk=gr->SetPenPal(sch); long ss=gr->AddTexture(sch); if(mk==0) mk='.'; gr->Reserve(n); long kq = gr->AllocPnts(n); #pragma omp parallel for for(long i=0;ivthr(i),y->vthr(i),z->vthr(i)); gr->AddPntQ(kq+i,p,gr->GetC(ss,c->vthr(i)),mglPoint(NAN),a?gr->GetA(a->vthr(i)):-1); } for(long i=0;imark_plot(kq+i, mk); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_a(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mgl_dots_ca(gr, x, y, z, z, a, sch, opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mgl_dots_ca(gr, x, y, z, z, NULL, sch, opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dots(_GR_, _DA_(x),_DA_(y),_DA_(z),s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_a_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dots_a(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(a),s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_ca_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dots_ca(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(c),_DA_(a),s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // mglTriangulation // //----------------------------------------------------------------------------- long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff); HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z) { mglData *nums=0; long n = x->GetNN(), m; if(y->GetNN()!=n || z->GetNN()!=n) return nums; mglPoint *pp = new mglPoint[n]; long *nn=0; for(long i=0;iv(i), y->v(i), z->v(i)); m = mgl_crust(n,pp,&nn,0); if(m>0) { nums=new mglData(3,m); for(long i=0;i<3*m;i++) nums->a[i]=nn[i]; } delete []pp; free(nn); return nums; } //----------------------------------------------------------------------------- #include "s_hull/s_hull_pro.h" HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y) { mglData *nums=0; long n = x->GetNN(); if(y->GetNN()!=n) return nums; // use s-hull here std::vector pts; Shx pt; double x1=mglInf, x2=-mglInf, y1=mglInf, y2=-mglInf; for(long i=0;ivthr(i), yy = y->vthr(i); if(xxx2) x2=xx; if(yyy2) y2=yy; } const double dx=x2-x1, dy=y2-y1; if(dx==0 || dy==0) return nums; for(long i=0;ivthr(i)-x1)/dx; pt.c = (y->vthr(i)-y1)/dy; if(mgl_isbad(pt.r) || mgl_isbad(pt.c)) continue; pt.id = i; pts.push_back(pt); } std::vector triads; static const double float_eps = std::numeric_limits::epsilon(); Dupex grid_step(float_eps, float_eps); const size_t original_size = pts.size(); if(pts.size() >= 3u && 0. < grid_step.r && 0. < grid_step.c) { std::vector out; de_duplicate(pts, out, grid_step); if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) { // Error occured. It may be caused by degenerated dataset. Well, let's try to increment rounding grid step. // Why 4? Why not. There are no particular reasons for this. grid_step.r *= 4.; grid_step.c *= 4.; out.clear(); triads.clear(); de_duplicate(pts, out, grid_step); if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) { // Last try. Let's assume uniform points distribution and use range / sqrt(pts.size()) * 2 as epsilon. // It removes a 3/4 of points in optimal case but in the worst case it merges all points to the one. const double density = 1. + floor(0.5 + std::sqrt(static_cast(pts.size()))); grid_step.r = grid_step.c = 2/density; out.clear(); de_duplicate(pts, out, grid_step); triads.clear(); s_hull_pro(pts, triads); } } } if (triads.empty()) { mgl_set_global_warn(_("Cannot triangulate this set!")); } else if(original_size > pts.size()) { mgl_set_global_warn(_("There are duplicated or indistinguishably adjacent points for triangulation.")); } long m = triads.size(); nums=new mglData(3,m); for(long i=0;ia[3*i] = triads[i].a; nums->a[3*i+1] = triads[i].b; nums->a[3*i+2] = triads[i].c; } return nums; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_triangulation_3d_(uintptr_t *x, uintptr_t *y, uintptr_t *z) { return uintptr_t(mgl_triangulation_3d(_DA_(x),_DA_(y),_DA_(z))); } uintptr_t MGL_EXPORT mgl_triangulation_2d_(uintptr_t *x, uintptr_t *y) { return uintptr_t(mgl_triangulation_2d(_DA_(x),_DA_(y))); } //----------------------------------------------------------------------------- // // DataGrid // //----------------------------------------------------------------------------- static void *mgl_grid_t(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0],ny=t->p[1]; mreal *b=t->a; const mreal *x=t->b, *y=t->c, *d=t->d; HCDT zdat = (HCDT) t->v; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) if(d[3*i0]>=0 && d[3*i0+1]>=0 && d[3*i0+2]>=0) { long k1 = long(d[3*i0]+0.5), k2 = long(d[3*i0+1]+0.5), k3 = long(d[3*i0+2]+0.5); mreal dxu,dxv,dyu,dyv; mreal z1=zdat->vthr(k1), z2=zdat->vthr(k2), z3=zdat->vthr(k3); mglPoint d1(x[k2]-x[k1],y[k2]-y[k1],z2-z1), d2(x[k3]-x[k1],y[k3]-y[k1],z3-z1), p; dxu = d2.x*d1.y - d1.x*d2.y; if(fabs(dxu)<1e-5) continue; // points lies on the same line dyv =-d1.x/dxu; dxv = d1.y/dxu; dyu = d2.x/dxu; dxu =-d2.y/dxu; long x1,y1,x2,y2; x1 = long(mgl_min(mgl_min(x[k1],x[k2]),x[k3])); // bounding box y1 = long(mgl_min(mgl_min(y[k1],y[k2]),y[k3])); x2 = long(mgl_max(mgl_max(x[k1],x[k2]),x[k3])); y2 = long(mgl_max(mgl_max(y[k1],y[k2]),y[k3])); x1 = x1>0 ? x1:0; x2 = x20 ? y1:0; y2 = y2x2) | (y1>y2)) continue; mreal x0 = x[k1], y0 = y[k1]; for(long i=x1;i<=x2;i++) for(long j=y1;j<=y2;j++) { mreal xx = (i-x0), yy = (j-y0); mreal u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; if((u<0) | (v<0) | (u+v>1)) continue; b[i+nx*j] = z1 + d1.z*u + d2.z*v; } } return 0; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_grid_xy(HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, mreal x1, mreal x2, mreal y1, mreal y2) { // NOTE: only for mglData const mglData *x = dynamic_cast(xdat); const mglData *y = dynamic_cast(ydat); long n=xdat->GetNN(); if((n<3) || (ydat->GetNN()!=n) || (zdat->GetNN()!=n)) return; mglData *nums = mgl_triangulation_2d(xdat,ydat); if(!nums) return; if(nums->nx<3) { delete nums; return; } long nn = nums->ny, par[3]={d->nx,d->ny,d->nz}; mreal xx[4]={x1,(d->nx-1)/(x2-x1), y1,(d->ny-1)/(y2-y1)}; mreal *xc=new mreal[n], *yc=new mreal[n]; if(x && y) #pragma omp parallel for for(long i=0;ia[i]-xx[0]); yc[i]=xx[3]*(y->a[i]-xx[2]); } else #pragma omp parallel for for(long i=0;ivthr(i)-xx[0]); yc[i]=xx[3]*(ydat->vthr(i)-xx[2]); } long tmp = d->nx*d->ny*d->nz; #pragma omp parallel for for(long i=0;ia[i] = NAN; mglStartThread(mgl_grid_t,0,nn,d->a,xc,yc,par,zdat,nums->a); delete nums; delete []xc; delete []yc; } void MGL_EXPORT mgl_data_grid_xy_(uintptr_t *d, uintptr_t *x, uintptr_t *y, uintptr_t *z, mreal *x1, mreal *x2, mreal *y1, mreal *y2) { mgl_data_grid_xy(_DT_,_DA_(x),_DA_(y),_DA_(z),*x1,*x2,*y1,*y2); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_grid(HMGL gr, HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, const char *opt) { gr->SaveState(opt); mgl_data_grid_xy(d,xdat,ydat,zdat,gr->Min.x,gr->Max.x,gr->Min.y,gr->Max.y); gr->LoadState(); } void MGL_EXPORT mgl_data_grid_(uintptr_t *gr, uintptr_t *d, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *opt,int lo) { char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_data_grid(_GR_,_DT_,_DA_(x),_DA_(y),_DA_(z),o); delete []o; } //----------------------------------------------------------------------------- // // Crust series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_crust(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { if(y->GetNN()!=x->GetNN() || z->GetNN()!=x->GetNN()) { gr->SetWarn(mglWarnDim,"Crust"); return; } HMDT nums = mgl_triangulation_3d(x, y, z); mgl_triplot_xyzc(gr,nums,x,y,z,z,sch,opt); mgl_delete_data(nums); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_crust_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_crust(_GR_, _DA_(x),_DA_(y),_DA_(z),s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- long static mgl_insert_trig(long i1,long i2,long i3,long **n) { static long Cur=0,Max=0; if(i1<0 || i2<0 || i3<0) return Cur; if(*n==0) { Max = 1024; Cur = 0; *n = (long *)malloc(Max*3*sizeof(long)); memset(*n,0,Max*3*sizeof(long)); } if(Cur>=Max) { Max += 1024; *n = (long *)realloc(*n,Max*3*sizeof(long)); memset(*n+3*(Max-1024),0,3*1024*sizeof(long)); } long *nn; if(i1>i3) { long k1=i1; i1=i3; i3=k1; } // simple sorting if(i1>i2) { long k1=i1; i1=i2; i2=k1; } if(i2>i3) { long k1=i2; i2=i3; i3=k1; } for(long i=0;i0) continue; r = mgl_anorm(qq[i]-qq[k1]); if(rr) rm = r; } rs += sqrt(rm); } rs *= ff/n; rs = rs*rs; // "average" distance const int nnum=100; long *ind, *set; // indexes of "close" points, flag that it was added and its number mglPoint *qq; // normalized point coordinates ind = new long[nnum]; set = new long[nnum]; qq = new mglPoint[nnum]; long k1,k2,k3,m=0; for(long i=0;i0) { set[k1]=1; mgl_insert_trig(i,ind[k1],ind[k2],nn); k1 = k2; } m = mgl_insert_trig(i,ind[k1],ind[0],nn); } delete []set; delete []ind; delete []qq; return m; } //----------------------------------------------------------------------------- ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/data.cpp���������������������������������������������������������������������������0000644�0001750�0001750�00000240250�13513030041�015354� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * data.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/data.h" #include "mgl2/datac.h" #include "mgl2/eval.h" #include "mgl2/thread.h" #include "interp.hpp" MGL_EXPORT int mglNumThr=0; //----------------------------------------------------------------------------- #if MGL_HAVE_PTHREAD #ifdef WIN32 #include #include #elif defined(__APPLE__) || defined (__FreeBSD__) #include #elif defined(unix) || defined(__unix) || defined(__unix__) #include #endif void MGL_EXPORT mgl_set_num_thr(int n) { #ifdef WIN32 SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); mglNumThr = n>0 ? n : systemInfo.dwNumberOfProcessors; #elif defined (__APPLE__) || defined(__FreeBSD__) int numProcessors = 1; size_t size = sizeof(numProcessors); sysctlbyname("hw.ncpu", &numProcessors, &size, NULL, 0); mglNumThr = n>0 ? n : numProcessors; #else mglNumThr = n>0 ? n : get_nprocs_conf(); #endif } #else void MGL_EXPORT mgl_set_num_thr(int) { mglNumThr = 1; } #endif void MGL_EXPORT mgl_set_num_thr_(int *n) { mgl_set_num_thr(*n); } //----------------------------------------------------------------------------- void MGL_EXPORT mglStartThread(void *(*func)(void *), void (*post)(mglThreadD *,mreal *), long n, mreal *a, const mreal *b, const mreal *c, const long *p, const void *v, const mreal *d, const mreal *e, const char *s) { if(!func) return; #if MGL_HAVE_PTHREAD if(mglNumThr<1) mgl_set_num_thr(0); if(mglNumThr>1) { pthread_t *tmp=new pthread_t[mglNumThr]; mglThreadD *par=new mglThreadD[mglNumThr]; for(long i=0;i1) { pthread_t *tmp=new pthread_t[mglNumThr]; mglThreadV *par=new mglThreadV[mglNumThr]; for(long i=0;i(a,nx,ny,nz,x,y,z); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx, mreal *dy, mreal *dz) { return mglSpline3t(a,nx,ny,nz,x,y,z,dx,dy,dz); } //----------------------------------------------------------------------------- mreal MGL_EXPORT_PURE mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z) { return mglLineart(a,nx,ny,nz,x,y,z); } //----------------------------------------------------------------------------- double MGL_EXPORT_CONST mgl_ipow(double x,int n) { double t; if(n==2) return x*x; if(n==1) return x; if(n<0) return 1./mgl_ipow(x,-n); if(n==0) return 1; t = mgl_ipow(x,n/2); t = t*t; if(n%2==1) t *= x; return t; } double MGL_EXPORT_PURE mgl_ipow_(mreal *x,int *n) { return mgl_ipow(*x,*n); } //----------------------------------------------------------------------------- double mgl_get_time(const char *time, const char *fmt) { #if !defined(WIN32) tm t; strptime(time,fmt,&t); return timegm(&t); #else return NAN; #endif } double mgl_get_time_(const char *time, const char *fmt,int l,int m) { char *s=new char[l+1]; memcpy(s,time,l); s[l]=0; char *f=new char[m+1]; memcpy(f,fmt,m); f[m]=0; double t=mgl_get_time(s,f); delete []s; delete []f; return t; } //----------------------------------------------------------------------------- static void *mgl_smth_x(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], kind=t->p[2]; mreal *b=t->a, delta=t->c[0]; const mreal *a=t->b; if(kind>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) if(mgl_isnum(a[i])) // bypass NAN values { long j = i%nx, nk = 2*kind+1; for(long k=-kind;k<=kind;k++) if(j+k>=0 && j+kid;in;i+=mglNumThr) { long j = i%nx; if(j>1 && jid;in;i+=mglNumThr) { long j = i%nx; mreal v = (j>0 && jid;in;i+=mglNumThr) { long j = i%nx; mreal v = (j>0 && ja[i]?v:a[i]; } if(delta>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) { double ab = fabs(a[i]-b[i]); if(ab>delta) b[i] = a[i]+(delta/ab)*(b[i]-a[i]); } return 0; } static void *mgl_smth_y(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0],ny=t->p[1], kind=t->p[2]; mreal *b=t->a, delta=t->c[0]; const mreal *a=t->b; if(kind>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) if(mgl_isnum(a[i])) // bypass NAN values { long j = (i/nx)%ny, nk = 2*kind+1; for(long k=-kind;k<=kind;k++) if(j+k>=0 && j+kid;in;i+=mglNumThr) { long j = (i/nx)%ny; if(j>1 && jid;in;i+=mglNumThr) { long j = (i/nx)%ny; mreal v = (j>0 && jid;in;i+=mglNumThr) { long j = (i/nx)%ny; mreal v = (j>0 && ja[i]?v:a[i]; } if(delta>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) { double ab = fabs(a[i]-b[i]); if(ab>delta) b[i] = a[i]+(delta/ab)*(b[i]-a[i]); } return 0; } static void *mgl_smth_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nn=t->p[0]*t->p[1], nz=t->n/nn, kind=t->p[2]; mreal *b=t->a, delta=t->c[0]; const mreal *a=t->b; if(kind>1) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) if(mgl_isnum(a[i])) // bypass NAN values { long j = i/nn, nk = 2*kind+1; for(long k=-kind;k<=kind;k++) if(j+k>=0 && j+kid;in;i+=mglNumThr) { long j = i/nn; if(j>1 && jid;in;i+=mglNumThr) { long j = i/nn; mreal v = (j>0 && jid;in;i+=mglNumThr) { long j = i/nn; mreal v = (j>0 && ja[i]?v:a[i]; } if(delta>0) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;in;i+=mglNumThr) { double ab = fabs(a[i]-b[i]); if(ab>delta) b[i] = a[i]+(delta/ab)*(b[i]-a[i]); } return 0; } void MGL_EXPORT mgl_data_smooth(HMDT d, const char *dirs, mreal delta) { long Type = -1; if(mglchr(dirs,'0')) return; bool xdir=mglchr(dirs,'x'), ydir=mglchr(dirs,'y'), zdir=mglchr(dirs,'z'); if(!xdir && !ydir && !zdir) xdir=ydir=zdir=true; if(mglchr(dirs,'d')) { if(mglchr(dirs,'1')) Type = 1; if(mglchr(dirs,'2')) Type = 2; if(mglchr(dirs,'3')) Type = 3; if(mglchr(dirs,'4')) Type = 4; if(mglchr(dirs,'5')) Type = 5; if(mglchr(dirs,'6')) Type = 6; if(mglchr(dirs,'7')) Type = 7; if(mglchr(dirs,'8')) Type = 8; if(mglchr(dirs,'9')) Type = 9; } else { if(mglchr(dirs,'1')) return; if(mglchr(dirs,'3')) Type = 1; if(mglchr(dirs,'5')) Type = 2; } if(mglchr(dirs,'_')) Type = -2; if(mglchr(dirs,'^')) Type = -3; long nx=d->nx,ny=d->ny,nz=d->nz; // if(Type == SMOOTH_NONE) return; long p[3]={nx,ny,Type}; mreal *b = new mreal[nx*ny*nz],dd=delta; // ����������� �� x memset(b,0,nx*ny*nz*sizeof(mreal)); if(nx>4 && xdir) { mglStartThread(mgl_smth_x,0,nx*ny*nz,b,d->a,&dd,p); memcpy(d->a,b,nx*ny*nz*sizeof(mreal)); memset(b,0,nx*ny*nz*sizeof(mreal)); } if(ny>4 && ydir) { mglStartThread(mgl_smth_y,0,nx*ny*nz,b,d->a,&dd,p); memcpy(d->a,b,nx*ny*nz*sizeof(mreal)); memset(b,0,nx*ny*nz*sizeof(mreal)); } if(nz>4 && zdir) { mglStartThread(mgl_smth_z,0,nx*ny*nz,b,d->a,&dd,p); memcpy(d->a,b,nx*ny*nz*sizeof(mreal)); } delete []b; } void MGL_EXPORT mgl_data_smooth_(uintptr_t *d, const char *dir, mreal *delta,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_smooth(_DT_,s,*delta); delete []s; } //----------------------------------------------------------------------------- static void *mgl_csum_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; mreal *b = new mreal[nn]; memcpy(b,d->a,nn*sizeof(mreal)); if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_csum_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_csum_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_csum_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } delete []b; } void MGL_EXPORT mgl_data_cumsum_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_cumsum(_DT_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_int_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a, dd=0.5/nz; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; mreal *b=t->a, dd=0.5/ny; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; mreal *b=t->a, dd=0.5/nx; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; mreal *b = new mreal[nn]; memcpy(b,d->a,nn*sizeof(mreal)); if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_int_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_int_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_int_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } delete []b; } void MGL_EXPORT mgl_data_integral_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_integral(_DT_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_dif_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a, dd=0.5*nz; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; mreal *b=t->a, dd=0.5*ny; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; mreal *b=t->a, dd=0.5*nx; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; mreal *b = new mreal[nn]; if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_dif_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_dif_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_dif_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } delete []b; } void MGL_EXPORT mgl_data_diff_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_diff(_DT_,s); delete []s; } //----------------------------------------------------------------------------- static void *mgl_dif2_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a, dd=nz*nz; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; mreal *b=t->a, dd=ny*ny; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; mreal *b=t->a, dd=nx*nx; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;inx,ny=d->ny,nz=d->nz,nn=nx*ny*nz; long p[3]={nx,ny,nz}; mreal *b = new mreal[nn]; if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_dif2_z,0,nx*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_dif2_y,0,nx*nz,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_dif2_x,0,nz*ny,b,d->a,0,p); memcpy(d->a,b,nn*sizeof(mreal)); } delete []b; } void MGL_EXPORT mgl_data_diff2_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_diff2(_DT_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_swap(HMDT d, const char *dir) { if(!dir || *dir==0) return; if(strchr(dir,'z') && d->nz>1) mgl_data_roll(d,'z',d->nz/2); if(strchr(dir,'y') && d->ny>1) mgl_data_roll(d,'y',d->ny/2); if(strchr(dir,'x') && d->nx>1) mgl_data_roll(d,'x',d->nx/2); } void MGL_EXPORT mgl_data_swap_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; mgl_data_swap(_DT_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_roll(HMDT dd, char dir, long num) { long nx=dd->nx,ny=dd->ny,nz=dd->nz, d; mreal *b,*a=dd->a; if(dir=='z' && nz>1) { d = num>0 ? num%nz : (num+nz*(1-num/nz))%nz; if(d==0) return; // nothing to do b = new mreal[nx*ny*nz]; memcpy(b,a+nx*ny*d,nx*ny*(nz-d)*sizeof(mreal)); memcpy(b+nx*ny*(nz-d),a,nx*ny*d*sizeof(mreal)); memcpy(a,b,nx*ny*nz*sizeof(mreal)); delete []b; } if(dir=='y' && ny>1) { d = num>0 ? num%ny : (num+ny*(1-num/ny))%ny; if(d==0) return; // nothing to do b = new mreal[nx*ny*nz]; memcpy(b,a+nx*d,(nx*ny*nz-nx*d)*sizeof(mreal)); #pragma omp parallel for for(long i=0;i1) { d = num>0 ? num%nx : (num+nx*(1-num/nx))%nx; if(d==0) return; // nothing to do b = new mreal[nx*ny*nz]; memcpy(b,a+d,(nx*ny*nz-d)*sizeof(mreal)); #pragma omp parallel for for(long i=0;inx,ny=d->ny,nz=d->nz; mreal *a=d->a; if(strchr(dir,'z') && nz>1) { #pragma omp parallel for collapse(2) for(long j=0;j1) { #pragma omp parallel for for(long i=0;i1) { #pragma omp parallel for for(long j=0;jd->nx) return; long i,j,n=d->nx,m=d->ny; mreal *b = new mreal[m*n], *a=d->a; for(i=j=0;i+1ny = j; delete []b; } void MGL_EXPORT mgl_data_clean_(uintptr_t *d, int *id) { mgl_data_clean(_DT_,*id); } //----------------------------------------------------------------------------- static void *mgl_solve_x(void *par) { mglThreadD *t=(mglThreadD *)par; HCDT d=(HCDT)t->v; long nx=t->p[0], ny=t->p[1], nz=t->p[2], n1=t->p[3]?nx-1:1, nn=t->n; const mreal *a=t->b, *ii=t->c; mreal *b=t->a,val=t->d[0],da = 1e-5*(val?fabs(val):1); #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long l=t->id;lnx-2) continue; if(a) for(long i=i0+1;ida || dx==0) { x += (val-v)/dx; kk++; v = mglSpline3(a,nx,ny,nz,x,j,k, &dx,0,0); if(kk>=10) { b[l] = x = fabs(v-val)v(i-1,j,k), y2=d->v(i,j,k); if((y1-val)*(y2-val)<=0) { b[l] = i-1 + (val-y1)/(y2-y1); break; } } b[l] /= n1; } return 0; } static void *mgl_solve_y(void *par) { mglThreadD *t=(mglThreadD *)par; HCDT d=(HCDT)t->v; long nx=t->p[0], ny=t->p[1], nz=t->p[2], n1=t->p[3]?ny-1:1, nn=t->n; const mreal *a=t->b, *ii=t->c; mreal *b=t->a,val=t->d[0],da = 1e-5*(val?fabs(val):1); #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long l=t->id;lny-2) continue; if(a) for(long i=i0+1;ida || dy==0) { x += (val-v)/dy; kk++; v = mglSpline3(a,nx,ny,nz,j,x,k, 0,&dy,0); if(kk>=10) { b[l] = x = fabs(v-val)v(j,i-1,k), y2=d->v(j,i,k); if((y1-val)*(y2-val)<=0) { b[l] = i-1 + (val-y1)/(y2-y1); break; } } b[l] /= n1; } return 0; } static void *mgl_solve_z(void *par) { mglThreadD *t=(mglThreadD *)par; HCDT d=(HCDT)t->v; long nx=t->p[0], ny=t->p[1], nz=t->p[2], n1=t->p[3]?nz-1:1, nn=t->n; const mreal *a=t->b, *ii=t->c; mreal *b=t->a,val=t->d[0],da = 1e-5*(val?fabs(val):1); #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long l=t->id;lnz-2) continue; if(a) for(long i=i0+1;ida || dz==0) { x += (val-v)/dz; kk++; v = mglSpline3(a,nx,ny,nz,j,k,x, 0,0,&dz); if(kk>=10) { b[l] = x = fabs(v-val)v(j,k,i-1), y2=d->v(j,k,i); if((y1-val)*(y2-val)<=0) { b[l] = i-1 + (val-y1)/(y2-y1); break; } } b[l] /= n1; } return 0; } HMDT MGL_EXPORT mgl_data_solve(HCDT dat, mreal val, char dir, HCDT i0, int norm) { const mglData *i = dynamic_cast(i0); const mglData *d = dynamic_cast(dat); long p[4]={dat->GetNx(), dat->GetNy(), dat->GetNz(), norm}; const mreal *ii=0; mglData *r=new mglData, id0; if(i0 && !i) { id0.Set(i0); i=&id0; } // <-- slow but should work if(dir=='x' && p[0]>1) { r->Create(p[1],p[2]); ii = (i && i->nx*i->ny==p[1]*p[2])?i->a:0; mglStartThread(mgl_solve_x,0,p[1]*p[2],r->a,d?d->a:0,ii,p,dat,&val); } if(dir=='y' && p[1]>1) { r->Create(p[0],p[2]); ii = (i && i->nx*i->ny==p[0]*p[2])?i->a:0; mglStartThread(mgl_solve_y,0,p[0]*p[2],r->a,d?d->a:0,ii,p,dat,&val); } if(dir=='z' && p[2]>1) { r->Create(p[0],p[1]); ii = (i && i->nx*i->ny==p[0]*p[1])?i->a:0; mglStartThread(mgl_solve_z,0,p[0]*p[1],r->a,d?d->a:0,ii,p,dat,&val); } return r; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_solve_1d(HCDT d, mreal val, int spl, long i0) { mreal x=0, y1, y2, a, a0, dx=0, da = 1e-5*(val?fabs(val):1); long nx = d->GetNx(); if(i0<0 || i0>=nx) i0=0; if(val==d->v(i0+1)) return i0+1; const mglData *dd=dynamic_cast(d); const mglDataC *dc=dynamic_cast(d); if(dd) for(long i=i0+1;ia[i-1]; y2=dd->a[i]; if((y1-val)*(y2-val)<=0) { x = i-1 + (val-y1)/(y2-y1); a0 = a = mglSpline1t(dd->a,nx,x,&dx); if(spl) for(unsigned k=0;fabs(a-val)>da || dx==0;) { x += (val-a)/dx; k++; a = mglSpline1t(dd->a,nx,x,&dx); if(k>=10) return fabs(a-val)a[i-1]); y2=abs(dc->a[i]); if((y1-val)*(y2-val)<=0) { x = i-1 + (val-y1)/(y2-y1); dual cx, ca = mglSpline1t(dc->a,nx,x,&cx); a0 = a = abs(ca); dx = a?(cx.real()*ca.real()+cx.imag()*ca.imag())/a:0; if(spl) for(unsigned k=0;fabs(a-val)>da || dx==0;) { x += (val-a)/dx; k++; ca = mglSpline1t(dc->a,nx,x,&cx); a = abs(ca); dx = a?(cx.real()*ca.real()+cx.imag()*ca.imag())/a:0; if(k>=10) return fabs(a-val)v(i-1); y2=d->v(i); if((y1-val)*(y2-val)<=0) return i-1 + (val-y1)/(y2-y1); } return NAN; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_linear_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz) { if(!d) return NAN; long kx=long(x), ky=long(y), kz=long(z); mreal b0,b1; const mglData *dd=dynamic_cast(d); if(dd) { long nx=dd->nx, ny=dd->ny, nz=dd->nz, dn=ny>1?nx:0; kx = kx>=0 ? kx:0; kx = kx=0 ? ky:0; ky = ky=0 ? kz:0; kz = kza, *bb; if(kz>=0) { aa=dd->a+kx+nx*(ky+ny*kz); bb = aa+nx*ny; b0 = aa[0]*(1-x-y+x*y) + x*(1-y)*aa[1] + y*(1-x)*aa[dn] + x*y*aa[1+dn]; b1 = bb[0]*(1-x-y+x*y) + x*(1-y)*bb[1] + y*(1-x)*bb[dn] + x*y*bb[1+dn]; } else { z=0; if(ky>=0) { aa=dd->a+kx+nx*ky; b0 = b1 = aa[0]*(1-x-y+x*y) + x*(1-y)*aa[1] + y*(1-x)*aa[dn] + x*y*aa[1+dn]; } else if(kx>=0) { aa=dd->a+kx; b0 = b1 = aa[0]*(1-x) + x*aa[1]; } else b0 = b1 = dd->a[0]; } if(dx) *dx = kx>=0?aa[1]-aa[0]:0; if(dy) *dy = ky>=0?aa[dn]-aa[0]:0; if(dz) *dz = b1-b0; } else { long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz(); kx = kx>=0 ? kx:0; kx = kx=0 ? ky:0; ky = ky=0 ? kz:0; kz = kz=0) { a0 = d->v(kx,ky,kz); a1 = d->v(kx+1,ky,kz); a2 = d->v(kx,ky+1,kz); b0 = a0*(1-x-y+x*y) + x*(1-y)*a1 + y*(1-x)*a2 + x*y*d->v(kx+1,ky+1,kz);; b1 = d->v(kx,ky,kz+1)*(1-x-y+x*y) + x*(1-y)*d->v(kx+1,ky,kz+1) + y*(1-x)*d->v(kx,ky+1,kz+1) + x*y*d->v(kx+1,ky+1,kz+1); } else { z=0; if(ky>=0) { a0 = d->v(kx,ky); a1 = d->v(kx+1,ky); a2 = d->v(kx,ky+1); b0 = b1 = a0*(1-x-y+x*y) + x*(1-y)*a1 + y*(1-x)*a2 + x*y*d->v(kx+1,ky+1); } else if(kx>=0) { a2=a0 = d->v(kx); a1 = d->v(kx+1); b0 = b1 = a0*(1-x) + x*a1; } else b0 = b1 = d->v(0); } if(dx) *dx = a1-a0; if(dy) *dy = a2-a0; if(dz) *dz = b1-b0; } return b0 + z*(b1-b0); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_linear(HCDT d, mreal x,mreal y,mreal z) { return mgl_data_linear_ext(d, x,y,z, 0,0,0); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_spline(HCDT d, mreal x,mreal y,mreal z) { if(mgl_isbad(x) || mgl_isbad(y) || mgl_isbad(z)) return NAN; return d->value(x,y,z); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_spline_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz) { if(mgl_isbad(x) || mgl_isbad(y) || mgl_isbad(z)) return NAN; return d->valueD(x,y,z,dx,dy,dz); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z) { return mgl_data_spline(_DA_(d),*x,*y,*z); } mreal MGL_EXPORT mgl_data_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z) { return mgl_data_linear(_DA_(d),*x,*y,*z); } mreal MGL_EXPORT mgl_data_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz) { return mgl_data_spline_ext(_DA_(d),*x,*y,*z,dx,dy,dz); } mreal MGL_EXPORT mgl_data_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz) { return mgl_data_linear_ext(_DA_(d),*x,*y,*z,dx,dy,dz); } mreal MGL_EXPORT mgl_data_solve_1d_(uintptr_t *d, mreal *val, int *spl, int *i0) { return mgl_data_solve_1d(_DA_(d),*val, *spl, *i0); } uintptr_t MGL_EXPORT mgl_data_solve_(uintptr_t *d, mreal *val, const char *dir, uintptr_t *i0, int *norm,int) { return uintptr_t(mgl_data_solve(_DA_(d),*val, *dir, _DA_(i0), *norm)); } //----------------------------------------------------------------------------- long MGL_LOCAL_CONST int_pow(long x, long n) { if(n==2) return x*x; if(n==1) return x; if(n==0) return 1; if(n<0) return 0; long t = int_pow(x,n/2); t = t*t; if(n%2==1) t *= x; return t; } long MGL_NO_EXPORT mgl_powers(long N, const char *how) { bool k2 = mglchr(how,'2'), k3 = mglchr(how,'3'), k5 = mglchr(how,'5'); const double lN=log(N), l2=log(2), l3=log(3), l5=log(5); if(k2 && k3 && k5) { double dm=lN; long im=0, jm=0, km=0; for(long i=0;i<=lN/l2;i++) for(long j=0;j<=(lN-i*l2)/l3;j++) for(long k=0;k<=(lN-i*l2-j*l3)/l5;k++) { double d = lN-i*l2-j*l3-k*l5; if(d>0 && d0 && d0 && d0 && dnx, h), 'x'); if(mglchr(how,'y')) mgl_data_crop(d, 0, mgl_powers(d->ny, h), 'y'); if(mglchr(how,'z')) mgl_data_crop(d, 0, mgl_powers(d->nz, h), 'z'); } void MGL_EXPORT mgl_data_crop_opt_(uintptr_t *d, const char *how, int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; mgl_data_crop_opt(_DT_,s); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_crop(HMDT d, long n1, long n2, char dir) { long nx=d->nx,ny=d->ny,nz=d->nz, nn; mreal *b; if(n1<0) n1=0; switch(dir) { case 'x': if(n1>=nx) break; n2 = n2>0 ? n2 : nx+n2; if(n2<0 || n2>=nx || n2a+nx*i+n1,nn*sizeof(mreal)); d->nx = nn; if(!d->link) delete []d->a; d->a = b; d->link=false; d->NewId(); break; case 'y': if(n1>=ny) break; n2 = n2>0 ? n2 : ny+n2; if(n2<0 || n2>=ny || n2a+nx*(n1+i+ny*j),nx*sizeof(mreal)); d->ny = nn; if(!d->link) delete []d->a; d->a = b; d->link=false; break; case 'z': if(n1>=nz) break; n2 = n2>0 ? n2 : nz+n2; if(n2<0 || n2>=nz || n2a+nx*ny*n1,nn*nx*ny*sizeof(mreal)); d->nz = nn; if(!d->link) delete []d->a; d->a = b; d->link=false; break; } } void MGL_EXPORT mgl_data_crop_(uintptr_t *d, int *n1, int *n2, const char *dir,int) { mgl_data_crop(_DT_,*n1,*n2,*dir); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_last(HCDT d, const char *cond, long *i, long *j, long *k) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); if(!cond) cond = "u"; mglFormula eq(cond); if(*i<0 || *i>=nx) *i=nx; if(*j<0 || *j>=ny) *j=ny-1; if(*k<0 || *k>=nz) *k=nz-1; long i0 = *i+nx*(*j+ny*(*k))-1; mreal x,y,z,dx=nx>1?1/(nx-1.):0,dy=ny>1?1/(ny-1.):0,dz=nz>1?1/(nz-1.):0; for(;i0>=0;i0--) { x = dx*(i0%nx); y = dy*((i0/nx)%ny); z = dz*(i0/(nx*ny)); if(eq.Calc(x,y,z,d->vthr(i0))) break; } *i = i0%nx; *j = (i0/nx)%ny; *k = i0/(nx*ny); return i0>=0 ? d->vthr(i0) : NAN; // NOTE: Return NAN if false } mreal MGL_EXPORT mgl_data_last_(uintptr_t *d, const char *cond, int *i, int *j, int *k, int l) { long ii=*i,jj=*j,kk=*k; char *s=new char[l+1]; memcpy(s,cond,l); s[l]=0; mreal res = mgl_data_last(_DT_,s,&ii,&jj,&kk); *i=ii; *j=jj; *k=kk; delete []s; return res; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_first(HCDT d, const char *cond, long *i, long *j, long *k) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); if(!cond) cond = "u"; mglFormula eq(cond); if(*i<0 || *i>=nx) *i=nx; if(*j<0 || *j>=ny) *j=ny-1; if(*k<0 || *k>=nz) *k=nz-1; long i0 = *i+nx*(*j+ny*(*k))-1; mreal x,y,z,dx=nx>1?1/(nx-1.):0,dy=ny>1?1/(ny-1.):0,dz=nz>1?1/(nz-1.):0; for(;i0vthr(i0))) break; } *i = i0%nx; *j = (i0/nx)%ny; *k = i0/(nx*ny); return i0vthr(i0) : NAN; // NOTE: Return NAN if false } mreal MGL_EXPORT mgl_data_first_(uintptr_t *d, const char *cond, int *i, int *j, int *k, int l) { long ii=*i,jj=*j,kk=*k; char *s=new char[l+1]; memcpy(s,cond,l); s[l]=0; mreal res = mgl_data_first(_DT_,s,&ii,&jj,&kk); *i=ii; *j=jj; *k=kk; delete []s; return res; } //----------------------------------------------------------------------------- long MGL_EXPORT mgl_data_find(HCDT d, const char *cond, char dir, long i, long j, long k) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); long m=-1; if(!cond) cond = "u"; mglFormula eq(cond); mreal x=i/(nx-1.),y=j/(ny-1.),z=k/(nz-1.); if(dir=='x' && nx>1) for(m=i;mv(m,j,k))) break; if(dir=='y' && ny>1) for(m=j;mv(i,m,k))) break; if(dir=='z' && nz>1) for(m=k;mv(i,j,m))) break; return m; } int MGL_EXPORT mgl_data_find_(uintptr_t *d, const char *cond, char *dir, int *i, int *j, int *k, int l, int) { char *s=new char[l+1]; memcpy(s,cond,l); s[l]=0; int res = mgl_data_find(_DT_,s,*dir,*i,*j,*k); delete []s; return res; } //----------------------------------------------------------------------------- int MGL_EXPORT mgl_data_find_any(HCDT d, const char *cond) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); bool cc = false; if(!cond || *cond==0) cond = "u"; mglFormula eq(cond); #pragma omp parallel for collapse(3) for(long k=0;kv(i,j,k))) cc = true; } return cc; } int MGL_EXPORT mgl_data_find_any_(uintptr_t *d, const char *cond, int l) { char *s=new char[l+1]; memcpy(s,cond,l); s[l]=0; int res = mgl_data_find_any(_DT_,s); delete []s; return res; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_momentum_val(HCDT dd, char dir, mreal *x, mreal *w, mreal *s, mreal *k) { long nx=dd->GetNx(),ny=dd->GetNy(),nz=dd->GetNz(); mreal i0=0,i1=0,i2=0,i3=0,i4=0; switch(dir) { case 'x': #pragma omp parallel for reduction(+:i0,i1,i2,i3,i4) for(long i=0;ivthr(i); i0+= v; i1+= v*d; i2+= v*t; i3+= v*d*t; i4+= v*t*t; } break; case 'y': #pragma omp parallel for reduction(+:i0,i1,i2,i3,i4) for(long i=0;ivthr(i); i0+= v; i1+= v*d; i2+= v*t; i3+= v*d*t; i4+= v*t*t; } break; case 'z': #pragma omp parallel for reduction(+:i0,i1,i2,i3,i4) for(long i=0;ivthr(i); i0+= v; i1+= v*d; i2+= v*t; i3+= v*d*t; i4+= v*t*t; } break; default: // "self-dispersion" i0 = nx*ny*nz; #pragma omp parallel for reduction(+:i1,i2,i3,i4) for(long i=0;ivthr(i), t = v*v; i1+= v; i2+= t; i3+= v*t; i4+= t*t; } } if(i0==0) return 0; mreal d=i1/i0; if(x) *x=d; if(w) *w=i2>d*d*i0 ? sqrt(i2/i0-d*d) : 0; if(s) *s=i3/i0; if(k) *k=i4/(i0*3); return i0; } mreal MGL_EXPORT mgl_data_momentum_val_(uintptr_t *d, char *dir, mreal *m, mreal *w, mreal *s, mreal *k,int) { mreal mm=0,ww=0,ss=0,kk=0,aa=0; aa = mgl_data_momentum_val(_DT_,*dir,&mm,&ww,&ss,&kk); *m=mm; *w=ww; *s=ss; *k=kk; return aa; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_norm_slice(HMDT d, mreal v1,mreal v2,char dir,long keep_en,long sym) { long nx=d->nx, ny=d->ny, nz=d->nz; mreal *a=d->a; mglData b(*d); mreal e0=1, e, m1, m2, aa; if(sym) { v2 = -v1>v2 ? -v1:v2; v1 = -v2; } if(dir=='z' && nz>1) { //#pragma omp parallel for private(m1,m2,aa,e,e0) // TODO add omp comparison here for(long k=0;kaa ? m2 : aa; e += aa*aa; } if(m1==m2) m2+=1; if(sym) { m2 = -m1>m2 ? -m1:m2; m1 = -m2; } if(keep_en && k) e = e0>0?sqrt(e/e0):1; else { e0 = e; e=1; } for(long i=0;i1) { //#pragma omp parallel for private(m1,m2,aa,e,e0) // TODO add omp comparison here for(long j=0;jaa ? m2 : aa; e += aa*aa; } if(m1==m2) m2+=1; if(sym) { m2 = -m1>m2 ? -m1:m2; m1 = -m2; } if(keep_en && j) e = e0>0?sqrt(e/e0):1; else { e0 = e; e=1; } #pragma omp parallel for collapse(2) for(long k=0;k1) { //#pragma omp parallel for private(m1,m2,aa,e,e0) // TODO add omp comparison here for(long i=0;iaa ? m2 : aa; e += aa*aa; } if(m1==m2) m2+=1; if(sym) { m2 = -m1>m2 ? -m1:m2; m1 = -m2; } if(keep_en && i) e = e0>0?sqrt(e/e0):1; else { e0 = e; e=1; } #pragma omp parallel for for(long k=0;ka, b.a, nx*ny*nz*sizeof(mreal)); } void MGL_EXPORT mgl_data_norm_slice_(uintptr_t *d, mreal *v1,mreal *v2,char *dir,int *keep_en,int *sym,int ) { mgl_data_norm_slice(_DT_,*v1,*v2,*dir,*keep_en,*sym); } //----------------------------------------------------------------------------- MGL_EXPORT const char *mgl_data_info(HCDT d) // NOTE: Not thread safe function! { static char buf[512]; char s[128]; buf[0]=0; snprintf(s,128,"nx = %ld\tny = %ld\tnz = %ld\n",d->GetNx(),d->GetNy(),d->GetNz()); s[127]=0; strcat(buf,s); long i=0,j=0,k=0; mreal A=0,Wa=0,X=0,Y=0,Z=0,Wx=0,Wy=0,Wz=0, b; b = mgl_data_max_int(d,&i,&j,&k); snprintf(s,128,_("Maximum is %g\t at x = %ld\ty = %ld\tz = %ld\n"), b,i,j,k); s[127]=0; strcat(buf,s); b = mgl_data_min_int(d,&i,&j,&k); snprintf(s,128,_("Minimum is %g\t at x = %ld\ty = %ld\tz = %ld\n"), b,i,j,k); s[127]=0; strcat(buf,s); mgl_data_momentum_val(d,'a',&A,&Wa,0,0); mgl_data_momentum_val(d,'x',&X,&Wx,0,0); mgl_data_momentum_val(d,'y',&Y,&Wy,0,0); mgl_data_momentum_val(d,'z',&Z,&Wz,0,0); snprintf(s,128,_("Averages are:\n = %g\t = %g\t = %g\t = %g\n"), A,X,Y,Z); s[127]=0; strcat(buf,s); snprintf(s,128,_("Widths are:\nWa = %g\tWx = %g\tWy = %g\tWz = %g\n"), Wa,Wx,Wy,Wz); s[127]=0; strcat(buf,s); return buf; } int MGL_EXPORT mgl_data_info_(uintptr_t *d, char *out, int len) { const char *res = mgl_data_info(_DA_(d)); if(out) mgl_strncpy(out,res,len); return strlen(res); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_insert(HMDT d, char dir, long at, long num) { if(num<1) return; at = at<0 ? 0:at; long nn, nx=d->nx, ny=d->ny, nz=d->nz, nxy=nx*ny; mglData b; if(dir=='x') { if(at>nx) at=nx; nn=nx+num; b.Create(nn,ny,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(mreal)); if(ata+at+nx*k,(nx-at)*sizeof(mreal)); if(ata[nx*k+at]; // copy values else for(long i=0;ia[nx*k+nx-1]; // copy values } d->Set(b); nx+=num; } if(dir=='y') { if(at>ny) at=ny; nn=num+ny; b.Create(nx,nn,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nx*nn*k, d->a+nxy*k,at*nx*sizeof(mreal)); if(ata+nx*(at+ny*k),(ny-at)*nx*sizeof(mreal)); if(ata+nx*(ny*k+at),nx*sizeof(mreal)); else for(long i=0;ia+nx*(ny*k+ny-1),nx*sizeof(mreal)); } d->Set(b); ny+=num; } if(dir=='z') { if(at>nz) at=nz; b.Create(nx,ny,nz+num); if(at>0) memcpy(b.a, d->a,at*nxy*sizeof(mreal)); if(ata+nxy*at,(nz-at)*nxy*sizeof(mreal)); if(ata+nxy*at,nxy*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ia+nxy*(nz-1),nxy*sizeof(mreal)); d->Set(b); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_delete(HMDT d, char dir, long at, long num) { if(num<1 || at<0) return; mglData b; long nx=d->nx, ny=d->ny, nz=d->nz, nn; if(dir=='x') { if(at+num>=nx) return; nn=nx-num; b.Create(nn,ny,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(mreal)); memcpy(b.a+at+nn*k, d->a+at+num+nx*k,(nx-at-num)*sizeof(mreal)); } d->Set(b); nx-=num; } if(dir=='y') { if(at+num>=ny) return; nn=ny-num; b.Create(nx,nn,nz); #pragma omp parallel for for(long k=0;k0) memcpy(b.a+nx*nn*k, d->a+nx*ny*k,at*nx*sizeof(mreal)); memcpy(b.a+nx*(at+nn*k), d->a+nx*(at+num+ny*k),(ny-at-num)*nx*sizeof(mreal)); } d->Set(b); ny-=num; } if(dir=='z') { if(at+num>=nz) return; b.Create(nx,ny,nz-num); if(at>0) memcpy(b.a, d->a,at*nx*ny*sizeof(mreal)); memcpy(b.a+nx*ny*at, d->a+nx*ny*(at+num),(nz-at-num)*nx*ny*sizeof(mreal)); d->Set(b); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_insert_(uintptr_t *d, const char *dir, int *at, int *num, int) { mgl_data_insert(_DT_,*dir,*at,*num); } void MGL_EXPORT mgl_data_delete_(uintptr_t *d, const char *dir, int *at, int *num, int) { mgl_data_delete(_DT_,*dir,*at,*num); } //----------------------------------------------------------------------------- #define omod(x,y) (y)*((x)>0?int((x)/(y)+0.5):int((x)/(y)-0.5)) void static mgl_omod(mreal *a, mreal da, int nx, int n) { bool qq=true; for(long i=1;ip[2], nn=t->n; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ia+i, t->b[0], nz, nn); return 0; } static void *mgl_sew_y(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], ny=t->p[1], nn=t->n; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ia+(i%nx)+nx*ny*(i/nx), t->b[0], ny, nx); return 0; } static void *mgl_sew_x(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], nn=t->n; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ia+i*nx, t->b[0], nx, 1); return 0; } void MGL_EXPORT mgl_data_sew(HMDT d, const char *dirs, mreal delta) { if(!dirs || *dirs==0) return; long nx=d->nx, ny=d->ny, nz=d->nz; long p[3]={nx,ny,nz}; mreal da = delta; if(strchr(dirs,'x') && nx>1) mglStartThread(mgl_sew_x,0,nz*ny,d->a,&da,0,p); if(strchr(dirs,'y') && ny>1) mglStartThread(mgl_sew_y,0,nz*nx,d->a,&da,0,p); if(strchr(dirs,'z') && nz>1) mglStartThread(mgl_sew_z,0,nx*ny,d->a,&da,0,p); } void MGL_EXPORT mgl_data_sew_(uintptr_t *d, const char *dirs, mreal *da, int l) { char *s=new char[l+1]; memcpy(s,dirs,l); s[l]=0; mgl_data_sew(_DT_,s,*da); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_put_val(HMDT d, mreal val, long xx, long yy, long zz) { long nx=d->nx, ny=d->ny, nz=d->nz; if(xx>=nx || yy>=ny || zz>=nz) return; mreal *a=d->a; if(xx>=0 && yy>=0 && zz>=0) a[xx+nx*(yy+zz*ny)] = val; else if(xx<0 && yy<0 && zz<0) #pragma omp parallel for for(long i=0;inx, ny=d->ny, nz=d->nz; if(xx>=nx || yy>=ny || zz>=nz) return; const mglData *mv = dynamic_cast(v); mreal *a=d->a, vv=v->v(0); const mreal *b = mv?mv->a:0; long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(); if(xx<0 && yy<0 && zz<0) // whole array { long nn = vx>=nx?nx:vx, mm = vy>=ny?ny:vy, ll = vz>=nz?nz:vz; if(nn>1 && mm>1 && ll>1) // #pragma omp parallel for for(long k=0;kv(i,j,k); if(nn>1 && mm>1) // #pragma omp parallel for for(long k=0;kv(i,j); else if(nn>1) // #pragma omp parallel for for(long k=0;kv(i); else // #pragma omp parallel for for(long ii=0;ii=nx?nx:vx, mm = vy>=ny?ny:vy; if(nn>1 && mm>1) // #pragma omp parallel for for(long j=0;jv(i,j); else if(nn>1) // #pragma omp parallel for for(long j=0;jv(i); else // #pragma omp parallel for for(long ii=0;ii=ny?ny:vx, mm = vy>=nz?nz:vy; if(nn>1 && mm>1) // #pragma omp parallel for collapse(2) for(long j=0;jv(i,j); else if(nn>1) // #pragma omp parallel for collapse(2) for(long j=0;jv(i); else // #pragma omp parallel for for(long ii=0;ii=nx?nx:vx, mm = vy>=nz?nz:vy; if(nn>1 && mm>1) // #pragma omp parallel for collapse(2) for(long j=0;jv(i,j); else if(nn>1) // #pragma omp parallel for collapse(2) for(long j=0;jv(i); else // #pragma omp parallel for for(long ii=0;ii=nx?nx:vx; if(nn>1) // #pragma omp parallel for for(long i=0;iv(i); else // #pragma omp parallel for for(long i=0;i=ny?ny:vx; if(nn>1) // #pragma omp parallel for for(long i=0;iv(i); else // #pragma omp parallel for for(long i=0;i=nz?nz:vx; if(nn>1) // #pragma omp parallel for for(long i=0;iv(i); else // #pragma omp parallel for for(long i=0;ip[0], ny=t->p[1], nz=t->p[2], nn=t->n, n2=nx*ny; mreal *b=t->a,au,av,aw,xu,xv,xw,yu,yv,yw,zu,zv,zw; HCDT x=(HCDT)(t->c),y=(HCDT)(t->d),z=(HCDT)(t->e); const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for private(au,av,aw,xu,xv,xw,yu,yv,yw,zu,zv,zw) #endif for(long i0=t->id;i0vthr(i0)-4*x->vthr(i0+1)+x->vthr(i0+2); yu = 3*y->vthr(i0)-4*y->vthr(i0+1)+y->vthr(i0+2); zu = 3*z->vthr(i0)-4*z->vthr(i0+1)+z->vthr(i0+2); } else if(i==nx-1) { au = 3*a[i0]-4*a[i0-1]+a[i0-2]; xu = 3*x->vthr(i0)-4*x->vthr(i0-1)+x->vthr(i0-2); yu = 3*y->vthr(i0)-4*y->vthr(i0-1)+y->vthr(i0-2); zu = 3*z->vthr(i0)-4*z->vthr(i0-1)+z->vthr(i0-2); } else { au = a[i0+1]-a[i0-1]; xu = x->vthr(i0+1)-x->vthr(i0-1); yu = y->vthr(i0+1)-y->vthr(i0-1); zu = z->vthr(i0+1)-z->vthr(i0-1); } if(j==0) { av = 3*a[i0]-4*a[i0+nx]+a[i0+2*nx]; xv = 3*x->vthr(i0)-4*x->vthr(i0+nx)+x->vthr(i0+2*nx); yv = 3*y->vthr(i0)-4*y->vthr(i0+nx)+y->vthr(i0+2*nx); zv = 3*z->vthr(i0)-4*z->vthr(i0+nx)+z->vthr(i0+2*nx); } else if(j==ny-1) { av = 3*a[i0]-4*a[i0-nx]+a[i0+(ny-3)*nx]; xv = 3*x->vthr(i0)-4*x->vthr(i0-nx)+x->vthr(i0-2*nx); yv = 3*y->vthr(i0)-4*y->vthr(i0-nx)+y->vthr(i0-2*nx); zv = 3*z->vthr(i0)-4*z->vthr(i0-nx)+z->vthr(i0-2*nx); } else { av = a[i0+nx]-a[i0-nx]; xv = x->vthr(i0+nx)-x->vthr(i0-nx); yv = y->vthr(i0+nx)-y->vthr(i0-nx); zv = z->vthr(i0+nx)-z->vthr(i0-nx); } if(k==0) { aw = 3*a[i0]-4*a[i0+n2]+a[i0+2*n2]; xw = 3*x->vthr(i0)-4*x->vthr(i0+n2)+x->vthr(i0+2*n2); yw = 3*y->vthr(i0)-4*y->vthr(i0+n2)+y->vthr(i0+2*n2); zw = 3*z->vthr(i0)-4*z->vthr(i0+n2)+z->vthr(i0+2*n2); } else if(k==nz-1) { aw = 3*a[i0]-4*a[i0-n2]+a[i0-2*n2]; xw = 3*x->vthr(i0)-4*x->vthr(i0-n2)+x->vthr(i0-2*n2); yw = 3*y->vthr(i0)-4*y->vthr(i0-n2)+y->vthr(i0-2*n2); zw = 3*z->vthr(i0)-4*z->vthr(i0-n2)+z->vthr(i0-2*n2); } else { aw = a[i0+n2]-a[i0-n2]; xw = x->vthr(i0+n2)-x->vthr(i0-n2); yw = y->vthr(i0+n2)-y->vthr(i0-n2); zw = z->vthr(i0+n2)-z->vthr(i0-n2); } b[i0] = (au*yv*zw-av*yu*zw-au*yw*zv+aw*yu*zv+av*yw*zu-aw*yv*zu) / (xu*yv*zw-xv*yu*zw-xu*yw*zv+xw*yu*zv+xv*yw*zu-xw*yv*zu); } return 0; } static void *mgl_diff_2(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], ny=t->p[1], nn=t->n, same=t->p[2]; mreal *b=t->a,au,av,xu,xv,yu,yv; HCDT x=(HCDT)(t->c),y=(HCDT)(t->d); const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for private(au,av,xu,xv,yu,yv) #endif for(long i0=t->id;i0vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2); yu = 3*y->vthr(i1)-4*y->vthr(i1+1)+y->vthr(i1+2); } else if(i==nx-1) { au = 3*a[i0]-4*a[i0-1]+a[i0-2]; xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2); yu = 3*y->vthr(i1)-4*y->vthr(i1-1)+y->vthr(i1-2); } else { au = a[i0+1]-a[i0-1]; xu = x->vthr(i1+1)-x->vthr(i1-1); yu = y->vthr(i1+1)-y->vthr(i1-1); } if(j==0) { av = 3*a[i0]-4*a[i0+nx]+a[i0+2*nx]; xv = 3*x->vthr(i1)-4*x->vthr(i1+nx)+x->vthr(i1+2*nx); yv = 3*y->vthr(i1)-4*y->vthr(i1+nx)+y->vthr(i1+2*nx); } else if(j==ny-1) { av = 3*a[i0]-4*a[i0-nx]+a[i0-2*nx]; xv = 3*x->vthr(i1)-4*x->vthr(i1-nx)+x->vthr(i1-2*nx); yv = 3*y->vthr(i1)-4*y->vthr(i1-nx)+y->vthr(i1-2*nx); } else { av = a[i0+nx]-a[i0-nx]; xv = x->vthr(i1+nx)-x->vthr(i1-nx); yv = y->vthr(i1+nx)-y->vthr(i1-nx); } b[i0] = (av*yu-au*yv)/(xv*yu-xu*yv); } return 0; } static void *mgl_diff_1(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], nn=t->n, same=t->p[1]; mreal *b=t->a,au,xu; HCDT x=(HCDT)(t->c); const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for private(au,xu) #endif for(long i0=t->id;i0vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2); } else if(i==nx-1) { au = 3*a[i0]-4*a[i0-1]+a[i0-2]; xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2); } else { au = a[i0+1]-a[i0-1]; xu = x->vthr(i1+1)-x->vthr(i1-1); } b[i0] = au/xu; } return 0; } void MGL_EXPORT mgl_data_diff_par(HMDT d, HCDT x, HCDT y, HCDT z) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), nn=nx*ny*nz; if(nx<2 || ny<2) return; mreal *b = new mreal[nn]; memset(b,0,nn*sizeof(mreal)); long p[3]={nx,ny,nz}; if(x&&y&&z && x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn) mglStartThread(mgl_diff_3,0,nn,b,d->a,(const mreal *)x,p,0,(const mreal *)y,(const mreal *)z); else if(x&&y && x->GetNx()*x->GetNy()==nx*ny && y->GetNx()*y->GetNy()==nx*ny) { p[2]=(x->GetNz()==nz && y->GetNz()==nz); mglStartThread(mgl_diff_2,0,nn,b,d->a,(const mreal *)x,p,0,(const mreal *)y); } else if(x && x->GetNx()==nx) { p[1]=(x->GetNy()*x->GetNz()==ny*nz); mglStartThread(mgl_diff_1,0,nn,b,d->a,(const mreal *)x,p,0,0); } memcpy(d->a,b,nn*sizeof(mreal)); delete []b; } void MGL_EXPORT mgl_data_diff_par_(uintptr_t *d, uintptr_t *v1, uintptr_t *v2, uintptr_t *v3) { mgl_data_diff_par(_DT_,_DA_(v1),_DA_(v2),_DA_(v3)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_set_value(HMDT dat, mreal v, long i, long j, long k) { if(i>=0 && inx && j>=0 && jny && k>=0 && knz) dat->a[i+dat->nx*(j+dat->ny*k)]=v; } void MGL_EXPORT mgl_data_set_value_(uintptr_t *d, mreal *v, int *i, int *j, int *k) { mgl_data_set_value(_DT_,*v,*i,*j,*k); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_data_get_value(HCDT dat, long i, long j, long k) { long nx = dat->GetNx(), ny = dat->GetNy(); return (i>=0 && i=0 && j=0 && kGetNz()) ? dat->vthr(i+nx*(j+ny*k)):NAN; } mreal MGL_EXPORT mgl_data_get_value_(uintptr_t *d, int *i, int *j, int *k) { return mgl_data_get_value(_DA_(d),*i,*j,*k); } //----------------------------------------------------------------------------- MGL_EXPORT_PURE mreal *mgl_data_data(HMDT dat) { return dat->a; } //----------------------------------------------------------------------------- MGL_EXPORT mreal *mgl_data_value(HMDT dat, long i,long j,long k) { long ii=i*dat->nx*(j+dat->ny*k); return ii>=0 && iiGetNN() ? dat->a+ii : 0; } //----------------------------------------------------------------------------- long MGL_EXPORT mgl_data_get_nx(HCDT dat) { return dat->GetNx(); } long MGL_EXPORT mgl_data_get_ny(HCDT dat) { return dat->GetNy(); } long MGL_EXPORT mgl_data_get_nz(HCDT dat) { return dat->GetNz(); } long MGL_EXPORT mgl_data_get_nx_(uintptr_t *d) { return _DA_(d)->GetNx(); } long MGL_EXPORT mgl_data_get_ny_(uintptr_t *d) { return _DA_(d)->GetNy(); } long MGL_EXPORT mgl_data_get_nz_(uintptr_t *d) { return _DA_(d)->GetNz(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_join(HMDT d, HCDT v) { if(!d || !v) return; long nx=d->nx, ny=d->ny, nz=d->nz, k=nx*ny*nz; const mglData *mv = dynamic_cast(v); long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(), m = vx*vy*vz; if(nx==vx && ny==vy && ny>1) d->nz += vz; else { ny *= nz; vy *= vz; if(nx==vx && nx>1) { d->nz = 1; d->ny = ny+vy; } else { d->ny = d->nz = 1; d->nx = k+m; } } mreal *b = new mreal[k+m]; memcpy(b,d->a,k*sizeof(mreal)); if(mv) memcpy(b+k,mv->a,m*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ivthr(i); if(!d->link) delete []d->a; d->a = b; d->link=false; d->NewId(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_join_(uintptr_t *d, uintptr_t *val) { mgl_data_join(_DT_,_DA_(val)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_refill_gs(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl) { HMDT coef = mgl_gspline_init(xdat, vdat); if(!coef) return; // incompatible dimensions const long nx = dat->nx, nn=dat->ny*dat->nz; mreal x0 = x1-xdat->v(0), dx = (x2-x1)/(nx-1); #pragma omp parallel for for(long i=0;ia[i+j*nx] = d; else dat->a[i+sl*nx] = d; } mgl_delete_data(coef); } //----------------------------------------------------------------------------- mreal MGL_NO_EXPORT mgl_index_1(mreal v, HCDT dat) { long mx=dat->GetNx(); mreal d,d1=0,d2=mx-1,v1,v2; v1 = dat->value(d1,0,0); v2 = dat->value(d2,0,0); long count=0; const mreal eps = MGL_EPSILON-1.; if(fabs(v-v1)0) return NAN; do { d = count<10?(d2-d1)*(v-v1)/(v2-v1)+d1:(d1+d2)/2; count++; mreal val = dat->value(d,0,0); // if(fabs(val-v)1e-5); return d; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_refill_x(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl) { long nx=dat->nx,mx=vdat->GetNx(),nn=dat->ny*dat->nz; if(mx!=xdat->GetNx()) return; // incompatible dimensions mreal dx = (x2-x1)/(nx-1); #pragma omp parallel for for(long i=0;ivalue(u,0,0); if(sl<0) for(long j=0;ja[i+j*nx] = d; else dat->a[i+sl*nx] = d; } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl) { long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),nn=nx*ny; bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN()); if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my)) return; // incompatible dimensions mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1); if(both) { #pragma omp parallel for for(long i=0;ia[i]=NAN; #pragma omp parallel for collapse(2) for(long j=0;jvthr(i0)-x1)/dx, vy0 = (ydat->vthr(i0)-y1)/dy; mreal vx1 = (xdat->vthr(i0+1)-x1)/dx, vy1 = (ydat->vthr(i0+1)-y1)/dy; mreal vx2 = (xdat->vthr(i0+mx)-x1)/dx, vy2 = (ydat->vthr(i0+mx)-y1)/dy; mreal vx3 = (xdat->vthr(i0+mx+1)-x1)/dx, vy3 = (ydat->vthr(i0+mx+1)-y1)/dy; long xx1 = long(mgl_min( mgl_min(vx0,vx1), mgl_min(vx2,vx3) )); // bounding box long yy1 = long(mgl_min( mgl_min(vy0,vy1), mgl_min(vy2,vy3) )); long xx2 = long(mgl_max( mgl_max(vx0,vx1), mgl_max(vx2,vx3) )); long yy2 = long(mgl_max( mgl_max(vy0,vy1), mgl_max(vy2,vy3) )); xx1=mgl_imax(xx1,0); xx2=mgl_imin(xx2,nx-1); yy1=mgl_imax(yy1,0); yy2=mgl_imin(yy2,ny-1); if(xx1>xx2 || yy1>yy2) continue; mreal d1x = vx1-vx0, d1y = vy1-vy0; mreal d2x = vx2-vx0, d2y = vy2-vy0; mreal d3x = vx3+vx0-vx1-vx2, d3y = vy3+vy0-vy1-vy2; mreal dd = d1x*d2y-d1y*d2x; mreal dsx =-4*(d2y*d3x - d2x*d3y)*d1y; mreal dsy = 4*(d2y*d3x - d2x*d3y)*d1x; for(long jj=yy1;jj<=yy2;jj++) for(long ii=xx1;ii<=xx2;ii++) { mreal xx = (ii-vx0), yy = (jj-vy0); mreal s = dsx*xx + dsy*yy + (dd+d3y*xx-d3x*yy)*(dd+d3y*xx-d3x*yy); if(s>=0) { s = sqrt(s); mreal qu = d3x*yy - d3y*xx + dd + s; mreal qv = d3y*xx - d3x*yy + dd + s; mreal u = 2.f*(d2y*xx - d2x*yy)/qu; mreal v = 2.f*(d1x*yy - d1y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad { qu = d3x*yy - d3y*xx + dd - s; qv = d3y*xx - d3x*yy + dd - s; u = 2.f*(d2y*xx - d2x*yy)/qu; v = 2.f*(d1x*yy - d1y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad } i0 = ii+nx*jj; s = vdat->value(i+u,j+v,0); if(sl<0) for(long k=0;ka[i0+k*nn] = s; else dat->a[i0+sl*nn] = s; } } } } else { mglData u(nx), v(ny); #pragma omp parallel for for(long i=0;ivalue(u.a[i],v.a[j],0); long i0=i+nx*j; if(sl<0) for(long k=0;ka[i0+k*nn] = d; else dat->a[i0+sl*nn] = d; } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2) { if(!dat || !xdat || !ydat || !zdat || !vdat) return; long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),mz=vdat->GetNz(); bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN() && zdat->GetNN()==vdat->GetNN()); if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my || zdat->GetNx()!=mz)) return; // incompatible dimensions const mreal acx=1e-6*fabs(x2-x1), acy=1e-6*fabs(y2-y1), acz=1e-6*fabs(z2-z1); if(both) #pragma omp parallel for collapse(3) for(long k=0;kvalueD(dx,dy,dz,&dxx,&dxy,&dxz); vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz); vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz); long count=0; do // use Newton method to find root { if(count>50) { dx=NAN; break; } count++; dd = -dxx*dyy*dzz+dxy*dyx*dzz+dxx*dyz*dzy-dxz*dyx*dzy-dxy*dyz*dzx+dxz*dyy*dzx; dx += ((dyz*dzy-dyy*dzz)*(xx-vx)+(dxy*dzz-dxz*dzy)*(yy-vy)+(dxz*dyy-dxy*dyz)*(zz-vz))/dd; dy += ((dyx*dzz-dyz*dzx)*(xx-vx)+(dxz*dzx-dxx*dzz)*(yy-vy)+(dxx*dyz-dxz*dyx)*(zz-vz))/dd; dz += ((dyy*dzx-dyx*dzy)*(xx-vx)+(dxx*dzy-dxy*dzx)*(yy-vy)+(dxy*dyx-dxx*dyy)*(zz-vz))/dd; vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz); vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz); vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz); } while(fabs(xx-vx)>acx && fabs(yy-vy)>acy && fabs(zz-vz)>acz); // this valid for linear interpolation dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:vdat->value(dx,dy,dz); } else { mglData u(nx), v(ny), w(nz); mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1), dz = (z2-z1)/(nz-1); #pragma omp parallel for for(long i=0;ia[i+nx*(j+ny*k)] = vdat->value(u.a[i],v.a[j],w.a[k]); } } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm) { if(!idat || (jdat && jdat->GetNN()!=idat->GetNN()) || (kdat && kdat->GetNN()!=idat->GetNN())) return 0; const mglData *dd=dynamic_cast(dat); long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz(); mglData *r=new mglData(idat->GetNx(),idat->GetNy(),idat->GetNz()); mreal dx = nx-1, dy = ny-1, dz = nz-1; if(!norm) dx=dy=dz=1; if(dd) #pragma omp parallel for for(long i=0;iGetNN();i++) { mreal x=dx*idat->vthr(i), y=jdat?dy*jdat->vthr(i):0, z=kdat?dz*kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?mglSpline3st(dd->a,nx,ny,nz, x,y,z):NAN; } else #pragma omp parallel for for(long i=0;iGetNN();i++) { mreal x=dx*idat->vthr(i), y=jdat?dy*jdat->vthr(i):0, z=kdat?dz*kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?dat->linear(x,y,z):NAN;; } return r; } uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *d, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm) { return uintptr_t(mgl_data_evaluate(_DT_,_DA_(idat),_DA_(jdat),_DA_(kdat),*norm)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_gspline_init(HCDT x, HCDT v) { long n = v->GetNx(); if(!x || x->GetNx()!=n) return 0; mglData *res = new mglData(5*(n-1)); mreal *xx=0, *vv=0; const mglData *dx = dynamic_cast(x); if(!dx) { xx = new mreal[n]; for(long i=0;iv(i); } const mglData *dv = dynamic_cast(v); if(!dv) { vv = new mreal[n]; for(long i=0;iv(i); } mgl_gspline_init(n,dx?dx->a:xx,dv?dv->a:vv,res->a); if(xx) delete []xx; if(vv) delete []vv; return res; } uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v) { return uintptr_t(mgl_gspline_init(_DA_(x),_DA_(v))); } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_gspline(HCDT c, mreal dx, mreal *d1, mreal *d2) { long i=0, n = c->GetNx(); if(n%5 || dx<0) return NAN; // not the table of coefficients while(dx>c->v(5*i)) { dx-=c->v(5*i); i++; if(5*i>=n) return NAN; } if(d1) *d1 = c->v(5*i+2)+dx*(2*c->v(5*i+3)+3*dx*c->v(5*i+4)); if(d2) *d2 = 2*c->v(5*i+3)+6*dx*c->v(5*i+4); return c->v(5*i+1)+dx*(c->v(5*i+2)+dx*(c->v(5*i+3)+dx*c->v(5*i+4))); } mreal MGL_EXPORT mgl_gspline_(uintptr_t *c, mreal *dx, mreal *d1, mreal *d2) { return mgl_gspline(_DA_(c),*dx,d1,d2); } //----------------------------------------------------------------------------- struct pnt { mreal x,y; pnt(mreal X, mreal Y):x(X),y(Y){} }; mreal static mgl_find_pnt(std::vector &mpos, mreal est, mreal dj) { mreal mv = dj, val=NAN; size_t n = mpos.size(), kk=0; for(size_t k=0;kGetNx(), ny=d->GetNy(); std::vector *max_pos = new std::vector[nx]; if(di<=0) di=dj; for(long i=0;iv(i,j), v1 = d->v(i,j-1), v2 = d->v(i,j+1); if(v>lvl && v1=v2) // NOTE only one edge is required // if(v>lvl && ((v1<=v && v>v2) || (v1=v2))) // NOTE only edges are required { bool c1=false, c2=false; for(long j1=j-1;j1>=0;j1--) { mreal vv = d->v(i,j1); if(vv>v) break; if(vvv(i,j2); if(vv>v) break; if(vv curv; for(long ii=0;iia[2*k] = curv[k].x; res->a[2*k+1] = curv[k].y; } delete []max_pos; return res; } uintptr_t MGL_EXPORT mgl_data_detect_(uintptr_t *d, mreal *lvl, mreal *dj, mreal *di, mreal *min_len) { return uintptr_t(mgl_data_detect(_DT_,*lvl,*dj, *di, *min_len)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_dilate(HMDT d, mreal val, long step) { long nx = d->GetNx(), ny=d->GetNy(), nz=d->GetNz(); if(step<1 || nx<2) return; long *dist = new long[nx*ny*nz], nn = nx*ny; bool done=false; if(nz>1 && ny>1) { done = true; for(long k=0;kvthr(i0)>=val) dist[i0]=0; else { dist[i0] = nx+ny; if(i>0 && dist[i0-1]+10 && dist[i0-nx]+10 && dist[i0-nn]+1=0;k--) for(long j=ny-1;j>=0;j--) for(long i=nx-1;i>=0;i--) { long i0 = i+nx*(j+ny*k); if(i1) { done = true; for(long j=0;jvthr(i0)>=val) dist[i0]=0; else { dist[i0] = nx+ny; if(i>0 && dist[i0-1]+10 && dist[i0-nx]+1=0;j--) for(long i=nx-1;i>=0;i--) { long i0 = i+nx*j; if(iv(i)>=val) dist[i]=0; else { dist[i] = nx; if(i>0 && dist[i-1]+1=0;i--) if(dist[i+1]+1a[i] = dist[i]<=step?1:0; delete []dist; } void MGL_EXPORT mgl_data_dilate_(uintptr_t *d, mreal *val, int *step) { mgl_data_dilate(_DT_,*val,*step); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_erode(HMDT d, mreal val, long step) { long nx = d->GetNx(), ny=d->GetNy(), nz=d->GetNz(); if(step<1 || nx<2) return; long *dist = new long[nx*ny*nz], nn = nx*ny; bool done=false; if(nz>1 && ny>1) { done = true; for(long k=0;kvthr(i0)0 && dist[i0-1]+10 && dist[i0-nx]+10 && dist[i0-nn]+1=0;k--) for(long j=ny-1;j>=0;j--) for(long i=nx-1;i>=0;i--) { long i0 = i+nx*(j+ny*k); if(i1) { done = true; for(long j=0;jvthr(i0)0 && dist[i0-1]+10 && dist[i0-nx]+1=0;j--) for(long i=nx-1;i>=0;i--) { long i0 = i+nx*j; if(iv(i)0 && dist[i-1]+1=0;i--) if(dist[i+1]+1a[i] = dist[i]>step?1:0; delete []dist; } void MGL_EXPORT mgl_data_erode_(uintptr_t *d, mreal *val, int *step) { mgl_data_erode(_DT_,*val,*step); } //----------------------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/export.cpp�������������������������������������������������������������������������0000644�0001750�0001750�00000054620�13513030041�015770� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * export.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #if defined(WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) #include #else #include #endif #include "mgl2/canvas.h" #include "mgl2/canvas_cf.h" #if MGL_HAVE_PNG #include #endif #if MGL_HAVE_JPEG extern "C" { #include } #endif #if MGL_HAVE_GIF #include #endif //----------------------------------------------------------------------------- int MGL_NO_EXPORT mgl_pnga_save(const char *fname, int w, int h, unsigned char **p) { #if MGL_HAVE_PNG bool fl = strcmp(fname,"-"); FILE *fp = fl ? fopen(fname, "wb") : stdout; if (!fp) return 1; png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (png_ptr) { png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr) { png_init_io(png_ptr, fp); png_set_filter(png_ptr, 0, PNG_ALL_FILTERS); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(png_ptr, info_ptr, p); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0); png_write_end(png_ptr, info_ptr); } png_destroy_write_struct(&png_ptr, &info_ptr); } if(fl) fclose(fp); return 0; #else mgl_set_global_warn(_("PNG support was disabled. Please, enable it and rebuild MathGL.")); return 1; #endif } //----------------------------------------------------------------------------- int MGL_NO_EXPORT mgl_png_save(const char *fname, int w, int h, unsigned char **p) { #if MGL_HAVE_PNG bool fl = strcmp(fname,"-"); FILE *fp = fl ? fopen(fname, "wb") : stdout; if (!fp) return 1; png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (png_ptr) { png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr) { png_init_io(png_ptr, fp); png_set_filter(png_ptr, 0, PNG_ALL_FILTERS); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(png_ptr, info_ptr, p); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0); png_write_end(png_ptr, info_ptr); } png_destroy_write_struct(&png_ptr, &info_ptr); } if(fl) fclose(fp); return 0; #else mgl_set_global_warn(_("PNG support was disabled. Please, enable it and rebuild MathGL.")); return 1; #endif } //----------------------------------------------------------------------------- int MGL_NO_EXPORT mgl_bmp_save(const char *fname, int w, int h, unsigned char **p) { bool fl = strcmp(fname,"-"); FILE *fp = fl ? fopen(fname, "wb") : stdout; if (!fp) return 1; char z[4] = {0,0,0,0}; unsigned u = w*h*3 + 54; // BITMAPFILEHEADER fwrite("BM",2,1,fp); fwrite(&u,4,1,fp); fwrite(z,4,1,fp); u=54; fwrite(&u,4,1,fp); // BITMAPINFOHEADER u=40; fwrite(&u,4,1,fp); fwrite(&w,4,1,fp); fwrite(&h,4,1,fp); unsigned short pp=1; fwrite(&pp,2,1,fp); pp=24; fwrite(&pp,2,1,fp); u = w*h*3; fwrite(z,4,1,fp); fwrite(&u,4,1,fp); fwrite(z,4,1,fp); fwrite(z,4,1,fp); fwrite(z,4,1,fp); fwrite(z,4,1,fp); // image for(long i=h-1;i>=0;i--) for(long j=0;j=0;i--) for(long j=0;j0) mgl_printf(fp, gz, "\n"); long jj=h-1-j; mgl_printf(fp, gz, "%02x%02x%02x",p[jj][3*i],p[jj][3*i+1],p[jj][3*i+2]); } mgl_printf(fp, gz, "\n\nshowpage\n%%%%EOF\n"); if(strcmp(fname,"-")) { if(gz) gzclose((gzFile)fp); else fclose((FILE *)fp); } return 0; } //----------------------------------------------------------------------------- int MGL_NO_EXPORT mgl_gif_save(const char *fname, int w, int h, unsigned char **l) { #if MGL_HAVE_GIF #if GIFLIB_MAJOR>=5 GifFileType *fg = EGifOpenFileName(fname, 0, 0); #else GifFileType *fg = EGifOpenFileName(fname, 0); #endif // define colormap GifColorType col[256]; memset(col,0,256*sizeof(GifColorType)); for(int i=0;i<6;i++) for(int j=0;j<6;j++) for(int k=0;k<6;k++) { long m = i+6*(j+6*k); // part 1 col[m].Red = 51*i; col[m].Green=51*j; col[m].Blue =51*k; } // write header #if GIFLIB_MAJOR>=5 ColorMapObject *gmap = GifMakeMapObject(256, col); EGifPutScreenDesc(fg, w, h, 256,0,gmap); GifFreeMapObject(gmap); #else ColorMapObject *gmap = MakeMapObject(256, col); EGifPutScreenDesc(fg, w, h, 256,0,gmap); FreeMapObject(gmap); #endif // write frame EGifPutImageDesc(fg, 0, 0, w, h, 0, 0); GifPixelType *line = new GifPixelType[w*h]; for(long m=0;m5 || (GIFLIB_MAJOR==5 && GIFLIB_MINOR>0) EGifCloseFile(fg,0); #else EGifCloseFile(fg); #endif delete []line; return 0; #else mgl_set_global_warn(_("GIF support was disabled. Please, enable it and rebuild MathGL.")); return 1; #endif } //----------------------------------------------------------------------------- // // Save animation // //----------------------------------------------------------------------------- void mglCanvas::StartGIF(const char *fname, int ms) { #if MGL_HAVE_GIF std::string fn=fname; if(fn.empty()) { fn=PlotId+".gif"; fname = fn.c_str(); } #if GIFLIB_MAJOR>5 || (GIFLIB_MAJOR==5 && GIFLIB_MINOR>0) if(gif) EGifCloseFile(gif,0); #else if(gif) EGifCloseFile(gif); #endif #if GIFLIB_MAJOR>=5 gif = EGifOpenFileName(fname, 0, 0); EGifSetGifVersion(gif,true); #else EGifSetGifVersion("89a"); gif = EGifOpenFileName(fname, 0); #endif // get picture sizes // NOTE: you shouldn't call SetSize() after StartGIF() !!! long width, height; unsigned char *f=0, **l=GetRGBLines(width, height, f); if(f) free(f); if(l) free(l); // define colormap GifColorType col[256]; memset(col,0,256*sizeof(GifColorType)); for(int i=0;i<6;i++) for(int j=0;j<6;j++) for(int k=0;k<6;k++) { long m = i+6*(j+6*k); // part 1 col[m].Red = 51*i; col[m].Green=51*j; col[m].Blue =51*k; } // write header #if GIFLIB_MAJOR>=5 ColorMapObject *gmap = GifMakeMapObject(256, col); EGifPutScreenDesc(gif, width, height, 256,0,gmap); GifFreeMapObject(gmap); #else ColorMapObject *gmap = MakeMapObject(256, col); EGifPutScreenDesc(gif, width, height, 256,0,gmap); FreeMapObject(gmap); #endif // put animation parameters ms /= 10; unsigned char ext1[11] = {0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30}; unsigned char ext2[9] = {0x08, (unsigned char)(ms%256), (unsigned char)(ms/256), 0xff}; unsigned char ext3[3] = {0x01, 0xff, 0xff}; #if GIFLIB_MAJOR>=5 EGifPutExtensionLeader(gif,0xff); EGifPutExtensionBlock(gif,11,ext1); EGifPutExtensionBlock(gif,3,ext3); EGifPutExtensionTrailer(gif); EGifPutExtension(gif,0xf9,4,ext2); #else EGifPutExtensionFirst(gif,0xff,11,ext1); EGifPutExtensionLast(gif,0xff,3,ext3); EGifPutExtension(gif,0xf9,4,ext2); #endif #else mgl_set_global_warn(_("GIF support was disabled. Please, enable it and rebuild MathGL.")); #endif } //----------------------------------------------------------------------------- void mglCanvas::CloseGIF() { #if MGL_HAVE_GIF #if GIFLIB_MAJOR>5 || (GIFLIB_MAJOR==5 && GIFLIB_MINOR>0) if(gif) EGifCloseFile(gif,0); #else if(gif) EGifCloseFile(gif); #endif #else mgl_set_global_warn(_("GIF support was disabled. Please, enable it and rebuild MathGL.")); #endif gif = 0; } //----------------------------------------------------------------------------- int mglCanvas::NewFrame() { Clf(); Identity(); CurFrameId++; return CurFrameId-1; } //----------------------------------------------------------------------------- void mglCanvas::EndFrame() { Finish(); if(get(MGL_VECT_FRAME)) PushDrwDat(); #if MGL_HAVE_GIF if(!gif) return; long width, height, n; unsigned char *f=0, **l=GetRGBLines(width, height, f); n = width*height; if(!l) return; EGifPutImageDesc(gif, 0, 0, width, height, 0, 0); GifPixelType *line = new GifPixelType[n]; for(long m=0;mGetRGBLines(w,h,f,true); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".png"; fname = fn.c_str(); } if(mgl_pnga_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_png_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_png(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_png_solid(HMGL gr, const char *fname,const char *) { long w,h; unsigned char *f=0, **p=0; p =_Gr_->GetRGBLines(w,h,f); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".png"; fname = fn.c_str(); } if(mgl_png_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_png_solid_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_png_solid(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_jpg(HMGL gr, const char *fname,const char *) { long w,h; unsigned char *f=0, **p=0; p =_Gr_->GetRGBLines(w,h,f); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".jpg"; fname = fn.c_str(); } if(mgl_jpeg_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_jpg_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_jpg(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_tga(HMGL gr, const char *fname,const char *) { long w,h; unsigned char *f=0, **p=0; p =_Gr_->GetRGBLines(w,h,f,true); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".tga"; fname = fn.c_str(); } if(mgl_tga_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_tga_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_tga(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_bmp(HMGL gr, const char *fname,const char *) { long w,h; unsigned char *f=0, **p=0; p =_Gr_->GetRGBLines(w,h,f); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".bmp"; fname = fn.c_str(); } if(mgl_bmp_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_bmp_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_bmp(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_bps(HMGL gr, const char *fname,const char *) { long w,h; unsigned char *f=0, **p=0; p =_Gr_->GetRGBLines(w,h,f); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".eps"; fname = fn.c_str(); } if(mgl_bps_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_bps_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_bps(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_gif(HMGL gr, const char *fname,const char *) { long w,h; unsigned char *f=0, **p=0; p =_Gr_->GetRGBLines(w,h,f); if(p) { std::string fn=fname; if(fn.empty()) { fn=gr->PlotId+".gif"; fname = fn.c_str(); } if(mgl_gif_save(fname,w,h,p)) gr->SetWarn(mglWarnOpen,fname); free(p); if(f) free(f); } } void MGL_EXPORT mgl_write_gif_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_gif(_GR_,s,f); delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_start_gif(HMGL gr, const char *fname,int ms) { _Gr_->StartGIF(fname,ms); } void MGL_EXPORT mgl_start_gif_(uintptr_t *gr, const char *fname,int *ms,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; mgl_start_gif(_GR_,s,*ms); delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_close_gif(HMGL gr) { _Gr_->CloseGIF(); } void MGL_EXPORT mgl_close_gif_(uintptr_t *gr) { mgl_close_gif(_GR_); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_write_frame(HMGL gr, const char *fname,const char *descr) { char buf[64]; if(!fname || !fname[0]) { snprintf(buf,64,"%s%04d.jpg",_Gr_->PlotId.c_str(),_Gr_->GetNumFrame()); buf[63]=0; fname = buf; } int len=strlen(fname); if(!strcmp(fname+len-4,".jpg")) mgl_write_jpg(gr,fname,descr); else if(!strcmp(fname+len-5,".jpeg")) mgl_write_jpg(gr,fname,descr); else if(!strcmp(fname+len-4,".prc")) mgl_write_prc(gr,fname,descr,1); else if(!strcmp(fname+len-4,".pdf")) mgl_write_prc(gr,fname,descr,1); else if(!strcmp(fname+len-4,".png")) mgl_write_png(gr,fname,descr); else if(!strcmp(fname+len-4,".eps")) mgl_write_eps(gr,fname,descr); else if(!strcmp(fname+len-5,".epsz")) mgl_write_eps(gr,fname,descr); else if(!strcmp(fname+len-7,".eps.gz")) mgl_write_eps(gr,fname,descr); else if(!strcmp(fname+len-4,".bps")) mgl_write_bps(gr,fname,descr); else if(!strcmp(fname+len-5,".bpsz")) mgl_write_bps(gr,fname,descr); else if(!strcmp(fname+len-7,".bps.gz")) mgl_write_bps(gr,fname,descr); else if(!strcmp(fname+len-4,".svg")) mgl_write_svg(gr,fname,descr); else if(!strcmp(fname+len-5,".svgz")) mgl_write_svg(gr,fname,descr); else if(!strcmp(fname+len-7,".svg.gz")) mgl_write_svg(gr,fname,descr); else if(!strcmp(fname+len-4,".gif")) mgl_write_gif(gr,fname,descr); else if(!strcmp(fname+len-4,".bmp")) mgl_write_bmp(gr,fname,descr); else if(!strcmp(fname+len-4,".tga")) mgl_write_tga(gr,fname,descr); else if(!strcmp(fname+len-5,".mgld")) mgl_export_mgld(gr,fname,descr); else if(!strcmp(fname+len-5,".json")) mgl_write_json(gr,fname,descr); else if(!strcmp(fname+len-6,".jsonz")) mgl_write_json(gr,fname,descr); else if(!strcmp(fname+len-4,".obj")) mgl_write_obj(gr,fname,descr,1); else if(!strcmp(fname+len-4,".tex")) mgl_write_tex(gr,fname,descr); else if(!strcmp(fname+len-4,".xyz")) mgl_write_xyz(gr,fname,descr); else if(!strcmp(fname+len-4,".stl")) mgl_write_stl(gr,fname,descr); else if(!strcmp(fname+len-4,".off")) mgl_write_off(gr,fname,descr,0); // else if(!strcmp(fname+len-4,".x3d")) mgl_write_x3d(gr,fname,descr,1); } void MGL_EXPORT mgl_write_frame_(uintptr_t *gr, const char *fname,const char *descr,int l,int n) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *f=new char[n+1]; memcpy(f,descr,n); f[n]=0; mgl_write_frame(_GR_,s,f); delete []s; delete []f;} //----------------------------------------------------------------------------- #ifdef WIN32 #include #include #endif void MGL_EXPORT mgl_show_image(HMGL gr, const char *viewer, int keep) { static size_t counter=size_t(0xffffffff*mgl_rnd()); char *fname = new char[256], *cmd = new char [288]; #if defined(_MSC_VER) snprintf(fname,128,"%s.png", tmpnam(NULL)); #else snprintf(fname,256,"%s/mathgl%lu.png", P_tmpdir, counter); #endif fname[255]=0; counter++; mgl_write_png_solid(gr,fname,"MathGL ShowImage file"); if(!viewer || !viewer[0]) viewer = MGL_DEF_VIEWER; #ifdef WIN32 if(keep) { snprintf(cmd,288,"%s %s &", viewer,fname); cmd[287]=0; if(system(cmd)==-1) printf(_("Error to call external viewer\n")); Sleep(2000); snprintf(cmd,288,"del %s", fname); } else snprintf(cmd,288,"%s %s; del %s", viewer,fname,fname); #else if(keep) { snprintf(cmd,288,"%s %s &", viewer,fname); cmd[287]=0; if(system(cmd)==-1) printf(_("Error to call external viewer\n")); sleep(2); snprintf(cmd,288,"rm %s", fname); } else snprintf(cmd,288,"%s %s; rm %s", viewer,fname,fname); #endif cmd[287] = 0; if(system(cmd)==-1) printf(_("Error to call external viewer\n")); delete []cmd; delete []fname; } void MGL_EXPORT mgl_show_image_(uintptr_t *gr, const char *viewer, int *keep, int l) { char *s=new char[l+1]; memcpy(s,viewer,l); s[l]=0; mgl_show_image(_GR_,s,*keep); delete []s; } //----------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/axis.cpp���������������������������������������������������������������������������0000644�0001750�0001750�00000114417�13513030041�015414� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * axis.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mgl2/data.h" #include "mgl2/canvas.h" #include "mgl2/prim.h" #include "mgl2/eval.h" std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt); //----------------------------------------------------------------------------- MGL_NO_EXPORT inline struct tm *mgl_localtime (const time_t *clock, tm *result, bool use_utc) { if (!clock || !result) return NULL; const tm *res = use_utc?gmtime(clock):localtime(clock); memcpy(result,res,sizeof(tm)); return result; } //----------------------------------------------------------------------------- long MGL_EXPORT_PURE mgl_have_color(const char *stl) { return mgl_get_num_color(stl,0); // long j=0; // if(stl) for(long i=0;stl[i];i++) // { // if(strchr(MGL_COLORS,stl[i])) j++; // if(stl[i]=='{' && stl[i+1]=='x') j++; // } // return j; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_wcstrim(wchar_t *str) { if(!str || *str==0) return; size_t n=mgl_wcslen(str), k, i; for(k=0;k' ') break; for(i=n;i>k;i--) if(str[i-1]>' ') break; for(size_t j=0;j0?stt:1; } //----------------------------------------------------------------------------- void mglCanvas::SetTicks(char dir, mreal d, int ns, mreal org, const wchar_t *lbl) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); if(aa.f==1) aa.t.clear(); aa.d=d; aa.f=0; aa.ns=ns; aa.o=org; aa.txt.clear(); if(!lbl || *lbl==0) aa.fact.clear(); else aa.fact = lbl; } //----------------------------------------------------------------------------- void mglCanvas::AddTick(char dir, double v, const wchar_t *lbl) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); bool ff = GetFormula(dir); UpdateAxis(); AdjustTicks(aa,ff); if(!v || !lbl || !lbl[0]) { aa.f = 0; return; } aa.f = 2; aa.ns=0; aa.ds=0; aa.AddLabel(lbl,v); } //----------------------------------------------------------------------------- void mglCanvas::AddTick(char dir, double v, const char *lbl) { MGL_TO_WCS(lbl,AddTick(dir,v,wcs)); } //----------------------------------------------------------------------------- void mglCanvas::SetTicksVal(char dir, HCDT v, const wchar_t *lbl, bool add) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); bool ff = GetFormula(dir); if(add) { UpdateAxis(); AdjustTicks(aa,ff); } else aa.txt.clear(); if(!v || !lbl || !lbl[0]) { aa.f = 0; return; } aa.f = 2; aa.ns=0; aa.ds=0; long i=0,l=0,n=v->GetNx(); for(long j=0;iv(i)); i++; l=j+1; } if(j>1 && lbl[j]=='n' && lbl[j-1]=='\\') { aa.AddLabel(std::wstring(lbl+l,j-l-1),v->v(i)); i++; l=j+1; } } if(iv(i)); } //----------------------------------------------------------------------------- void mglCanvas::SetTicksVal(char dir, HCDT v, const char *lbl, bool add) { MGL_TO_WCS(lbl,SetTicksVal(dir,v,wcs,add)); } //----------------------------------------------------------------------------- void mglCanvas::SetTicksVal(char dir, const wchar_t *lbl, bool add) { long i=0,len=mgl_wcslen(lbl); for(long j=1;j63) i=63; mglData val(i+1); val.Fill(Min.x,Max.x); SetTicksVal(dir, &val, lbl, add); } //----------------------------------------------------------------------------- void mglCanvas::SetTicksVal(char dir, const char *lbl, bool add) { long i=0,len=strlen(lbl); for(long j=1;j63) i=63; mglData val(i+1); val.Fill(Min.x,Max.x); SetTicksVal(dir, &val, lbl, add); } //----------------------------------------------------------------------------- void mglCanvas::SetTicksVal(char dir, HCDT v, const wchar_t **lbl, bool add) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); bool ff = GetFormula(dir); if(add) { UpdateAxis(); AdjustTicks(aa,ff); } else aa.txt.clear(); if(!v || !lbl) { aa.f = 0; return; } aa.f = 2; aa.ns=0; aa.ds=0; long n=v->GetNx(); for(long i=0;iv(i)); } //----------------------------------------------------------------------------- void mglCanvas::SetTicksVal(char dir, HCDT v, const char **lbl, bool add) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); bool ff = GetFormula(dir); aa.txt.clear(); if(add) { UpdateAxis(); AdjustTicks(aa,ff); } if(!v || !lbl) { aa.f = 0; return; } aa.f = 2; aa.ns=0; aa.ds=0; for(long i=0;iGetNx();i++) MGL_TO_WCS(lbl[i],aa.AddLabel(wcs,v->v(i))); } //----------------------------------------------------------------------------- void mglCanvas::SetTickTempl(char dir, const wchar_t *t) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); if(aa.f==1) aa.f = 0; // remove time ticks if(!t || !t[0]) aa.t.clear(); else aa.t=t; } //----------------------------------------------------------------------------- void mglCanvas::SetTickTempl(char dir, const char *t) { if(!strchr("xyzca",dir)) return; mglAxis &aa = GetAxis(dir); if(aa.f==1) aa.f = 0; // remove time ticks if(!t || !t[0]) aa.t.clear(); else MGL_TO_WCS(t,aa.t=wcs); } //----------------------------------------------------------------------------- static double mgl_adj_val(double v,mreal *ds=0) { double n = floor(log10(v)), s; v = floor(v*pow(10.,-n)); n = pow(10.,n); if(v==1) { v = n/5; s=n/10; } else if(v<4){ v = n/2; s=n/10; } else if(v<7){ v = n; s=n/5; } else { v = 2*n; s=n/2; } if(ds) *ds=s; return v; } //----------------------------------------------------------------------------- void mglCanvas::SetTickTime(char dir, mreal d, const char *t) { if(!strchr("xyzca",dir)) return; mglAxis &aa = (dir=='x' ? ax : (dir=='y' ? ay : (dir=='z' ? az : ac))); UpdateAxis(); time_t tt; tm t1,t2; tt=(time_t)aa.v1; mgl_localtime(&tt, &t1, get(MGL_USE_GMTIME)); tt=(time_t)aa.v2; mgl_localtime(&tt, &t2, get(MGL_USE_GMTIME)); if(aa.v11 ? "%x" : "%X"; if(abs(t1.tm_year-t2.tm_year)>3) t = "%Y"; } mreal ds=0; if(d==0) // try to select optimal step { if(abs(t1.tm_year-t2.tm_year)>1) // number of second in year NOTE: improve it { d = 365.25*24*3600*mgl_adj_val(abs(t1.tm_year-t2.tm_year),&ds); ds *= 365.25*24*3600; } // NOTE here should be months ... but it is too unregular ... so omit it now // else if(t1.tm_mon!=t2.tm_mon) d = 30*24*3600; // number of second in month else if(abs(t1.tm_yday-t2.tm_yday)>=14) // number of second in week { d = mgl_adj_val(abs(t1.tm_yday-t2.tm_yday)/7,&ds); ds = ((ds<1)?1./7:ds)*7*24*3600; d = ((d>=1)?d:1)*7*24*3600; } else if(abs(t1.tm_yday-t2.tm_yday)>1) // localtime("%x") cannot print time < 1 day { d = 24*3600.*mgl_adj_val(abs(t1.tm_yday-t2.tm_yday),&ds); ds *= 24*3600; if(d<24*3600) { d=24*3600; ds=d/2;} } else if(abs(t1.tm_hour-t2.tm_hour)>1) { d = 3600.*mgl_adj_val(abs(t1.tm_hour-t2.tm_hour),&ds); ds *=3600; } else if(abs(t1.tm_min-t2.tm_min)>1) { d = 60*mgl_adj_val(abs(t1.tm_min-t2.tm_min),&ds); ds *=60; } else if(abs(t1.tm_sec-t2.tm_sec)>1) // localtime("%X") cannot print time < 1 sec { d = mgl_adj_val(abs(t1.tm_sec-t2.tm_sec),&ds); if(d<1) { d=1; ds=0.5;} } else // adjust msec. NOTE: this is not supported by localtime() !!! d = mgl_adj_val(fabs(aa.v2-aa.v1),&ds); } aa.ds = ds; aa.dv = d; aa.f = 1; aa.txt.clear(); MGL_TO_WCS(t,aa.t=wcs); if(strchr("xyztuvw",aa.ch)) aa.org.Set(GetOrgX(aa.ch,aa.inv), GetOrgY(aa.ch,aa.inv), GetOrgZ(aa.ch,aa.inv)); if(aa.ch=='x') aa.v0 = aa.org.x; if(aa.ch=='y') aa.v0 = aa.org.y; if(aa.ch=='z') aa.v0 = aa.org.z; mreal v, v0 = mgl_isnan(aa.o) ? aa.v0 : aa.o, v1; if(aa.v2>aa.v1) { v1 = aa.v2; v0 = v0 - aa.dv*floor((v0-aa.v1)/aa.dv+1e-3); } else { v1 = aa.v1; v0 = v0 - aa.dv*floor((v0-aa.v2)/aa.dv+1e-3); } if(v0+aa.dv!=v0 && v1+aa.dv!=v1) for(v=v0;v<=v1;v+=aa.dv) { wchar_t buf[64]; tt = (time_t)v; tm tp; mgl_localtime(&tt, &tp, get(MGL_USE_GMTIME)); wcsftime(buf,64,aa.t.c_str(),&tp); aa.AddLabel(buf,v); } } //----------------------------------------------------------------------------- void mglCanvas::AdjustTicks(const char *dir, bool force, std::string stl) { if(force) SetTuneTicks(3); UpdateAxis(); if(strchr(dir,'x') || strchr(dir,'X')) // NOTE dir have to be non-NULL here !!! { if(force) ax.d=0; ax.stl=stl; AdjustTicks(ax,fx!=0); } if(strchr(dir,'y') || strchr(dir,'Y')) { if(force) ay.d=0; ay.stl=stl; AdjustTicks(ay,fy!=0); } if(strchr(dir,'z') || strchr(dir,'Z')) { if(force) az.d=0; az.stl=stl; AdjustTicks(az,fz!=0); } if(strchr(dir,'a') || strchr(dir,'c')) { if(force) ac.d=0; ac.stl=stl; AdjustTicks(ac,fa!=0); } } //----------------------------------------------------------------------------- void mglCanvas::AdjustTicks(mglAxis &aa, bool ff) { double d = fabs(aa.v2-aa.v1); if(aa.f>0) return; if(ff && mgl_islog(aa.v1,aa.v2)) { aa.dv = 0; aa.ds=0; } else if(aa.d>0) { aa.dv = aa.d; aa.ds = aa.d/(abs(aa.ns)+1); } else if(aa.d>-1.5) // like =0 or =-1 { aa.dv = mgl_adj_val(d,&aa.ds); aa.o=0; } else { d /= -aa.d; long n = lrint(floor(log10(d))); aa.dv = pow(10.,n)*mgl_int(d*pow(10.,-n)); aa.o=0; aa.ds = pow(10.,n); } LabelTicks(aa); } //----------------------------------------------------------------------------- static int mgl_tick_ext(mreal a, mreal b, wchar_t s[32], mreal &v) { int kind = 0; if(fabs(a-b)<=0.01*fabs(a)) { kind = 1; v = fabs(a-b); if(v>1000.f) { int k=int(log10(v)-0.01); kind=3; v=mgl_ipow(10.,k); mglprintf(s, 32, L" (@{\\times{}10^{%d}})", k); } else if(v<0.02f) { int k=int(log10(v)-0.01)-1; kind=3; v=mgl_ipow(10.,k); mglprintf(s, 32, L" (@{\\times{}10^{%d}})", k); } } else { v = fabs(b)>fabs(a)?fabs(b):fabs(a); if(v>=1000.f) { kind = 2; int k=int(log10(v)-0.01); v=mgl_ipow(10.,k); mglprintf(s, 32, L" \\times 10^{%d}", k); } else if(v<=1e-3f) { kind = 2; int k=int(log10(v)-0.01)-1; v=mgl_ipow(10.,k); mglprintf(s, 32, L" \\times 10^{%d}", k); } } return kind; } //----------------------------------------------------------------------------- /*static std::wstring mgl_format(mreal v1, mreal v2, bool zero) { v1=fabs(v1); v2=fabs(v2); if(v1>v2) v2=v1; wchar_t str[5]=L"%.3g"; int prec=int(2-log10(v2)); if(prec<0) prec=0; if(v2<=0.001 || v2>=10000) { str[2] = '2'; str[3]='e'; } else if(zero) { str[2] = '0'+prec; str[3]='f'; } return str; }*/ //----------------------------------------------------------------------------- static std::wstring mgl_tick_text(mreal z, mreal z0, mreal d, mreal v, int kind, const std::wstring &fact, mreal step, const char *stl) { std::wstring str; bool ff = step>0 && !fact.empty();// && mgl_wcslen(str)+fact.length()<62; if(ff) z/=step; mreal u = fabs(z)z0) u = fabs(z-z0)z0)) u /= v; str = mgl_ftoa(u,stl?stl:""); if((kind&1) && z>z0) str = L"@{(+"+str+L")}"; // if(kind&1) fmt = z>z0?L"@{(+"+fmt+L")}":L"%g"; // mglprintf(str,64,fmt.c_str(), u); if(ff) { if(str==L"-1" || str==L"+1" || str==L"\u22121") str = str[0] + fact; else if(str==L"1") str = fact; else if(str!=L"0") str += fact; } return str; } //----------------------------------------------------------------------------- void mglCanvas::LabelTicks(mglAxis &aa) { if(strchr("xyztuvw",aa.ch)) aa.org.Set(GetOrgX(aa.ch,aa.inv), GetOrgY(aa.ch,aa.inv), GetOrgZ(aa.ch,aa.inv)); if(aa.ch=='x') aa.v0 = aa.org.x; if(aa.ch=='y') aa.v0 = aa.org.y; if(aa.ch=='z') aa.v0 = aa.org.z; wchar_t buf[64]=L""; if(aa.f) return; aa.txt.clear(); bool minus = mglchr(aa.stl.c_str(),'-') && !mglchr(aa.stl.c_str(),'+'); if(aa.dv==0 && aa.v1>0) // positive log-scale { mreal v1 = aa.v1, v2 = aa.v2; if(v1>v2) { v1 = aa.v2; v2 = aa.v1; } mreal v0 = exp(M_LN10*floor(0.1+log10(v1))); int ds = int(floor(0.1+log10(v2/v0))/7)+1; for(mreal v=v0;v<=v2*MGL_EPSILON;v*=10) if(v*MGL_EPSILON>=v1) { int d = int(floor(0.1+log10(v))); if(d==0) wcscpy(buf,L"1"); else if(d==1) wcscpy(buf,L"10"); else if(d>0) mglprintf(buf,64,L"10^{%d}",d); else mglprintf(buf,64,minus?L"10^{-%d}":L"10^{\u2212%d}",-d); if(d%ds!=0) *buf=0; // remove too often log ticks aa.AddLabel(buf,v); } } else if(aa.dv==0 && aa.v2<0) // negative log-scale { mreal v1 = aa.v1, v2 = aa.v2; if(v1>v2) { v1 = aa.v2; v2 = aa.v1; } mreal v0 = -exp(M_LN10*floor(0.1+log10(-v2))); int ds = int(floor(0.1+log10(v1/v0))/7)+1; for(mreal v=v0;v>=v1*MGL_EPSILON;v*=10) if(v*MGL_EPSILON<=v2) { int d = int(floor(0.1+log10(-v))); if(d==0) wcscpy(buf,minus?L"-1":L"\u22121"); else if(d==1) wcscpy(buf,minus?L"-10":L"\u221210"); else if(d>0) mglprintf(buf,64,minus?L"-10^{%d}":L"\u221210^{%d}",d); else mglprintf(buf,64,minus?L"-10^{-%d}":L"\u221210^{\u2212%d}",-d); if(d%ds!=0) *buf=0; // remove too often log ticks aa.AddLabel(buf,v); } } else if(aa.dv) // ticks drawing { mreal w=0; int kind=0; wchar_t s[32]=L""; if(aa.t.empty() && TuneTicks && !strchr(aa.stl.c_str(),'!')) kind = mgl_tick_ext(aa.v2, aa.v1, s, w); if(((TuneTicks&1)==0 && kind==2) || ((TuneTicks&2)==0 && kind!=2)) kind=0; mreal v0 = mgl_isnan(aa.o) ? aa.v0 : aa.o, v1; if(mgl_isnan(v0)) v0=0; if(aa.v2>aa.v1) { v1 = aa.v2; v0 = v0 - aa.dv*floor((v0-aa.v1)/aa.dv+1e-3); } else { v1 = aa.v1; v0 = v0 - aa.dv*floor((v0-aa.v2)/aa.dv+1e-3); } if(v0+aa.dv!=v0 && v1+aa.dv!=v1) { if(aa.t.empty()) for(mreal v=v0;v<=v1;v+=aa.dv) aa.AddLabel(mgl_tick_text(v,v0,aa.dv/100,w,kind,aa.fact,aa.d,aa.stl.c_str()),v); else for(mreal v=v0;v<=v1;v+=aa.dv) { if(aa.t[0]!='&') mglprintf(buf, 64, aa.t.c_str(), fabs(v)0) for(long i=0;iaa.v1 && fabs(u-exp(M_LN10*floor(0.1+log10(u))))<0.01*u) for(long j=2;j<10 && v*j0 && !get(MGL_NOSUBTICKS) && (fabs(aa.v1)>1e-150 || fabs(aa.v2)>1e-150)) { if(aa.v2>aa.v1) v0 = v0 - aa.ds*floor((v0-aa.v1)/aa.ds+1e-3); else v0 = v0 - aa.ds*floor((v0-aa.v2)/aa.ds+1e-3); if(v0+aa.ds!=v0 && aa.v2+aa.ds!=aa.v2) { if(*SubTStl && !have_color) SetPenPal(SubTStl); for(v=v0;(v-aa.v2)*(v-aa.v1)<=0;v+=aa.ds) tick_draw(o+d*v,da,db,1); } } if(!have_color) SetPenPal(AxisStl); if(text&1) DrawLabels(aa); EndGroup(); } //----------------------------------------------------------------------------- void mglCanvas::DrawLabels(mglAxis &aa, bool inv, const mglMatrix *M) { if(M==0) M=&B; if(strchr("xyz",aa.ch)) aa.org.Set(GetOrgX(aa.ch,aa.inv), GetOrgY(aa.ch,aa.inv), GetOrgZ(aa.ch,aa.inv)); if(aa.ch=='x') aa.v0 = aa.org.x; if(aa.ch=='y') aa.v0 = aa.org.y; if(aa.ch=='z') aa.v0 = aa.org.z; mglPoint d(aa.dir), o(aa.org), q(NAN); // "transverse" org if(strchr("xyz",aa.ch)) o -= d*(o*d); mglPoint s=(Min+Max)/2, dv(mgl_sign(s.x-o.x), mgl_sign(s.y-o.y), mgl_sign(s.z-o.z)); mglPoint a = aa.a*(dv*aa.a) + aa.b*(dv*aa.b); if(aa.ch=='c') a = aa.a; long n = aa.txt.size(); mreal *w=new mreal[n], wsp = 2*TextWidth(" ",FontDef,-1); long *kk=new long[n], kq = AllocPnts(n); #pragma omp parallel for for(long i=0;iaa.v2 || aa.txt[i+1].val>aa.v2)) continue; if(kk[i]<0 || kk[i+1]<0) continue; mreal v = (GetPntP(kk[i+1])-GetPntP(kk[i])).norm(); // distance between ticks mreal vv = (w[i]+w[i+1])/2-wsp; // length of labels if(v>0 && l < vv/v) l = vv/v; if(c>v) c = v; } h /= c; mreal tet=0; if(mgl_isnum(aa.angl)) tet = aa.angl*M_PI/180; // manual rotation else if(get(MGL_ENABLE_RTEXT) && get(MGL_TICKS_ROTATE) && l>1) // try rotate first { mreal t1 = 1.1*h<1 ? asin(1.1*h) : M_PI/2; mreal r2 = l*l+h*h; mreal t2 = r2*1.21>1 ? asin((l*sqrt(r2-1/1.21)+h/1.1)/r2):M_PI/2; tet = t1l1?l1:l2; } char *align=new char[n], *up=new char[n]; for(long i=0;i=0) // select proper align { mglPoint p(a),r(o+d*aa.txt[i].val); ScalePoint(M, r, p, false); mglPnt &pp = Pnt[kk[i]]; mreal ux=pp.u*cs + pp.v*sn, uy=pp.v*cs - pp.u*sn; bool Nrot = !get(MGL_ENABLE_RTEXT) || !get(MGL_TICKS_ROTATE); bool Vcnt = ux==0 && uy!=0 && Nrot; bool algn = tet!=0; // TODO add proper align for arbitrary tet! if(ux*ux+uy*uy!=0 && Nrot) { ux=1; uy=0; algn=true; } if(ux<0 || (ux==0 && uy<0)) { ux=-ux; uy=-uy; pp.w=-pp.w; } pp.u = ux; pp.v = uy; mreal pu = p.x*ux+p.y*uy, pv = p.y*ux-p.x*uy; /*, su = ps.x*ux+ps.y*uy;*/ if(Vcnt) up[i]='V'; else if(aa.ch!='c') up[i] = ((pv>0) ^ inv) ? 'T':'t'; else up[i]=(aa.ns==0 || aa.ns==3)?'t':'T'; int t=0; if(algn) { if(aa.ch!='c') t= (pu==0)?0:(pu<0? -1:1); else t=inv?-1:1; } char val[3]={'L','C','R'}; align[i] = val[t+1]; } long k = get(MGL_TICKS_SKIP) ? 1+l : 1; for(long i=0;i=0) { mreal v = aa.txt[i].val; if(get(MGL_NO_ORIGIN) && v==aa.v0) continue; if(v>aa.v1 && v0 ? 't':'T'; } //----------------------------------------------------------------------------- void mglCanvas::tick_draw(mglPoint o, mglPoint d1, mglPoint d2, int f) { if(TickLen==0) return; // try to exclude ticks out of axis range if(f && ((o.x-Min.x)*(o.x-Max.x)>0 || (o.y-Min.y)*(o.y-Max.y)>0 || (o.z-Min.z)*(o.z-Max.z)>0)) return; mreal v = font_factor*TickLen/sqrt(1.f+f*st_t); mglPoint p=o; ScalePoint(&B,o, d1, false); d1.Normalize(); ScalePoint(&B,p, d2, false); d2.Normalize(); long k1 = AddPnt(&B, p+d1*v, CDef, mglPoint(NAN), 0, 0); long k2 = AddPnt(&B, p, CDef, mglPoint(NAN), 0, 0); long k3 = AddPnt(&B, p+d2*v, CDef, mglPoint(NAN), 0, 0); line_plot(k1,k2); line_plot(k2,k3); } //----------------------------------------------------------------------------- void mglCanvas::Grid(const char *dir, const char *pen, const char *opt) { SaveState(opt); bool at_tick=mglchr(dir,'!'); if(!mglchrs(dir,"xyz")) dir="xyz"; AdjustTicks(dir,false); SetPenPal(pen); static int cgid=1; StartGroup("AxisGrid",cgid++); if(strchr(dir,'x')) DrawGrid(ax,at_tick); if(strchr(dir,'y')) DrawGrid(ay,at_tick); if(strchr(dir,'z')) DrawGrid(az,at_tick); EndGroup(); } //----------------------------------------------------------------------------- static void mgl_drw_grid(HMGL gr, double val, const mglPoint &d, const mglPoint &oa, const mglPoint &ob, const mglPoint &da1, const mglPoint &db1, const mglPoint &da2, const mglPoint &db2) { mglPoint q(oa+d*val); // lines along 'a' long kq = gr->AllocPnts(31); #pragma omp parallel for for(long i=0;i<31;i++) { mreal v=i/30.; gr->AddPntQ(kq+i,q+da1*(1-v)+da2*v); } gr->curve_plot(31,kq); q = ob+d*val; // lines along 'b' kq = gr->AllocPnts(31); #pragma omp parallel for for(long i=0;i<31;i++) { mreal v = i/30.; gr->AddPntQ(kq+i,q+db1*(1-v)+db2*v); } gr->curve_plot(31,kq); } void mglCanvas::DrawGrid(mglAxis &aa, bool at_tick) { mglPoint pp[8]={Min,Min,Min,Min,Max,Max,Max,Max},nan(NAN), oo[8], org=Min; pp[1].x=Max.x; pp[2].y=Max.y; pp[3].z=Max.z; pp[4].x=Min.x; pp[5].y=Min.y; pp[6].z=Min.z; mreal zm=INFINITY; memcpy(oo,pp,8*sizeof(mglPoint)); for(int i=0;i<8;i++) // find deepest point { ScalePoint(&B,pp[i],nan,false); if(pp[i].z0 && !get(MGL_NOSUBTICKS)) { mreal v0 = mgl_isnan(aa.o) ? aa.v0 : aa.o; if(aa.v2>aa.v1) v0 = v0 - aa.ds*floor((v0-aa.v1)/aa.ds+1e-3); else v0 = v0 - aa.ds*floor((v0-aa.v2)/aa.ds+1e-3); fflush(stdout); // somehow this help to bypass bug in GCC 32bit if(v0+aa.ds!=v0 && aa.v2+aa.ds!=aa.v2) for(mreal v=v0;(v-aa.v2)*(v-aa.v1)<=0;v+=aa.ds) mgl_drw_grid(this, v, d, oa, ob, da1, db1, da2, db2); } if(aa.dv) at_tick = false; long n=aa.txt.size(); if(n>0) for(long i=0;iaa.v1 && fabs(u-exp(M_LN10*floor(0.1+log10(u))))<0.01*u) for(long j=2;j<10 && v*j0?1:-1; shift += ac.sh; } if(dir=='x') { AdjustTicks(ax,fx!=0); aa = &ax; if(ax.dv) t = (Min.x+Max.x+pos*(Max.x-Min.x))/2; else t = Min.x*pow(Max.x/Min.x, (pos+1)/2); p.Set(t, GetOrgY(ax.ch,ax.inv), GetOrgZ(ax.ch,ax.inv)); q.Set(1,0,0); shift += ax.sh; } if(dir=='y' && !(TernAxis&3)) { AdjustTicks(ay,fy!=0); aa = &ay; if(ay.dv) t = (Min.y+Max.y+pos*(Max.y-Min.y))/2; else t = Min.y*pow(Max.y/Min.y, (pos+1)/2); p.Set(GetOrgX(ay.ch,ay.inv), t, GetOrgZ(ay.ch,ay.inv)); q.Set(0,1,0); shift += ay.sh; if(TernAxis&3) { q.Set(-1,1,0); pos=-pos; } } if(dir=='y' && (TernAxis&3)) { ty.ch='T'; ty.dir.Set(-1,1); ty.org.Set(1,0,ay.org.z); AdjustTicks(ty,fy!=0); aa = &ty; if(ty.dv) t = (Min.y+Max.y+pos*(Max.y-Min.y))/2; else t = Min.y*pow(Max.y/Min.y, (pos+1)/2); p.Set(GetOrgX(ty.ch,ty.inv), t, GetOrgZ(ty.ch,ty.inv)); q.Set(0,1,0); shift += ty.sh; if(TernAxis&3) { q.Set(-1,1,0); pos=-pos; } } if(dir=='t' && (TernAxis&3)) { ty.ch='t'; ty.dir.Set(0,-1); ty.org.Set(0,1,ay.org.z); AdjustTicks(ty,fy!=0); pos = -pos; aa = &ty; if(ty.dv) t = (Min.y+Max.y+pos*(Max.y-Min.y))/2; else t = Min.y*pow(Max.y/Min.y, (pos+1)/2); p.Set(GetOrgX(ty.ch,ty.inv), t, GetOrgZ(ty.ch,ty.inv)); q.Set(0,1,0); shift += ty.sh; } if(dir=='z') { AdjustTicks(az,fz!=0); aa = &az; if(az.dv) t = (Min.z+Max.z+pos*(Max.z-Min.z))/2; else t = Min.z*pow(Max.z/Min.z, (pos+1)/2); p.Set(GetOrgX(az.ch,az.inv), GetOrgY(az.ch,az.inv), t); q.Set(0,0,1); shift += az.sh; } if(aa) { char font[64],ff[3]=":C"; memset(font,0,64); if(pos<-0.2) ff[1]='L'; if(pos>0.2) ff[1]='R'; mgl_strncpy(font,FontDef,32); strcat(font,ff); long kk = AddPnt(&B, p,-1,q,0,7); ff[1]=0; if(kk>=0) { mglPnt &pp = Pnt[kk]; if(pp.u<0 || (pp.u==0 && pp.v<0)) { pp.u=-pp.u; pp.v=-pp.v; pp.w=-pp.w; } if(dir=='c' && ac.a.y!=0) { ff[0] = ac.a.y>0?'T':'t'; strcat(font,ff); text_plot(kk,text,font,-1.4,ac.a.y>0?shift:0); } else { ff[0] = GetLabelPos(t, kk, *aa); strcat(font,ff); text_plot(kk,text,font,-1.4,(ff[0]=='T'?0.3:0.35)+shift); } } } LoadState(); } //----------------------------------------------------------------------------- void mglCanvas::Box(const char *col, bool ticks) { mglPoint o = Org; mreal tl=TickLen; if(!ticks) TickLen=0; set(MGL_NOSUBTICKS); Org = Min; static int cgid=1; StartGroup("Box",cgid++); Axis("xyz_",col); if(TernAxis&1) { Org.x=Max.x; Org.y=Min.y; Org.z=Max.z; DrawAxis(ax, 0, 0,col); DrawAxis(az, 0, 0,col); Org.x=Min.x; Org.y=Max.y; Org.z=Max.z; DrawAxis(az, 0, 0,col); mglAxis ty(ay); ty.ch='T'; ty.dir.Set(-1,1); ty.org.Set(1,0,Max.z); DrawAxis(ty, 0, 0,col); ty.ch='t'; ty.dir.Set(0,-1); ty.org.Set(0,1,Max.z); DrawAxis(ty, 0, 0,col); } else if(TernAxis&2) { mglAxis ty(az); ty.ch='T'; ty.a.Set(1,0); ty.b.Set(-1,1); ty.dir.Set(-1,0,1); ty.org.Set(1,0,0); DrawAxis(ty, 0, 0,col); ty.ch='t'; ty.a.Set(0,1); ty.b.Set(-1,1); ty.dir.Set(0,-1,1); ty.org.Set(0,1,0); DrawAxis(ty, 0, 0,col); } else { Org.z=Max.z; Axis("xy_",col); Org = Max; Axis("xyz_",col); Org.z=Min.z; Axis("xy_",col); Org.x=Min.x; DrawAxis(az,0,0,col); Org.x=Max.x; Org.y=Min.y; DrawAxis(az,0,0,col); if(mglchr(col,'@')) { // edge points mglPoint p[8]={Min,Min,Min,Min,Max,Max,Max,Max},nan(NAN),oo[8]; p[1].x=Max.x; p[2].y=Max.y; p[3].z=Max.z; p[4].x=Min.x; p[5].y=Min.y; p[6].z=Min.z; mreal zm=INFINITY; int im=0; memcpy(oo,p,8*sizeof(mglPoint)); for(int i=0;i<8;i++) // find deepest point { ScalePoint(&B,p[i],nan,false); if(p[i].z1 && col[i-1]=='{') { color[1]=col[i]; color[2]=col[i+1]; break; } else { color[0]=col[i]; color[1]=0; break; } } } SetPenPal(color); mreal dx = (Max.x-Min.x)/30, dy = (Max.y-Min.y)/30, dz = (Max.z-Min.z)/30; long kq = AllocPnts(3*31*31); #pragma omp parallel for collapse(2) for(long i=0;i<31;i++) for(long j=0;j<31;j++) { long i0=kq+3*(i+31*j); AddPntQ(i0, mglPoint(oo[im].x,Min.y+dy*i,Min.z+dz*j)); AddPntQ(i0+1,mglPoint(Min.x+dx*i,oo[im].y,Min.z+dz*j)); AddPntQ(i0+2,mglPoint(Min.x+dx*i,Min.y+dy*j,oo[im].z)); } for(long i=0;i<30;i++) for(long j=0;j<30;j++) { long i0=kq+3*(i+31*j); quad_plot(i0, i0+3,i0+93,i0+96); quad_plot(i0+1,i0+4,i0+94,i0+97); quad_plot(i0+2,i0+5,i0+95,i0+98); } } } EndGroup(); clr(MGL_NOSUBTICKS); Org=o; TickLen=tl; } //----------------------------------------------------------------------------- void mglCanvas::Colorbar(const char *sch) { bool in = mglchr(sch,'I'); mreal sx = (fabs(B.b[0])+fabs(B.b[1])+fabs(B.b[2]))/B.pf/B1.b[0], x=1; mreal sy = (fabs(B.b[3])+fabs(B.b[4])+fabs(B.b[5]))/B.pf/B1.b[4], y=0; if(mglchr(sch,'<')) { x=in?(1-sx)/2:0.05; y=0; } else if(mglchr(sch,'^')) { x=0; y=in?(1+sy)/2:0.95; } else if(mglchr(sch,'_')) { x=0; y=in?(1-sy)/2:0.05; } else { x=in?(1+sx)/2:0.95; y=0; } Colorbar(sch, x, y, 1, 1); } //----------------------------------------------------------------------------- void mglCanvas::Colorbar(const char *sch, mreal x, mreal y, mreal w, mreal h) { bool in = mglchr(sch,'I'); bool text = !mglchr(sch,'~'); int where = 0; // ‘0’ - right, ‘1’ - left, ‘2’ - above, ‘3’ - under if(mglchr(sch,'>')) where = in?1:0; if(mglchr(sch,'<')) where = in?0:1; if(mglchr(sch,'^')) where = in?3:2; if(mglchr(sch,'_')) where = in?2:3; if(mglchr(sch,'A')) { Push(); Identity(); } ac.stl.clear(); for(const char *s="+E0123456789-fF!";*s;s++) if(mglchr(sch,*s)) ac.stl += *s; AdjustTicks("c",mglchr(sch,'a'),ac.stl.c_str()); long n=256, s = AddTexture(sch); mglData v(n); if(ac.d || fa==0 || Min.c*Max.c<=0) v.Fill(Min.c,Max.c); else if(Min.c>0) { v.Fill(log(Min.c), log(Max.c)); v.Modify("exp(u)"); } else if(Max.c<0) { v.Fill(log(-Min.c), log(-Max.c)); v.Modify("-exp(u)"); } mreal *c=new mreal[n]; for(long i=0;i')) { x=in?(1+sx)/2:1; y=0; } if(mglchr(sch,'<')) { x=in?(1-sx)/2:0; y=0; } if(mglchr(sch,'^')) { x=0; y=in?(1+sy)/2:1; } if(mglchr(sch,'_')) { x=0; y=in?(1-sy)/2:0; } Colorbar(v, sch, x, y, 1, 1); } //----------------------------------------------------------------------------- void mglCanvas::Colorbar(HCDT v, const char *sch, mreal x, mreal y, mreal w, mreal h) { bool in = mglchr(sch,'I'); bool text = !mglchr(sch,'~'); int where = 0; if(mglchr(sch,'>')) where = in?1:0; if(mglchr(sch,'<')) where = in?0:1; if(mglchr(sch,'^')) where = in?3:2; if(mglchr(sch,'_')) where = in?2:3; if(mglchr(sch,'A')) { Push(); Identity(); } ac.stl.clear(); for(const char *s="+E0123456789-fF!";*s;s++) if(mglchr(sch,*s)) ac.stl += *s; AdjustTicks("c",mglchr(sch,'a'),ac.stl.c_str()); mreal *c=new mreal[v->GetNx()]; if(!mgl_have_color(sch)) sch = MGL_DEF_PAL; long s = AddTexture(sch); int nc = GetNumPal(s*256); mreal dc = nc>1 ? 1/(MGL_EPSILON*(nc-1)):0; for(long i=0;iGetNx();i++) c[i] = s+i*dc; colorbar(v, c, where, x, y, w, h, text); delete []c; if(mglchr(sch,'A')) Pop(); } //----------------------------------------------------------------------------- void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, mreal w, mreal h, bool text) { static int cgid=1; StartGroup("Colorbar",cgid++); long n=vv->GetNx(); mreal s3=B.pf,ss=1/s3; // NOTE: colorbar was wider ss=0.9; mglPoint p1,p2; mglMatrix M=B1; M.pf=s3; M.norot=true; set(MGL_DISABLE_SCALE); // NOTE this make colorbar non-thread-safe!!! x = s3*(2*x-1); y = s3*(2*y-1); w *= s3; h *= s3; mask = MGL_SOLID_MASK; const long kq = AllocPnts(n*2); for(long i=0;iv(i))*2-1; p1 = p2 = mglPoint((ss*d+1)*w+x, (ss*d+1)*h+y, s3); switch(where) { case 1: p1.x = x; p2.x = x+0.1*w; break; case 2: p1.y = y-0.1*h; p2.y = y; break; case 3: p1.y = y; p2.y = y+0.1*h; break; default:p1.x = x-0.1*w; p2.x = x; break; } AddPntQ(kq+i, &M, p1,c[i]); AddPntQ(kq+i+n, &M, p2,c[i]); } for(long i=0;iv(i); ac.AddLabel(mgl_ftoa(d,ac.stl.c_str()),d); } else { wchar_t buf[64]; for(long i=0;iv(i); mglprintf(buf,64,ac.t.c_str(),d); ac.AddLabel(buf,d); } } } else { UpdateAxis(); AdjustTicks(ac,fa!=0); } // hint for using standard label drawing function SetPenPal(TickStl); for(size_t i=0;iCalc(0,0,0,ac.txt[i].val):ac.txt[i].val; ac.txt[i].val = d = 2*(d-FMin.c)/(FMax.c-FMin.c)-1; if(fabs(d)>1) continue; // this is factor // mreal d = ac.txt[i].val = GetA(ac.txt[i].val)*2-1; p1 = p2 = mglPoint((ss*d+1)*w+x, (ss*d+1)*h+y, s3); switch(where) { case 1: p1.x = x; p2.x = x+0.1*w; break; case 2: p1.y = y-0.1*h; p2.y = y; break; case 3: p1.y = y; p2.y = y+0.1*h; break; default:p1.x = x-0.1*w; p2.x = x; break; } mglPoint p3(0.75*p1.x+0.25*p2.x, 0.75*p1.y+0.25*p2.y, s3); mglPoint p4(0.25*p1.x+0.75*p2.x, 0.25*p1.y+0.75*p2.y, s3); // line_plot(AddPnt(&M, p1), AddPnt(&M, p2)); line_plot(AddPnt(&M, p1), AddPnt(&M, p3)); line_plot(AddPnt(&M, p4), AddPnt(&M, p2)); } ac.dir.Set(ss*w,ss*h,0); ac.a.Set(0,0,0); ac.org.Set(w+x,h+y,s3+1); ac.b.Set(0,0,0); switch(where) { case 1: ac.dir.x = 0; ac.a.x= 1; ac.org.x = x+0.1*w-(get(MGL_ENABLE_RTEXT)?0:0.06); break; case 2: ac.dir.y = 0; ac.a.y=-1; ac.org.y = y-0.1*h; break; case 3: ac.dir.y = 0; ac.a.y= 1; ac.org.y = y+0.1*h; break; default:ac.dir.x = 0; ac.a.x=-1; ac.org.x = x-0.1*w; break; } SetPenPal(AxisStl); bool inv = where!=3 && where!=0; ac.ns = where; ac.angl=NAN; // NOTE ns isn't used for colorbar if(text) DrawLabels(ac,inv,&M); clr(MGL_DISABLE_SCALE); EndGroup(); } //----------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/canvas.cpp�������������������������������������������������������������������������0000644�0001750�0001750�00000131350�13513030041�015716� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * canvas.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/font.h" #include "mgl2/canvas.h" //----------------------------------------------------------------------------- MGL_EXPORT std::string mglGlobalMess; ///< Buffer for receiving global messages //----------------------------------------------------------------------------- mglCanvas::mglCanvas(int w, int h) : mglBase() { clr(MGL_DISABLE_SCALE); set(MGL_VECT_FRAME); // NOTE: require a lot of memory! Z=0; C=G=G4=GB=0; OI=0; gif=0; CurFrameId=0; Delay=0.5; Width=Height=Depth=0; ObjId=-1; fscl=ftet=0; PlotId = _("frame"); pnt_col = 0; ac.ch='c'; ax.dir.Set(1,0,0); ax.a.Set(0,1,0); ax.b.Set(0,0,1); ax.ch='x'; ay.dir.Set(0,1,0); ay.a.Set(1,0,0); ay.b.Set(0,0,1); ay.ch='y'; az.dir.Set(0,0,1); az.a.Set(0,1,0); az.b.Set(1,0,0); az.ch='z'; SetSize(w,h); SetQuality(MGL_DRAW_NORM); DefaultPlotParam(); } //----------------------------------------------------------------------------- mglCanvas::~mglCanvas() { if(G) { delete []G; delete []C; delete []Z; delete []G4;delete []GB;delete []OI; } if(pnt_col) delete []pnt_col; } //----------------------------------------------------------------------------- long mglCanvas::PushDrwDat() { mglDrawDat d; d.Pnt=Pnt; d.Prm=Prm; d.Sub=Sub; d.Glf=Glf; d.Ptx=Ptx; d.Txt=Txt; #pragma omp critical(drw) MGL_PUSH(DrwDat,d,mutexDrw); return DrwDat.size(); } //----------------------------------------------------------------------------- void mglCanvas::ResetFrames() { CurFrameId=0; DrwDat.clear(); } //----------------------------------------------------------------------------- void mglCanvas::SetFrame(long i) { if(get(MGL_VECT_FRAME) && i>=0 && i=DrwDat.size()) return; ClearFrame(); const mglDrawDat &d=DrwDat[k]; #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexPnt); pthread_mutex_lock(&mutexPrm); pthread_mutex_lock(&mutexSub); pthread_mutex_lock(&mutexGlf); pthread_mutex_lock(&mutexPtx); pthread_mutex_lock(&mutexTxt); #endif #pragma omp critical { Pnt=d.Pnt; Prm=d.Prm; Sub=d.Sub; Glf=d.Glf; Ptx=d.Ptx; Txt=d.Txt; ClearPrmInd(); } #if MGL_HAVE_PTHREAD pthread_mutex_unlock(&mutexTxt); pthread_mutex_unlock(&mutexPtx); pthread_mutex_unlock(&mutexGlf); pthread_mutex_unlock(&mutexSub); pthread_mutex_unlock(&mutexPrm); pthread_mutex_unlock(&mutexPnt); #endif } //----------------------------------------------------------------------------- void mglCanvas::ClearFrame() { #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexPnt); pthread_mutex_lock(&mutexPrm); pthread_mutex_lock(&mutexGlf); pthread_mutex_lock(&mutexPtx); pthread_mutex_lock(&mutexTxt); pthread_mutex_lock(&mutexSub); pthread_mutex_lock(&mutexLeg); pthread_mutex_lock(&mutexGrp); pthread_mutex_lock(&mutexAct); #endif #pragma omp critical { StartAutoGroup(NULL); Leg.clear(); Grp.clear(); Act.clear(); Glf.clear(); Pnt.clear(); Prm.clear(); Ptx.clear(); ClearPrmInd(); Txt.clear(); Txt.reserve(3); // mglBlock inpl = Sub[0]; Sub.clear(); Sub.push_back(inpl); // NOTE at least one inplot should present!!! mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1); Txt.push_back(t1); Txt.push_back(t2); // No extra lock is required } #if MGL_HAVE_PTHREAD pthread_mutex_unlock(&mutexAct); pthread_mutex_unlock(&mutexGrp); pthread_mutex_unlock(&mutexLeg); pthread_mutex_unlock(&mutexSub); pthread_mutex_unlock(&mutexTxt); pthread_mutex_unlock(&mutexPtx); pthread_mutex_unlock(&mutexGlf); pthread_mutex_unlock(&mutexPrm); pthread_mutex_unlock(&mutexPnt); #endif ClfZB(true); } //----------------------------------------------------------------------------- void mglCanvas::ShowFrame(long k) { if(k<0 || (size_t)k>=DrwDat.size()) return; ClfZB(); size_t npnt=Pnt.size(), nglf=Glf.size(), nptx=Ptx.size(), ntxt=Txt.size(), nsub=Sub.size(); #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexPnt); pthread_mutex_lock(&mutexPrm); pthread_mutex_lock(&mutexSub); pthread_mutex_lock(&mutexGlf); pthread_mutex_lock(&mutexPtx); pthread_mutex_lock(&mutexTxt); #endif #pragma omp critical { const mglDrawDat &d=DrwDat[k]; Glf.resize(d.Glf.size()); for(size_t i=0;i=0) p.sub += nsub; else p.sub -= nsub; Pnt.push_back(p); } Prm.reserve(d.Prm.size()); for(size_t i=0;i=0) { a.z = Pnt[a.n1].z; // this is a bit less accurate but simpler for transformation a.id = ObjId; #pragma omp critical(prm) MGL_PUSH(Prm,a,mutexPrm); ClearPrmInd(); clr(MGL_FINISHED); } } //----------------------------------------------------------------------------- extern uint64_t mgl_mask_def[16]; void mglCanvas::DefaultPlotParam() { /* NOTE: following variables and mutex will not be changed by DefaultPlotParam() long InUse; ///< Smart pointer (number of users) mglFont *fnt; ///< Class for printing vector text int Quality; ///< Quality of plot (0x0-pure, 0x1-fast; 0x2-fine; 0x4 - low memory) int Width; ///< Width of the image int Height; ///< Height of the image int Depth; ///< Depth of the image int CurFrameId; ///< Number of automaticle created frames GifFileType *gif;*/ SetDrawReg(1,1,0); Perspective(0); SetPenDelta(1); SetBBox(); memcpy(mgl_mask_val, mgl_mask_def, 16*sizeof(uint64_t)); // should be > 16*8 ax.Clear(); ay.Clear(); az.Clear(); ac.Clear(); mgl_clear_fft(); DefMaskAn=0; ResetMask(); SetTickRotate(true); SetTickSkip(true); SetWarn(mglWarnNone,""); mglGlobalMess = ""; ObjId = -1; HighId = INT_MIN; SetFunc(0,0); CutOff(0); Ternary(0); Stop=false; event_cb = NULL; event_par=NULL; SetRanges(mglPoint(-1,-1,-1,-1), mglPoint(1,1,1,1)); SetOrigin(NAN,NAN,NAN,NAN); SetBarWidth(0.7); SetMarkSize(1); SetArrowSize(1); SetAlphaDef(0.5); FontDef[0]=0; SetTranspType(0); SetMeshNum(0); // NOTE: default MeshNum=0 SetRotatedText(true); CurrPal = 0; SetLegendMarks(); SetFontSize(4); SetTuneTicks(3); SetAmbient(); SetDiffuse(); clr(MGL_DISABLE_SCALE); clr(MGL_USE_GMTIME); clr(MGL_NOSUBTICKS); SetDifLight(false); SetReduceAcc(false); SetDefScheme(MGL_DEF_SCH); SetPalette(MGL_DEF_PAL); SetPenPal("k-1"); Alpha(false); stack.clear(); Restore(); DefColor('k'); SetPlotFactor(0); Sub.clear(); InPlot(0,1,0,1,false); clr(MGL_FULL_CURV); SetTickLen(0); SetCut(true); AdjustTicks("xyzc",true); Clf('w'); for(int i=0;i<10;i++) { AddLight(i, mglPoint(0,0,1)); Light(i,false); } Light(0,true); Light(false); SetDifLight(true); } //----------------------------------------------------------------------------- // Optimal axis position //----------------------------------------------------------------------------- mreal mglCanvas::FindOptOrg(char dir, int ind) const { static mglPoint px, py, pz; static mglMatrix bb; mglPoint nn[8]={mglPoint(0,0,0), mglPoint(0,0,1), mglPoint(0,1,0,0), mglPoint(0,1,1), mglPoint(1,0,0), mglPoint(1,0,1), mglPoint(1,1,0), mglPoint(1,1,1)}, pp[8]; memcpy(pp, nn, 8*sizeof(mglPoint)); // do nothing if transformation matrix is the same if(B!=bb) { bb = B; for(long i=0;i<8;i++) PostScale(&B,pp[i]); // find point with minimal y long j=0; for(long i=1;i<8;i++) if(pp[i].ypp[2].x) pz.y=1-pz.y; else pz.x=1-pz.x; } else if(tx==0 && ty==0) // x- && y-axis is vertical { py.x=1-py.x; if(pp[1].x>pp[3].x) { px.z=1-px.z; py.z=1-py.z; } } else if(tzpp[2].x) pz.y=1-pz.y; else pz.x=1-pz.x; } else if(typp[3].x) py.z=1-py.z; else py.x=1-py.x; } else if(txpp[2].x) px.y=1-px.y; else px.z=1-px.z; } } // return to normal variables mglPoint rx = Min+(Max-Min)/px; mglPoint ry = Min+(Max-Min)/py; mglPoint rz = Min+(Max-Min)/pz; mreal res = rx.val(ind); if(dir=='y') res = ry.val(ind); if(dir=='z') res = rz.val(ind); return res; } //----------------------------------------------------------------------------- mreal mglCanvas::GetOrgX(char dir, bool inv) const { mreal res = Org.x; if(mgl_isnan(res)) { if(strchr("xyz",dir)) res = FindOptOrg(dir,0); else if(dir=='t') res = Min.x; else res = B.b[6]>0 ? Max.x:Min.x; if(inv) res = Min.x+Max.x-res; } return res; } //----------------------------------------------------------------------------- mreal mglCanvas::GetOrgY(char dir, bool inv) const { mreal res = Org.y; if(mgl_isnan(res)) { if(strchr("xyz",dir)) res = FindOptOrg(dir,1); else if(dir=='t') res = Min.y; else res = B.b[7]>0 ? Max.y:Min.y; if(inv) res = Min.y+Max.y-res; } return res; } //----------------------------------------------------------------------------- mreal mglCanvas::GetOrgZ(char dir, bool inv) const { mreal res = Org.z; if(mgl_isnan(res)) { if(strchr("xyz",dir)) res = FindOptOrg(dir,2); else if(dir=='t') res = Min.z; else res = B.b[8]>0 ? Max.z:Min.z; if(inv) res = Min.z+Max.z-res; } return res; } //----------------------------------------------------------------------------- // Put primitives //----------------------------------------------------------------------------- #define MGL_MARK_PLOT if(Quality&MGL_DRAW_LMEM) \ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \ d.PDef = PDef; d.pPos = pPos; mark_draw(Pnt[p],type,size,&d); }\ else{ mglPrim a; a.w = pw; a.s = size; \ a.n1 = p; a.n4 = type; a.angl=0; add_prim(a); } void mglCanvas::mark_plot(long p, char type, mreal size) { if(p<0 || mgl_isnan(Pnt[p].x) || mgl_isnan(size)) return; if(type>128 || type<0) { smbl_plot(p,type-128,20*MarkSize*(size?fabs(size):1)); return; } long pp=p; mreal pw = 0.15/sqrt(font_factor); size = size?fabs(size):1; size *= MarkSize*0.35*font_factor; if(type=='.') size = fabs(PenWidth)*sqrt(font_factor/400); if(TernAxis&12) for(int i=0;i<4;i++) { p = ProjScale(i, pp); if(p>=0) {MGL_MARK_PLOT} } else { MGL_MARK_PLOT } } //----------------------------------------------------------------------------- #define MGL_LINE_PLOT if(Quality&MGL_DRAW_LMEM) \ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \ d.PDef = PDef; d.pPos = pPos; line_draw(Pnt[p1],Pnt[p2],&d); }\ else { mglPrim a(1); a.n3=PDef; a.s = pPos; \ a.n1 = p1; a.n2 = p2; a.w = pw; a.angl=0; add_prim(a); } void mglCanvas::line_plot(long p1, long p2) { if(PDef==0) return; if(SamePnt(p1,p2)) return; if(p1>p2) { long kk=p1; p1=p2; p2=kk; } // rearrange start/end for proper dashing long pp1=p1,pp2=p2; mreal pw = fabs(PenWidth)*sqrt(font_factor/400), d=0; if(TernAxis&12) for(int i=0;i<4;i++) { p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2); if(p1>=0&&p2>=0) { d += hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y); MGL_LINE_PLOT pPos = fmod(pPos+d/pw, 16); } } else { d = hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y); MGL_LINE_PLOT pPos = fmod(pPos+d/pw, 16); } } //----------------------------------------------------------------------------- #define MGL_TRIG_PLOT if(Quality&MGL_DRAW_LMEM) \ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \ trig_draw(Pnt[p1],Pnt[p2],Pnt[p3],true,&d); }\ else{ mglPrim a(2); a.n1 = p1; a.n2 = p2; a.n3 = p3; \ a.m=mask; a.angl=MaskAn; a.w = pw; add_prim(a);} void mglCanvas::trig_plot(long p1, long p2, long p3) { if(SamePnt(p1,p2) || SamePnt(p1,p3)) return; long pp1=p1,pp2=p2,pp3=p3; mreal pw = fabs(PenWidth)*sqrt(font_factor/400); if(TernAxis&12) for(int i=0;i<4;i++) { p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2); p3 = ProjScale(i, pp3); if(p1>=0&&p2>=0&&p3>=0) {MGL_TRIG_PLOT} } else { MGL_TRIG_PLOT } } //----------------------------------------------------------------------------- #define MGL_QUAD_PLOT if(Quality&MGL_DRAW_LMEM) \ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \ quad_draw(Pnt[p1],Pnt[p2],Pnt[p3],Pnt[p4],&d); }\ else{ mglPrim a(3); a.n1 = p1; a.n2 = p2; a.n3 = p3; a.n4 = p4; \ a.m=mask; a.angl=MaskAn; a.w = pw; add_prim(a); } void mglCanvas::quad_plot(long p1, long p2, long p3, long p4) { if(SamePnt(p1,p2)) { trig_plot(p4,p2,p3); return; } if(SamePnt(p2,p4)) { trig_plot(p1,p4,p3); return; } if(SamePnt(p1,p3)) { trig_plot(p1,p2,p4); return; } if(SamePnt(p3,p4)) { trig_plot(p1,p2,p3); return; } long pp1=p1,pp2=p2,pp3=p3,pp4=p4; mreal pw = fabs(PenWidth)*sqrt(font_factor/400); if(TernAxis&12) for(int i=0;i<4;i++) { p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2); p3 = ProjScale(i, pp3); p4 = ProjScale(i, pp4); if(p1>=0&&p2>=0&&p3>=0&&p4>=0) {MGL_QUAD_PLOT} } else { MGL_QUAD_PLOT } } //----------------------------------------------------------------------------- mreal mglCanvas::text_plot(long p,const wchar_t *text,const char *font,mreal size,mreal sh,mreal col,bool rot) { if(p<0 || mgl_isnan(Pnt[p].x) || !text || *text==0) return 0; if(size<0) size *= -FontSize; if(!font) font=""; if(TernAxis&4) // text at projections { mreal res; TernAxis = TernAxis&(~4); for(int i=0;i<4;i++) res = text_plot(ProjScale(i,p,true),text,font,size/2,sh,col,rot); TernAxis = TernAxis|4; return res; } else if(TernAxis&8) // text at projections { mreal res; TernAxis = TernAxis&(~8); // for(int i=0;i<4;i++) res = text_plot(ProjScale(3,p,true),text,font,size/2,sh,col,rot); TernAxis = TernAxis|8; return res; } mglPnt q=Pnt[p]; mreal ll = q.u*q.u+q.v*q.v; bool inv=false; // if(rot && (q.u<0 || (q.u==0 && q.v<0))) // NOTE this is 1st part of rotation changes (see also GetGlyphPhi()) // { q.u=-q.u; q.v=-q.v; q.w=-q.w; inv=true; } mreal fsize=size/6.5*font_factor, h = fnt->Height(font)*fsize, w, shift = -(sh+0.02)*h; // text drawing itself #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexPtx); #endif #pragma omp critical(ptx) { Bt = B; Bt.norot=(q.sub<0); // NOTE check this later for mglInPlot inv = inv ^ (strchr(font,'T')!=0); if(strchr(font,'V')) shift = 0.1*h; else { if(inv) shift = 0.2*h-shift; shift += 0.015*h; // Correction for glyph rotation around proper point } int align; float col1=col, col2=col; if(mglGetStyle(font,0,&align)) { col1 = AddTexture(font); col2 = col1+1/MGL_FEPSILON; } else if(col<0) col1 = col2 = AddTexture(char(0.5-col)); align = align&3; Bt.x = q.x; Bt.y = q.y - shift; Bt.z = q.z; if(ll>0) { Bt.x += shift*q.v/sqrt(ll); Bt.y += shift*(1-q.u/sqrt(ll)); if(q.u==0 && !get(MGL_ENABLE_RTEXT)) Bt.y -= 0.1*h; } fscl = fsize; forg = p; if(mgl_isnan(ll) || !get(MGL_ENABLE_RTEXT)) ftet = 0; else if(ll) ftet = -180*atan2(q.v,q.u)/M_PI; else ftet = NAN; if(!(Quality&MGL_DRAW_LMEM)) // add text itself { mglColor mc = Txt[long(col1)].GetC(col1); mglPrim a(6); a.n1 = p; a.n2 = int(255*mc.r) + 256*(int(255*mc.g) + 256*int(255*mc.b)); a.n3 = Ptx.size(); Ptx.push_back(mglText(text,font)); a.s = size; a.w = shift; a.p=ftet; add_prim(a); } q.c=col1; q.ta=0; Txt[long(col1)].GetC(col1,0,q); q.u = q.v = NAN; q.a=q.ta=1; memset(Bt.b,0,9*sizeof(float)); Bt.b[0] = Bt.b[4] = Bt.b[8] = fscl; float opf = Bt.pf; Bt.RotateN(ftet,0,0,1); Bt.pf = Bt.norot?1.55:opf; if(strchr(font,'@')) // draw box around text { long k1,k2,k3,k4; mglPnt pt; mglPoint pp; float y1, y2; w = fnt->Width(text,font, &y1,&y2); h = fnt->Height(font); float d=-w*align/2.-h*0.2; w+=h*0.4; pt = q; pp.Set(d,y1-h*0.2); PostScale(&Bt,pp); pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y; #pragma omp critical(pnt) {k1=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);} pt = q; pp.Set(w+d,y1-h*0.2); PostScale(&Bt,pp); pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y; #pragma omp critical(pnt) {k2=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);} pt = q; pp.Set(d,y2+h*0.2); PostScale(&Bt,pp); pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y; #pragma omp critical(pnt) {k3=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);} pt = q; pp.Set(w+d,y2+h*0.2); PostScale(&Bt,pp); pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y; #pragma omp critical(pnt) {k4=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);} PDef = 0xffff; // reset to solid line line_plot(k1,k2); line_plot(k1,k3); line_plot(k4,k2); line_plot(k4,k3); mreal bl = AddTexture('w'); k1 = CopyNtoC(k1,bl); k2 = CopyNtoC(k2,bl); k3 = CopyNtoC(k3,bl); k4 = CopyNtoC(k4,bl); quad_plot(k1,k2,k3,k4); } const char *ffont = font; while(*ffont && *ffont!=':') ffont++; fsize *= fnt->Puts(text,ffont,col1,col2)/2; } #if MGL_HAVE_PTHREAD pthread_mutex_unlock(&mutexPtx); #endif return fsize; } //----------------------------------------------------------------------------- void mglCanvas::Glyph(mreal x, mreal y, mreal f, int s, long j, mreal col) { mglPrim a(4); // NOTE: no projection since text_plot() did it a.s = fscl/Bt.pf; a.w = get(MGL_ENABLE_RTEXT)?ftet:1e5; a.p = f/fnt->GetFact(s&3); mreal cc = col<0 ? AddTexture(char(0.5-col)):col; if(cc<0) cc = CDef; a.n1 = AddPnt(&Bt, mglPoint(Bt.x,Bt.y,Bt.z), cc, mglPoint(x,y,NAN), -1, -1); a.n2 = forg; a.n3 = s; a.n4 = AddGlyph(s,j); if(a.n1<0) return; if(Quality&MGL_DRAW_LMEM) { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PDef = s; d.pPos = a.s; d.PenWidth=a.w; glyph_draw(a,&d); } else add_prim(a); } //----------------------------------------------------------------------------- #define MGL_GLYPH_PLOT if(Quality&MGL_DRAW_LMEM) glyph_draw(a,&d);\ else add_prim(a); void mglCanvas::smbl_plot(long p1, char id, double size) { if(p1<0 || mgl_isnan(Pnt[p1].x)) return; mglPnt q=Pnt[p1]; mreal ftet=NAN, ll = q.u*q.u+q.v*q.v; if(mgl_isnan(ll) || !get(MGL_ENABLE_RTEXT)) ftet = 0; else if(ll) ftet = -180*atan2(q.v,q.u)/M_PI; long pk; q.u=q.v=0; q.w=NAN; #pragma omp critical(pnt) {pk=Pnt.size(); MGL_PUSH(Pnt,q,mutexPnt);} mglPrim a(4); a.s = fabs(size)/6.5*font_factor/B.pf; a.w = get(MGL_ENABLE_RTEXT)?ftet:1e5; a.p = 1./(mgl_fact*mgl_fgen); a.n1 = pk; a.n2 = p1; a.n3 = size<0?4:0; a.n4 = AddGlyph(id); if(a.n4<0) return; // no symbol is defined by user mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PDef = size<0?4:0; d.pPos = a.s; d.PenWidth=a.w; if(TernAxis&12) for(int i=0;i<4;i++) { a.n1 = ProjScale(i, pk); MGL_GLYPH_PLOT } else { MGL_GLYPH_PLOT } } //----------------------------------------------------------------------------- // Plot positioning functions //----------------------------------------------------------------------------- void mglCanvas::InPlot(mreal x1,mreal x2,mreal y1,mreal y2, const char *st) { if(Width<=0 || Height<=0 || Depth<=0) return; if(!st) { InPlot(x1,x2,y1,y2,false); return; } inW = Width*(x2-x1); inH = Height*(y2-y1); inX=Width*x1; inY=Height*y1; ZMin=1; if(strchr(st,'T')) { y1*=0.9; y2*=0.9; } // general title bool r = !(strchr(st,'r') || strchr(st,'R') || strchr(st,'>') || strchr(st,'g')); bool l = !(strchr(st,'l') || strchr(st,'L') || strchr(st,'<') || strchr(st,'g')); bool u = !(strchr(st,'u') || strchr(st,'U') || strchr(st,'_') || strchr(st,'g')); bool a = !(strchr(st,'a') || strchr(st,'A') || strchr(st,'^') || strchr(st,'g') || strchr(st,'t')); // let use simplified scheme -- i.e. no differences between axis, colorbar and/or title mreal xs=(x1+x2)/2, ys=(y1+y2)/2, f1 = 1.3, f2 = 1.1; if(strchr(st,'#')) f1=f2=1.55; if(r && l) { x2=xs+(x2-xs)*f1; x1=xs+(x1-xs)*f1; } else if(r) { x2=xs+(x2-xs)*f1; x1=xs+(x1-xs)*f2; } else if(l) { x2=xs+(x2-xs)*f2; x1=xs+(x1-xs)*f1; } if(a && u) { y2=ys+(y2-ys)*f1; y1=ys+(y1-ys)*f1; } else if(a) { y2=ys+(y2-ys)*f1; y1=ys+(y1-ys)*f2; } else if(u) { y2=ys+(y2-ys)*f2; y1=ys+(y1-ys)*f1; } B.clear(); if(get(MGL_AUTO_FACTOR)) B.pf = 1.55; // Automatically change plot factor !!! B.x = (x1+x2)/2*Width; B.y = (y1+y2)/2*Height; B.b[0] = Width*(x2-x1); B.b[4] = Height*(y2-y1); B.b[8] = sqrt(B.b[0]*B.b[4]); B.z = (1.f-B.b[8]/(2*Depth))*Depth; B1=B; font_factor = B.b[0] < B.b[4] ? B.b[0] : B.b[4]; mglBlock p; p.AmbBr = AmbBr; p.DifBr = DifBr; p.B = B; for(int i=0;i<10;i++) p.light[i] = light[i]; p.id = ObjId; p.n1=x1*Width; p.n2=x2*Width; p.n3=y1*Height; p.n4=y2*Height; #pragma omp critical(sub) MGL_PUSH(Sub,p,mutexSub); } //----------------------------------------------------------------------------- void mglCanvas::InPlot(mglMatrix &M,mreal x1,mreal x2,mreal y1,mreal y2, bool rel) { if(Width<=0 || Height<=0 || Depth<=0) return; M.clear(); if(get(MGL_AUTO_FACTOR)) M.pf = 1.55; // Automatically change plot factor !!! if(rel) { M.x = B1.x + (x1+x2-1)/2*B1.b[0]/1.55; M.y = B1.y + (y1+y2-1)/2*B1.b[4]/1.55; M.b[0] = B1.b[0]*(x2-x1); M.b[4] = B1.b[4]*(y2-y1); M.b[8] = sqrt(M.b[0]*M.b[4]); M.z = B1.z + (1.f-M.b[8]/(2*Depth))*B1.b[8]; } else { M.x = (x1+x2)/2*Width; M.y = (y1+y2)/2*Height; M.b[0] = Width*(x2-x1); M.b[4] = Height*(y2-y1); M.b[8] = sqrt(M.b[0]*M.b[4]); M.z = (1.f-M.b[8]/(2*Depth))*Depth; B1=M; } inW=M.b[0]; inH=M.b[4]; ZMin=1; inX=Width*x1; inY=Height*y1; if(!rel || !get(MGL_NO_SCALE_REL)) font_factor = M.b[0] < M.b[4] ? M.b[0] : M.b[4]; mglBlock p; p.AmbBr = AmbBr; p.DifBr = DifBr; p.B = M; for(int i=0;i<10;i++) p.light[i] = light[i]; p.id = ObjId; p.n1=x1*Width; p.n2=x2*Width; p.n3=y1*Height; p.n4=y2*Height; #pragma omp critical(sub) MGL_PUSH(Sub,p,mutexSub); } //----------------------------------------------------------------------------- void mglCanvas::StickPlot(int num, int id, mreal tet, mreal phi) { mreal dx,dy,wx,wy,x1,y1,f1,f2; mglPoint p1(-1,0,0), p2(1,0,0); // first iteration InPlot(0,1,0,1,true); Rotate(tet, phi); PostScale(GetB(),p1); PostScale(GetB(),p2); f1 = B.pf; dx=(p2.x-p1.x)*1.55/B1.b[0]; dy=(p2.y-p1.y)*1.55/B1.b[4]; wx=1/(1+(num-1)*fabs(dx)); wy=1/(1+(num-1)*fabs(dy)); x1=dx>0?dx*id:dx*(id-num+1); y1=dy>0?dy*id:dy*(id-num+1); InPlot(x1*wx,(x1+1)*wx,y1*wy,(y1+1)*wy,true); Rotate(tet,phi); f2 = B.pf; dx*=f1/f2; dy*=f1/f2; // add correction due to PlotFactor wx=1/(1+(num-1)*fabs(dx)); wy=1/(1+(num-1)*fabs(dy)); x1=dx>0?dx*id:dx*(id-num+1); y1=dy>0?dy*id:dy*(id-num+1); InPlot(x1*wx,(x1+1)*wx,y1*wy,(y1+1)*wy,true); Rotate(tet,phi); f1=f2; f2 = B.pf; dx*=f1/f2; dy*=f1/f2; // add correction due to PlotFactor wx=1/(1+(num-1)*fabs(dx)); wy=1/(1+(num-1)*fabs(dy)); x1=dx>0?dx*id:dx*(id-num+1); y1=dy>0?dy*id:dy*(id-num+1); InPlot(x1*wx,(x1+1)*wx,y1*wy,(y1+1)*wy,true); Rotate(tet,phi); } //----------------------------------------------------------------------------- void mglCanvas::Rotate(mreal tetz,mreal tetx,mreal tety) { B.Rotate(tetz,tetx,tety); if(get(MGL_AUTO_FACTOR)) { float w=(fabs(B.b[3])+fabs(B.b[4])+fabs(B.b[5]))/B1.b[4]; float h=(fabs(B.b[0])+fabs(B.b[1])+fabs(B.b[2]))/B1.b[0]; B.pf = 1.55+0.6147*(w0) Sub[n-1].B = B; } //----------------------------------------------------------------------------- void mglMatrix::Rotate(mreal tetz,mreal tetx,mreal tety) { // RotateN(TetX,1.,0.,0.); // RotateN(TetY,0.,1.,0.); // RotateN(TetZ,0.,0.,1.); float R[9], O[9]; float cx=cos(tetx*M_PI/180), sx=-sin(tetx*M_PI/180), cy=cos(tety*M_PI/180), sy=-sin(tety*M_PI/180), cz=cos(tetz*M_PI/180), sz=-sin(tetz*M_PI/180); R[0] = cx*cy; R[1] = -cy*sx; R[2] = sy; R[3] = cx*sy*sz+cz*sx; R[4] = cx*cz-sx*sy*sz; R[5] =-cy*sz; R[6] = sx*sz-cx*cz*sy; R[7] = cx*sz+cz*sx*sy; R[8] = cy*cz; memcpy(O,b,9*sizeof(float)); b[0] = R[0]*O[0] + R[3]*O[1] + R[6]*O[2]; b[1] = R[1]*O[0] + R[4]*O[1] + R[7]*O[2]; b[2] = R[2]*O[0] + R[5]*O[1] + R[8]*O[2]; b[3] = R[0]*O[3] + R[3]*O[4] + R[6]*O[5]; b[4] = R[1]*O[3] + R[4]*O[4] + R[7]*O[5]; b[5] = R[2]*O[3] + R[5]*O[4] + R[8]*O[5]; b[6] = R[0]*O[6] + R[3]*O[7] + R[6]*O[8]; b[7] = R[1]*O[6] + R[4]*O[7] + R[7]*O[8]; b[8] = R[2]*O[6] + R[5]*O[7] + R[8]*O[8]; } //----------------------------------------------------------------------------- void mglCanvas::RotateN(mreal Tet,mreal x,mreal y,mreal z) { B.RotateN(Tet,x,y,z); if(get(MGL_AUTO_FACTOR)) { float w=(fabs(B.b[3])+fabs(B.b[4])+fabs(B.b[5]))/B1.b[4]; float h=(fabs(B.b[0])+fabs(B.b[1])+fabs(B.b[2]))/B1.b[0]; B.pf = 1.55+0.6147*(w0) Sub[n-1].B = B; } //----------------------------------------------------------------------------- void mglMatrix::RotateN(mreal Tet,mreal vx,mreal vy,mreal vz) { float R[9],T[9],c=cos(Tet*M_PI/180),s=-sin(Tet*M_PI/180),r=1-c,n=sqrt(vx*vx+vy*vy+vz*vz); vx/=n; vy/=n; vz/=n; T[0] = vx*vx*r+c; T[1] = vx*vy*r-vz*s; T[2] = vx*vz*r+vy*s; T[3] = vx*vy*r+vz*s; T[4] = vy*vy*r+c; T[5] = vy*vz*r-vx*s; T[6] = vx*vz*r-vy*s; T[7] = vy*vz*r+vx*s; T[8] = vz*vz*r+c; memcpy(R,b,9*sizeof(float)); b[0] = T[0]*R[0] + T[3]*R[1] + T[6]*R[2]; b[1] = T[1]*R[0] + T[4]*R[1] + T[7]*R[2]; b[2] = T[2]*R[0] + T[5]*R[1] + T[8]*R[2]; b[3] = T[0]*R[3] + T[3]*R[4] + T[6]*R[5]; b[4] = T[1]*R[3] + T[4]*R[4] + T[7]*R[5]; b[5] = T[2]*R[3] + T[5]*R[4] + T[8]*R[5]; b[6] = T[0]*R[6] + T[3]*R[7] + T[6]*R[8]; b[7] = T[1]*R[6] + T[4]*R[7] + T[7]*R[8]; b[8] = T[2]*R[6] + T[5]*R[7] + T[8]*R[8]; } //----------------------------------------------------------------------------- void mglCanvas::View(mreal tetx,mreal tetz,mreal tety) { Bp.Rotate(-tetz,-tetx,-tety); } //----------------------------------------------------------------------------- void mglCanvas::Zoom(mreal x1, mreal y1, mreal x2, mreal y2) { Bp.pf=0; Bp.clear(); ClfZB(); if(x1==x2 || y1==y2) { x1=y1=0; x2=y2=1; } x1=2*x1-1; x2=2*x2-1; y1=2*y1-1; y2=2*y2-1; Bp.b[0]=2/fabs(x2-x1); Bp.b[4]=2/fabs(y2-y1); Bp.x=(x1+x2)/fabs(x2-x1);Bp.y=(y1+y2)/fabs(y2-y1); } //----------------------------------------------------------------------------- int mglCanvas::GetSplId(long x,long y) const { long id=-1; for(long i=Sub.size()-1;i>=0;i--) { const mglBlock &p = Sub[i]; if(p.n1<=x && p.n2>=x && p.n3<=y && p.n4>=y) { id=p.id; break; } } return id; } //----------------------------------------------------------------------------- void mglCanvas::Aspect(mreal Ax,mreal Ay,mreal Az) { if(mgl_isnan(Ax)) { mreal dy = (Max.y-Min.y), dx = (Max.x-Min.x), dz = (Max.z-Min.z); if(mgl_islog(Min.x,Max.x) && fx) dx = log10(Max.x/Min.x); if(mgl_islog(Min.y,Max.y) && fy) dy = log10(Max.y/Min.y); if(mgl_islog(Min.z,Max.z) && fz) dz = log10(Max.z/Min.z); mreal gy=exp(M_LN10*floor(0.5+log10(fabs(dy/dx)))); mreal gz=exp(M_LN10*floor(0.5+log10(fabs(dz/dx)))); if(Ay>0) gy*=Ay; if(Az>0) gz*=Az; Ax = inH*dx; Ay = inW*dy*gy; Az = sqrt(inW*inH)*dz*gz; } mreal a = fabs(Ax) > fabs(Ay) ? fabs(Ax) : fabs(Ay); a = a > fabs(Az) ? a : fabs(Az); if(a==0) { SetWarn(mglWarnZero,"Aspect"); return; } Ax/=a; Ay/=a; Az/=a; B.b[0] *= Ax; B.b[3] *= Ax; B.b[6] *= Ax; B.b[1] *= Ay; B.b[4] *= Ay; B.b[7] *= Ay; B.b[2] *= Az; B.b[5] *= Az; B.b[8] *= Az; size_t n = Sub.size(); if(n>0) Sub[n-1].B = B; } //----------------------------------------------------------------------------- void mglCanvas::Shear(mreal Sx,mreal Sy) { float Fx=1+fabs(Sx)*inH/inW, Fy=1+fabs(Sy)*inW/inH; const float R[6]={B.b[0],B.b[1],B.b[2],B.b[3],B.b[4],B.b[5]}; B.b[0] = (R[0]+Sx*R[3])/Fx; B.b[1] = (R[1]+Sx*R[4])/Fx; B.b[2] = (R[2]+Sx*R[5])/Fx; B.b[3] = (R[3]+Sy*R[0])/Fy; B.b[4] = (R[4]+Sy*R[1])/Fy; B.b[5] = (R[5]+Sy*R[2])/Fy; size_t n = Sub.size(); if(n>0) Sub[n-1].B = B; } //----------------------------------------------------------------------------- void mglCanvas::ShearPlot(int num, int id, mreal sx, mreal sy, mreal xd, mreal yd) { InPlot(0,1,0,1,true); if(!(fabs(xd)<=1 && fabs(yd)<=1)) { xd=1; yd=0; } mreal wx,wy,dx,dy,wf,hf,x1,y1; int ix=sy>=0?id:num-id-1, iy=sx>=0?id:num-id-1; for(int i=0;i<3;i++) // iterations to solve cubic equation { wx = fabs(sx)*inH/inW; dx = xd + yd*wx; wf = 1+wx+(num-1)*fabs(dx); wy = fabs(sy)*inW/inH; dy = yd + xd*wy; hf = 1+wy+(num-1)*fabs(dy); x1=(dx>=0?ix:(ix-num+1))*dx; y1=(dy>=0?iy:(iy-num+1))*dy; InPlot(x1/wf,(x1+1+wx)/wf,y1/hf,(y1+1+wy)/hf,true); } Shear(sx,sy); } //----------------------------------------------------------------------------- // Lighting and transparency //----------------------------------------------------------------------------- void mglCanvas::Fog(mreal d, mreal dz) { FogDist=d; FogDz = dz; } //----------------------------------------------------------------------------- void mglCanvas::Light(int n, bool enable) { if(n<0 || n>9) { SetWarn(mglWarnLId,"Light"); return; } light[n].n = enable; size_t m=Sub.size(); if(m>0) Sub[m-1].light[n].n = enable; } //----------------------------------------------------------------------------- void mglCanvas::AddLight(int n, mglPoint r, mglPoint d, char col, mreal br, mreal ap) { if(n<0 || n>9) { SetWarn(mglWarnLId,"AddLight"); return; } light[n].n = true; light[n].a = ap>0?ap*ap:3; light[n].b = br; light[n].r = r; light[n].d = d; light[n].c.Set(col); size_t m=Sub.size(); if(m>0) Sub[m-1].light[n] = light[n]; } //----------------------------------------------------------------------------- void mglCanvas::arrow_plot(long n1, long n2, char st) { if(n1<0 || n2<0 || !strchr("AVKSDTIOX",st)) return; float ll = PenWidth*ArrowSize*0.35*font_factor; uint64_t m=mask; int ma=MaskAn; ResetMask(); if((Quality&3)==3) arrow_plot_3d(n1, n2, st, ll); else arrow_draw(n1, n2, st, ll); mask=m; MaskAn=ma; } //----------------------------------------------------------------------------- std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt) { char se[70], sf[70], ff[8]="%.3f", ee[8]="%.3e"; int dig=3; for(const char *s="0123456789";*s;s++) if(mglchr(fmt,*s)) dig = *s-'0'; if(mglchr(fmt,'E')) ee[3] = 'E'; bool plus = mglchr(fmt,'+'); bool tex = mglchr(fmt,'F'); int fdig = int(log10(v)); fdig = fdig>0?(fdig=lf-fdig && sf[i]=='0';i--) sf[i]=0; if(sf[i]=='.') sf[i]=0; lf = strlen(sf); // parse -nan numbers if(!strcmp(sf,"-nan")) memcpy(sf,"nan",4); // clear exp format int st = se[0]=='-'?1:0; if(strcmp(sf,"nan")) { if(plus || se[3+st+dig]=='-') // first remove zeros after 'e' { for(i=(dig>0?4:3)+st+dig;i0?4:3)+st+dig,se+i,le-i+1); } else { for(i=(dig>0?3:2)+st+dig;i0?3:2)+st+dig,se+i,le-i+1); } } le=strlen(se); // don't allow '+' at the end if(le>0 && se[le-1]=='+') se[--le]=0; // remove single 'e' if(le>0 && (se[le-1]=='e' || se[le-1]=='E')) se[--le]=0; for(i=1+st+dig;i>st && se[i]=='0';i--); // remove final '0' if(se[i]=='.') i--; memmove(se+i+1,se+2+st+dig,le-dig); le=strlen(se); // add '+' sign if required if(plus && !strchr("-0niNI",se[0])) { for(size_t i=le+1;i>0;i--) se[i]=se[i-1]; for(size_t i=lf+1;i>0;i--) sf[i]=sf[i-1]; se[0] = sf[0] = '+'; } if((lf>le && !mglchr(fmt,'f')) || !strcmp(sf,"0") || !strcmp(sf,"-0")) strcpy(sf,se); lf = strlen(sf); std::wstring res; res.reserve(lf+8); if(mglchr(fmt,'-') && !(plus||tex)) // replace '-' by "\minus" for(i=0;i "\cdot 10^{...}" { if(res[0]=='1' && (res[1]=='e' || res[1]=='E')) { res.replace(0,2,L"10^{"); res += L'}'; } else if(wcschr(L"+-\u2212",res[0]) && res[1]=='1' && (res[2]=='e' || res[2]=='E')) { res.replace(1,2,L"10^{"); res += L'}'; } else { size_t p; for(p=1;p &leg, mreal x, mreal y, const char *font, const char *opt) { long n=leg.size(); mreal iw, ih; if(n<1) { SetWarn(mglWarnLeg,"Legend"); return; } mreal ll = SaveState(opt); if(mgl_isnan(ll)) ll=0.1; if(saved) MarkSize=MSS; // restore back size of marks static int cgid=1; StartGroup("Legend",cgid++); if(ll<=0 || mgl_isnan(ll)) ll=0.1; ll *=font_factor; mreal size = 0.8*FontSize; // setup font and parse absolute coordinates if(!font) font="#"; char *pA, *ff = new char[strlen(font)+3]; const char *fmt = strchr(font,':'); strcpy(ff,fmt?fmt:""); strcat(ff,":L"); Push(); if((pA=strchr(ff,'A'))) { *pA = ' '; InPlot(0,1,0,1,false); iw=B1.b[0]; ih=B1.b[4]; } else if(mglchr(font,'A')) { InPlot(0,1,0,1,false); iw=B1.b[0]; ih=B1.b[4]; } else { iw=B1.b[0]/B1.pf; ih=B1.b[4]/B1.pf; } // find sizes mreal h=TextHeight(font,size); mreal dx = 0.03*iw, dy = 0.03*ih, w=0, t, sp=TextWidth(" ",font,size); for(long i=0;it ? w:t; } w += ll+0.01*iw; // add space for lines long j = long((ih*0.95)/h); if(j<1) j=1; long ncol = 1+(n-1)/j, nrow = (n+ncol-1)/ncol; if(strchr(font,'-')) // horizontal legend { j = long((iw*0.95)/w); if(j<1) j=1; nrow = 1+(n-1)/j; ncol = (n+nrow-1)/nrow; } if(mglchr(font,'^')) // use "external" positioning { x = x>=0.5 ? x*iw : x*iw-w*ncol-2*dx; y = y>=0.5 ? y*ih : y*ih-h*nrow-2*dy; } else { x *= iw-w*ncol-2*dx; y *= ih-h*nrow-2*dy; } x += B.x-iw/2+dx; y += B.y-ih/2+dy; // draw it mglPoint p,q(NAN,NAN,NAN); mreal cc = AddTexture(font); mreal c1,c2; //=AddTexture(char(k1?k1:'w')), c2=AddTexture(char(k2?k2:'k')); if(cc<2 || Txt[long(cc+0.5)].n==0) { c1 = AddTexture('w'); cc = c2 = AddTexture('k'); } else switch(Txt[long(cc+0.5)].n) { case 1: c1 = AddTexture('w'); c2 = AddTexture('k'); break; case 2: c1 = cc; cc+=1/MGL_FEPSILON; c2 = AddTexture('k'); break; default: c1 = cc; c2 = cc+0.5; cc += 1/MGL_FEPSILON; break; } if((Flag&3)==2) { mreal tt=c1; c2=c1; c1=tt; } mglMatrix M=B; M.norot=true; if(strchr(font,'#')) // draw bounding box { SetPenPal("k-"); long k1=AddPnt(&M,mglPoint(x,y,Depth/1.01),c1,q,1,0); long k2=AddPnt(&M,mglPoint(x+w*ncol,y,Depth/1.01),c1,q,1,0); long k3=AddPnt(&M,mglPoint(x,y+h*nrow,Depth/1.01),c1,q,1,0); long k4=AddPnt(&M,mglPoint(x+w*ncol,y+h*nrow,Depth/1.01),c1,q,1,0); quad_plot(k1,k2,k3,k4); k1=CopyNtoC(k1,c2); k2=CopyNtoC(k2,c2); k3=CopyNtoC(k3,c2); k4=CopyNtoC(k4,c2); line_plot(k1,k2); line_plot(k2,k4); line_plot(k4,k3); line_plot(k3,k1); } for(long i=0;i=1) { SetWarn(mglWarnSpc,"Table"); return; } long i,j,m=val->GetNy(),n=val->GetNx(); // mreal pos=SaveState(opt); mreal vw = SaveState(opt); static int cgid=1; StartGroup("Table",cgid++); bool grid = mglchr(frm,'#'), eqd = mglchr(frm,'='), lim = mglchr(frm,'|'); if(mgl_isnan(vw)) vw=1; else lim = true; if(!text) text=L""; x=x<0?0:x; y=y<0?0:y; y=y>1?1:y; // if(vw>1-x) vw=1-x; char fmt[8]="3",ss[2]=" "; for(const char *s="0123456789";*s;s++) if(mglchr(frm,*s)) fmt[0]=*s; for(const char *s="f+E-F";*s;s++) if(mglchr(frm,*s)) { ss[0] = *s; strcat(fmt,ss); } std::vector str; for(i=0;iv(i,j),fmt)+L'\n'; buf += mgl_ftoa(val->v(i,m-1),fmt); str.push_back(buf); } mreal sp=2*TextWidth(" ",frm,-1), w=*text ? sp+TextWidth(text,frm,-1):0, w1=0, ww, h; for(i=0;ivw*inW) { h=vw*inW/w; SetFontSize(-h); w*=h; w1*=h; sp*=h; } h = TextHeight(frm,-1); // now we can determine text height x = x*(inW-w)+B.x-inW/2; y = y*(inH-h*m)+B.y-inH/2; mglPoint p,q(NAN,NAN); mreal xx,yy; if(grid) // draw bounding box { SetPenPal("k-"); long k1,k2; k1=AddPnt(&B,mglPoint(x,y,Depth),-1,q,-1,0); k2=AddPnt(&B,mglPoint(x,y+m*h,Depth),-1,q,-1,0); line_plot(k1,k2); ww = *text ? TextWidth(text,frm,-1)+sp:0; k1=AddPnt(&B,mglPoint(x+ww,y,Depth),-1,q,-1,0); k2=AddPnt(&B,mglPoint(x+ww,y+m*h,Depth),-1,q,-1,0); line_plot(k1,k2); for(i=0,xx=x+ww,yy=y;i0 ? size/FontSize:-size, h=TextHeight(stl,size)*s/2; if(h>=inH) { SetWarn(mglWarnSpc,"Title"); return; } static int cgid=1; StartGroup("Title",cgid++); int align; bool box=mglchr(stl,'#'), col = mglGetStyle(stl,0,&align); align = align&3; mreal y=inY+inH-h, zpos = 0;//3*Depth; mglPoint p(inX + inW*align/2.,y,zpos),q(NAN,NAN,NAN); mglMatrix M=B; M.norot=true; if(title) text_plot(AddPnt(&M,p,-1,q,-1,0),title,stl,size); if(box) // draw boungind box { mreal c1=AddTexture('w'), c2=col?AddTexture(stl):AddTexture('k'); if((Flag&3)==2 && !col) { mreal cc=c1; c2=c1; c1=cc; } else if((Flag&3)==2) c1=AddTexture('k'); long k1,k2,k3,k4; k1=AddPnt(&M,mglPoint(inX,y-h*0.4,zpos),c1,q,-1,0); k2=AddPnt(&M,mglPoint(inX+inW,y-h*0.4,zpos),c1,q,-1,0); k3=AddPnt(&M,mglPoint(inX,y+h,zpos),c1,q,-1,0); k4=AddPnt(&M,mglPoint(inX+inW,y+h,zpos),c1,q,-1,0); quad_plot(k1,k2,k3,k4); k1=CopyNtoC(k1,c2); k2=CopyNtoC(k2,c2); k3=CopyNtoC(k3,c2); k4=CopyNtoC(k4,c2); line_plot(k1,k2); line_plot(k2,k4); line_plot(k4,k3); line_plot(k3,k1); } B1.y -= h/2; B1.b[4] -= h; B=B1; inH-=h; font_factor = B.b[0] < B.b[4] ? B.b[0] : B.b[4]; EndGroup(); } //----------------------------------------------------------------------------- void mglCanvas::StartAutoGroup (const char *lbl) { static int id=1; if(lbl==NULL) { id=1; grp_counter=0; return; } grp_counter++; if(grp_counter>1) return; // do nothing in "subgroups" if(ObjId<0) { ObjId = -id; id++; } size_t len = Grp.size(); if(ObjId>=0 && (len==0 || (len>0 && ObjId!=Grp[len-1].Id))) #pragma omp critical(grp) { MGL_PUSH(Grp,mglGroup(lbl,ObjId),mutexGrp);} else if(ObjId<0) #pragma omp critical(grp) { MGL_PUSH(Grp,mglGroup(lbl,ObjId),mutexGrp);} } //----------------------------------------------------------------------------- void mglCanvas::EndGroup() { LoadState(); if(Quality&MGL_DRAW_LMEM) { Pnt.clear(); Prm.clear(); Ptx.clear(); ClearPrmInd(); Glf.clear(); Act.clear(); Grp.clear(); } if(grp_counter>0) grp_counter--; } //----------------------------------------------------------------------------- int mglCanvas::IsActive(int xs, int ys,int &n) { long i, h = (Width>Height ? Height:Width)/100; for(i=0;i<(long)Act.size();i++) { const mglActivePos &p=Act[i]; if(abs(xs-p.x)<=h && abs(ys-p.y)<=h) { n=p.n; return p.id; } } n=-1; return GetObjId(xs,ys); } //----------------------------------------------------------------------------- void mglCanvas::Push() { #pragma omp critical(stk) {MGL_PUSH(stack,B,mutexStk);} } //----------------------------------------------------------------------------- void mglCanvas::Pop() { B = stack.back(); #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexStk); stack.pop_back(); pthread_mutex_unlock(&mutexStk); #else #pragma omp critical(stk) stack.pop_back(); #endif } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/opengl.cpp�������������������������������������������������������������������������0000644�0001750�0001750�00000041352�13513030041�015731� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef WIN32 #include #endif #ifdef __APPLE__ #include #else #include #endif #include "mgl2/opengl.h" #include "mgl2/mgl_cf.h" #include //----------------------------------------------------------------------------- /// Create mglGraph object in OpenGL mode. HMGL MGL_EXPORT mgl_create_graph_gl() { return new mglCanvasGL; } /// Create mglGraph object in OpenGL mode. uintptr_t MGL_EXPORT mgl_create_graph_gl_() { return uintptr_t(new mglCanvasGL); } //----------------------------------------------------------------------------- mglCanvasGL::mglCanvasGL() : mglCanvas(1,1) { Clf(); Zoom(0,0,1,1); set(MGL_FULL_CURV); } //----------------------------------------------------------------------------- mglCanvasGL::~mglCanvasGL(){} //----------------------------------------------------------------------------- void set_pen(unsigned style, mreal width, mreal pos) { if(style==0) return; unsigned long pdef = style*0x100010001; pdef >>= long(32*pos)%32; // NOTE try to bypass OpenGL limitations style = pdef & 0xffff; width *= 20; if(style!=0xffff) { glEnable(GL_LINE_STIPPLE); glLineStipple(int(width+0.5),style); } else glDisable(GL_LINE_STIPPLE); if(width>1) glLineWidth(width); // NOTE bypass bug on some drivers, where width>1 must be else glLineWidth(1); } //----------------------------------------------------------------------------- void mglCanvasGL::Finish() { #if MGL_USE_DOUBLE #define MGL_GL_TYPE GL_DOUBLE #else #define MGL_GL_TYPE GL_FLOAT #endif // Try to add smoothing glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_BLEND); if((Flag&3)==1) glBlendFunc(GL_DST_COLOR, GL_ZERO); else if((Flag&3)==2) glBlendFunc(GL_SRC_ALPHA, GL_ONE); else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(Prm.size()>0) { PreparePrim(0); /* glVertexPointer(3, MGL_GL_TYPE, sizeof(mglPnt), &(Pnt[0].x)); // something wrong with arrays glNormalPointer(MGL_GL_TYPE, sizeof(mglPnt), &(Pnt[0].u)); glColorPointer(4, MGL_GL_TYPE, sizeof(mglPnt), &(Pnt[0].r)); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY);*/ int pdef=PDef; mreal ss=pPos, ww=PenWidth; mglPrim p; for(size_t i=0;i7) { SetWarn(mglWarnLId,"AddLight"); return; } if(c.Valid()) { spc[0] = br*c.r; spc[1] = br*c.g; spc[2] = br*c.b; amb[0] = AmbBr*c.r; amb[1] = AmbBr*c.g; amb[2] = AmbBr*c.b; } else { spc[0] = spc[1] = spc[2] = br; amb[0] = amb[1] = amb[2] = AmbBr; } ap = 90-180*atan(fabs(ap))/M_PI; dif[0] = dif[1] = dif[2] = DifBr; dif[3] = amb[3] = spc[3] = 1.; if(inf) { pos[0] = d.x; pos[1] = d.y; pos[2] = d.z; pos[3] = 0; } else { pos[0] = r.x; pos[1] = r.y; pos[2] = r.z; pos[3] = 1; } glShadeModel(GL_SMOOTH); glLightfv(GL_LIGHT0+n, GL_AMBIENT, amb); glLightfv(GL_LIGHT0+n, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0+n, GL_SPECULAR, spc); glLightfv(GL_LIGHT0+n, GL_POSITION, pos); if(!inf) { // float dir[4]={d.x, d.y, d.z, 0}; // glLightfv(GL_LIGHT0+n, GL_SPOT_DIRECTION, dir); // glLightf(GL_LIGHT0+n, GL_SPOT_CUTOFF, ap); } glEnable(GL_LIGHT0+n); } //----------------------------------------------------------------------------- void mglCanvasGL::Light(int n, bool enable) { if(enable) glEnable(GL_LIGHT0+n); else glDisable(GL_LIGHT0+n); } //----------------------------------------------------------------------------- bool mglCanvasGL::Light(bool enable) { if(enable) { glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE);} else { glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); } return mglCanvas::Light(enable); } //----------------------------------------------------------------------------- void mglCanvasGL::LightScale(const mglMatrix *M) { mglCanvas::LightScale(M); GLenum ll[8] = {GL_LIGHT0,GL_LIGHT1,GL_LIGHT2,GL_LIGHT3,GL_LIGHT4, GL_LIGHT5,GL_LIGHT6,GL_LIGHT7}; float pos[4]={0,0,0,0}; for(int i=0;i<8;i++) // NOTE only global light is used in OpenGL mode { pos[0] = light[i].p.x; pos[1] = light[i].p.y; pos[2] = light[i].p.z; if(light[i].n) glLightfv(ll[i], GL_POSITION, pos); } } //----------------------------------------------------------------------------- void mglCanvasGL::Zoom(mreal x1, mreal y1, mreal x2, mreal y2) { glMatrixMode(GL_PROJECTION);//GL_PROJECTION GL_VIEWPORT GL_MODELVIEW glLoadIdentity(); glScaled(x2-x1,y2-y1,1); glTranslated((x1+x2-1)/2,(y1+y2-1)/2,0); } //----------------------------------------------------------------------------- void mglCanvasGL::View(mreal TetX,mreal TetY,mreal TetZ) { glMatrixMode(GL_PROJECTION);//GL_PROJECTION GL_VIEWPORT GL_MODELVIEW glRotated(TetX,1.,0.,0.); glRotated(TetY,0.,1.,0.); glRotated(TetZ,0.,0.,1.); } //----------------------------------------------------------------------------- void mglCanvasGL::Fog(mreal d, mreal) { if(d>0) { float back[4]={BDef[0]/255.f,BDef[1]/255.f,BDef[2]/255.f,BDef[3]/255.f}; glFogf(GL_FOG_MODE,GL_EXP); glFogf(GL_FOG_DENSITY,5*d); glFogfv(GL_FOG_COLOR,back); glEnable(GL_FOG); } else glDisable(GL_FOG); } //----------------------------------------------------------------------------- void mglCanvasGL::Clf(mglColor Back) { mglCanvas::Clf(Back); if(Back==NC) Back.Set(BDef[0]/255.,BDef[1]/255.,BDef[2]/255.); gl_clf(Back); } //----------------------------------------------------------------------------- void mglCanvasGL::Clf(const char *col) { mglCanvas::Clf(col); gl_clf(mglColor(BDef[0]/255.,BDef[1]/255.,BDef[2]/255.)); } //----------------------------------------------------------------------------- void mglCanvasGL::gl_clf(mglColor Back) { if(Back==NC) Back = WC; // glDepthFunc(GL_LESS); glDepthFunc(GL_GREATER); glClearColor(Back.r,Back.g,Back.b,1.); glClearDepth(-10.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_COLOR_MATERIAL); glMatrixMode(GL_MODELVIEW);//GL_MODELVIEW GL_VIEWPORT GL_PROJECTION glLoadIdentity(); glScaled(2,2,2); glTranslated(-0.5,-0.5,-0.5); // float dif[4]={DifBr,DifBr,DifBr,1}; // glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dif); float spc[4]={1,1,1,1}; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spc); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, DifBr); } //----------------------------------------------------------------------------- /*void mglCanvasGL::EndFrame() { // mglGraph::EndFrame(); glEndList(); } //----------------------------------------------------------------------------- int mglCanvasGL::NewFrame() { Clf(); Identity(); glNewList(CurFrameId,GL_COMPILE); CurFrameId++; return CurFrameId-1; }*/ //----------------------------------------------------------------------------- unsigned char **mglCanvasGL::GetRGBLines(long &width, long &height, unsigned char *&f, bool alpha) { long x, y, d = alpha ? 4:3; GLint w[4]; glGetIntegerv(GL_VIEWPORT,w); x=w[0]; y=w[1]; width=w[2]; height=w[3]; unsigned char **p; p = (unsigned char **)malloc(height * sizeof(unsigned char *)); f = (unsigned char *) malloc(width*height * sizeof(unsigned char)*d); for(long i=0;iPenWidth = ss?ss:sqrt(font_factor/400); pnt_draw(q,d); } else { if(d) { d->PDef = MGL_SOLID_MASK; d->angle = 0; d->PenWidth*=fabs(50*size); if(d->PenWidth<1) d->PenWidth=1; } if(!strchr("xsSoO",type)) ss *= 1.1; switch(type) { case 'P': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y-ss; p2.x = q.x+ss; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y+ss; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p3,d); line_draw(p3,p0,d); case '+': p0.x = q.x-ss; p0.y = q.y; p1.x = q.x+ss; p1.y = q.y; line_draw(p0,p1,d); p2.x = q.x; p2.y = q.y-ss; p3.x = q.x; p3.y = q.y+ss; line_draw(p2,p3,d); break; case 'X': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y-ss; p2.x = q.x+ss; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y+ss; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p3,d); line_draw(p3,p0,d); case 'x': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y+ss; line_draw(p0,p1,d); p2.x = q.x+ss; p2.y = q.y-ss; p3.x = q.x-ss; p3.y = q.y+ss; line_draw(p2,p3,d); break; case 'S': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x-ss; p1.y = q.y+ss; p2.x= q.x+ss; p2.y= q.y+ss; p3.x = q.x+ss; p3.y = q.y-ss; quad_draw(p0,p1,p3,p2,d); case 's': p0.x = q.x-ss; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y-ss; p2.x = q.x+ss; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y+ss; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p3,d); line_draw(p3,p0,d); break; case 'D': p0.x = q.x; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y; p2.x= q.x; p2.y= q.y+ss; p3.x = q.x-ss; p3.y = q.y; quad_draw(p0,p1,p3,p2,d); case 'd': p0.x = q.x; p0.y = q.y-ss; p1.x = q.x+ss; p1.y = q.y; p2.x = q.x; p2.y = q.y+ss; p3.x = q.x-ss; p3.y = q.y; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p3,d); line_draw(p3,p0,d); break; case 'Y': p1.x = q.x; p1.y = q.y-ss; line_draw(q,p1,d); p2.x = q.x-0.8*ss; p2.y = q.y+0.6*ss; line_draw(q,p2,d); p3.x = q.x+0.8*ss; p3.y = q.y+0.6*ss; line_draw(q,p3,d); break; case '*': p0.x = q.x-ss; p0.y = q.y; p1.x = q.x+ss; p1.y = q.y; line_draw(p0,p1,d); p0.x = q.x-0.6*ss; p0.y = q.y-0.8*ss; p1.x = q.x+0.6*ss; p1.y = q.y+0.8*ss; line_draw(p0,p1,d); p0.x = q.x-0.6*ss; p0.y = q.y+0.8*ss; p1.x = q.x+0.6*ss; p1.y = q.y-0.8*ss; line_draw(p0,p1,d); break; case 'T': p0.x = q.x-ss; p0.y = q.y-ss/2; p1.x = q.x+ss; p1.y = q.y-ss/2; p2.x= q.x; p2.y= q.y+ss; trig_draw(p0,p1,p2,false,d); case '^': p0.x = q.x-ss; p0.y = q.y-ss/2; p1.x = q.x+ss; p1.y = q.y-ss/2; p2.x= q.x; p2.y= q.y+ss; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p0,d); break; case 'V': p0.x = q.x-ss; p0.y = q.y+ss/2; p1.x = q.x+ss; p1.y = q.y+ss/2; p2.x= q.x; p2.y= q.y-ss; trig_draw(p0,p1,p2,false,d); case 'v': p0.x = q.x-ss; p0.y = q.y+ss/2; p1.x = q.x+ss; p1.y = q.y+ss/2; p2.x= q.x; p2.y= q.y-ss; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p0,d); break; case 'L': p0.x = q.x+ss/2; p0.y = q.y+ss; p1.x = q.x+ss/2; p1.y = q.y-ss; p2.x= q.x-ss; p2.y= q.y; trig_draw(p0,p1,p2,false,d); case '<': p0.x = q.x+ss/2; p0.y = q.y+ss; p1.x = q.x+ss/2; p1.y = q.y-ss; p2.x= q.x-ss; p2.y= q.y; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p0,d); break; case 'R': p0.x = q.x-ss/2; p0.y = q.y+ss; p1.x = q.x-ss/2; p1.y = q.y-ss; p2.x= q.x+ss; p2.y= q.y; trig_draw(p0,p1,p2,false,d); case '>': p0.x = q.x-ss/2; p0.y = q.y+ss; p1.x = q.x-ss/2; p1.y = q.y-ss; p2.x= q.x+ss; p2.y= q.y; line_draw(p0,p1,d); line_draw(p1,p2,d); line_draw(p2,p0,d); break; case 'O': /* for(long j=long(-ss);j<=long(ss);j++) for(long i=long(-ss);i<=long(ss);i++) { long x=long(q.x)+i, y=long(q.y)+j; if(i*i+j*j>=ss*ss || !d || xx1 || x>d->x2 || yy1 || y>d->y2) continue; if(cs[3]) pnt_plot(x,y,q.z+1,cs,d->ObjId); }*/ case 'o': for(long i=0;i<=20;i++) // TODO copy from mark_pix()?! { p0 = p1; p1.x = q.x+ss*cos(i*M_PI/10); p1.y = q.y+ss*sin(i*M_PI/10); if(i>0) line_draw(p0,p1,d); } break; case 'C': pnt_draw(q,d); for(long i=0;i<=20;i++) { p0 = p1; p1.x = q.x+ss*cos(i*M_PI/10); p1.y = q.y+ss*sin(i*M_PI/10); if(i>0) line_draw(p0,p1,d); } break; } } } //----------------------------------------------------------------------------- void mglCanvasGL::glyph_fill(mreal phi, const mglPnt &pp, mreal f, const mglGlyph &g, const mglDrawReg *d) { if(!g.trig || g.nt<=0) return; const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180); mglPnt q0=pp, q1=pp, q2=pp; q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=NAN; for(long ik=0;ik * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/canvas.h" #include "mgl2/thread.h" #if MGL_HAVE_OMP #include #endif //----------------------------------------------------------------------------- void mglCanvas::pxl_combine(long id, long n, const void *) { #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=id;i=0) { float x = p.xx-Width/2., y = p.yy-Height/2., z = p.zz-Depth/2.; p.x = b[0]*x + b[1]*y + b[2]*z + dx; p.y = b[3]*x + b[4]*y + b[5]*z + dy; p.z = b[6]*x + b[7]*y + b[8]*z + dz; float d = get_persp(Bp.pf,p.z,Depth); p.x = Width/2. + d*p.x; p.y = Height/2. + d*p.y; } } } //----------------------------------------------------------------------------- void mglCanvas::pxl_setz_adv(long id, long n, const void *) { #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=id;i= sqrt(2*num_thr) ??? const int nx=Q,ny=Q; // TODO find dependence on Q for 1, 2, 4, 8 threads. Try to select optimal #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=id;i=0 && i0Z[3*i0]) { Z[3*i0]=z; c[0]=r[0]; c[1]=r[1]; c[2]=r[2]; c[3]=r[3]; OI[i0]=-1; } } } //----------------------------------------------------------------------------- void mglCanvas::pxl_other(long id, long n, const void *p) { const mglCanvas *gr = (const mglCanvas *)p; if(Quality&MGL_DRAW_NORM) #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long k=id;kZ[3*k+2],gr->C+12*k+8,gr->OI[k]); pnt_plot(i,j,gr->Z[3*k+1],gr->C+12*k+4,gr->OI[k]); pnt_plot(i,j,gr->Z[3*k],gr->C+12*k,gr->OI[k]); } else #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long k=id;kZ[3*k],gr->C+12*k,gr->OI[k]); } } //----------------------------------------------------------------------------- void mglCanvas::pnt_plot(long x,long y,mreal z,const unsigned char ci[4], int obj_id) { if(ci[3]) { long i0=x+Width*(Height-1-y); unsigned char *cc = C+12*i0, c[4]; c[0]=ci[0]; c[1]=ci[1]; c[2]=ci[2]; c[3]=ci[3]; float *zz = Z+3*i0, zf = FogDist*(z/Depth-0.5-FogDz); // try to remove double transparency near vertexes if(fabs(z-zz[0])<1 && OI[i0]==obj_id && abs(cc[0]-ci[0])+abs(cc[1]-ci[1])+abs(cc[2]-ci[2])<5) { if(cc[3]=zz[1]) // shift point on slice down and paste new point { zz[2] = zz[1]; combine(cc+8,cc+4); if(z>=zz[0]) { zz[1] = zz[0]; zz[0] = z; OI[i0]=obj_id; cc[4]=cc[0]; cc[0]=c[0]; cc[5]=cc[1]; cc[1]=c[1]; cc[6]=cc[2]; cc[2]=c[2]; cc[7]=cc[3]; cc[3]=c[3]; } else { zz[1] = z; cc[4]=c[0]; cc[5]=c[1]; cc[6]=c[2]; cc[7]=c[3]; } } else { if(z>=zz[2]) // shift point on slice down and paste new point { zz[2] = z; combine(cc+8,c); } else // point below the background { combine(c,cc+8); cc[8]=c[0]; cc[9]=c[1]; cc[10]=c[2];cc[11]=c[3]; } } } if(Quality&MGL_DRAW_FAST) { if(z>=zz[0]) // point upper the background { zz[0]=z; combine(cc,c); OI[i0]=obj_id; } else { combine(c,cc); cc[6]=cc[2]; cc[2]=c[2]; cc[7]=cc[3]; cc[3]=c[3]; } } else { if(z>=zz[0]) // point upper the background { zz[0]=z; cc[0]=c[0]; cc[1]=c[1]; cc[2]=c[2]; cc[3]=c[3]; OI[i0]=obj_id; } } } } //----------------------------------------------------------------------------- inline float mexp(float x) // exp(-x) ~ 1/(1+x+x^2/2+x^3/4+x^5/40) { return 1.f/(1.f+x*(1.f+x*x/2.f)); } //{ return 1/(1+x*(1+x/2*(1+x/2*(1+x*x/10)))); } //{ return exp(-x); } void mglCanvas::col2int(const mglPnt &p,unsigned char *r, int obj_id) const { // if(!r) return r; // NOTE r must be provided! if(p.a<=0) { r[0]=r[1]=r[2]=r[3]=0; return; } float b0=0,b1=0,b2=0, ar,ag,ab,dif; const size_t nl = p.sub>=0?p.sub:-1-p.sub; const bool glob = !get(MGL_LOCAL_LIGHT); ar = ag = ab = glob?AmbBr:Sub[nl].AmbBr; dif = glob?DifBr:Sub[nl].DifBr; const mglLight *gll = glob?light:Sub[nl].light; if(mgl_isnum(p.u+p.v+p.w)) { for(long i=0;i<10;i++) { const mglLight &ll=gll[i]; if(!ll.n) continue; if(mgl_isnan(ll.q.x)) // source at infinity { const mglPoint &lp = ll.p; float nn = 2*(p.u*lp.x+p.v*lp.y+p.w*lp.z) / (p.u*p.u+p.v*p.v+p.w*p.w+1e-6f); float d0 = lp.x - p.u*nn; float d1 = lp.y - p.v*nn; float d2 = lp.z - p.w*nn; nn = 1 + d2/sqrt(d0*d0+d1*d1+d2*d2+1e-6f); // nn = exp(-ll.a*nn)*ll.b*2; nn = mexp(ll.a*nn)*ll.b*2.f; const mglColor &lc = ll.c; b0 += nn*lc.r; b1 += nn*lc.g; b2 += nn*lc.b; } else // diffuse and specular light { const mglPoint &lp=ll.p, &lq=ll.q; float d0 = lq.x-p.x; // direction to light source float d1 = lq.y-p.y; float d2 = lq.z-p.z; float nn = 1+(d0*lp.x+d1*lp.y+d2*lp.z)/sqrt(d0*d0+d1*d1+d2*d2+1e-6f); // float bb = exp(-3*ll.a*nn); nn = bb*dif*2; float bb = mexp(3*ll.a*nn); nn = bb*dif*2; const mglColor &lc = ll.c; ar += nn*lc.r; ag += nn*lc.g; ab += nn*lc.b; nn = 2*(p.u*d0+p.v*d1+p.w*d2) / (p.u*p.u+p.v*p.v+p.w*p.w+1e-6f); d0 -= p.u*nn; d1 -= p.v*nn; d2 -= p.w*nn; nn = 1 + d2/sqrt(d0*d0+d1*d1+d2*d2+1e-6f); // nn = exp(-ll.a*nn)*bb*ll.b*2; nn = mexp(ll.a*nn)*bb*ll.b*2.f; b0 += nn*lc.r; b1 += nn*lc.g; b2 += nn*lc.b; } } b0 += (ar>1 ? 1:ar)*p.r; // diffuse light b1 += (ag>1 ? 1:ag)*p.g; b2 += (ab>1 ? 1:ab)*p.b; b0 = b0<1 ? b0 : 1; // normalize components b1 = b1<1 ? b1 : 1; b2 = b2<1 ? b2 : 1; } else { b0=p.r; b1=p.g; b2=p.b; } // try to highlight faces if(obj_id==HighId) { b0*=0.7; b1*=0.7; b2*=0.7; } r[0] = (unsigned char)(255*b0); r[1] = (unsigned char)(255*b1); r[2] = (unsigned char)(255*b2); // r[3] = get(MGL_ENABLE_ALPHA) ? (unsigned char)(255*p.a) : 255; r[3] = (unsigned char)((Quality&MGL_DRAW_NORM)?255*p.a:255); // return r; } //----------------------------------------------------------------------------- /// color mixing: color c1 is under color c2 !!! void mglCanvas::combine(unsigned char *c1, const unsigned char *c2) const { if(c2[3]) { const unsigned a1=c1[3], a2=c2[3]; if((Flag&3)==0) { unsigned b1=255-a2; c1[0] = (c1[0]*b1 + c2[0]*a2)/256; c1[1] = (c1[1]*b1 + c2[1]*a2)/256; c1[2] = (c1[2]*b1 + c2[2]*a2)/256; c1[3] = (unsigned char)(a2+a1*b1/255); } else if((Flag&3)==1) { c1[0] = (unsigned char)((255-a1*(255-c1[0])/256)*(255-a2*(255-c2[0])/256)/256); c1[1] = (unsigned char)((255-a1*(255-c1[1])/256)*(255-a2*(255-c2[1])/256)/256); c1[2] = (unsigned char)((255-a1*(255-c1[2])/256)*(255-a2*(255-c2[2])/256)/256); c1[3] = 255; } else if((Flag&3)==2) { unsigned b1,b2,b3; b1 = (c1[0]*a1 + c2[0]*a2)/255; c1[0] = b1<255 ? b1 : 255; b2 = (c1[1]*a1 + c2[1]*a2)/255; c1[1] = b2<255 ? b2 : 255; b3 = (c1[2]*a1 + c2[2]*a2)/255; c1[2] = b3<255 ? b3 : 255; c1[3] = 255; } } } //----------------------------------------------------------------------------- // it looks as MSV=4 is optimal for speed-vs-quality #define MSV 4 int inline visible(long i, long j, const unsigned char m[8], mreal pw, int a) // Check if pixel visible { float c = mgl_cos[(a+360)%360], s = mgl_cos[(a+450)%360]; int ii,jj,ss=0; #if MSV==4 ii = int(0.5+((i-0.33)*c+(j-0.33)*s)/pw)&7; jj = int(0.5+((j-0.33)*c-(i-0.33)*s)/pw)&7; if(m[jj] & (1L<x1); x2=mgl_imin(x2,d->x2); y1=mgl_imax(y1,d->y1); y2=mgl_imin(y2,d->y2); if(x1>x2 || y1>y2) return; const float dd = d1.x*d2.y-d1.y*d2.x; const float dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y; const float dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x; mglPoint n1(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z)); mglPoint n2(mglPoint(p2.x-p4.x,p2.y-p4.y,p2.z-p4.z)^mglPoint(p3.x-p4.x,p3.y-p4.y,p3.z-p4.z)); mglPoint nr((n1.x+n2.x)*0.5,(n1.y+n2.y)*0.5,(n1.z+n2.z)*0.5); const float x0 = p1.x, y0 = p1.y; const int oi = d->ObjId, ang=d->angle; const mreal pw = d->PenWidth; const uint64_t pd = d->PDef; mglPnt tmp(p1+d1+d2+d3), pp(p1); if(mgl_isnan(tmp.u) && mgl_isnum(tmp.v)) { pp.u = nr.x; pp.v = nr.y; pp.w = nr.z; d1.u=d1.v=d1.w=d2.u=d2.v=d2.w=d3.u=d3.v=d3.w=0; } for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { int ms = (pd==MGL_SOLID_MASK) ? 4 : visible(i,j,d->m, pw,ang); if(ms!=0) { float xx = (i-x0), yy = (j-y0), s; s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy); if(s>=0) { s = sqrt(s); float qu = d3.x*yy - d3.y*xx + dd + s; float qv = d3.y*xx - d3.x*yy + dd + s; float u = 2.f*(d2.y*xx - d2.x*yy)/qu; float v = 2.f*(d1.x*yy - d1.y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad { qu = d3.x*yy - d3.y*xx + dd - s; qv = d3.y*xx - d3.x*yy + dd - s; // u = v = -1.f; u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad } mglPnt p(pp+d1*u+d2*v+d3*(u*v)); col2int(p,r,oi); r[3] = ms*r[3]/MSV; if(r[3]) pnt_plot(i,j,p.z,r,oi); } } } } //----------------------------------------------------------------------------- /* Linear interpolation r(u,v) = r0 + (r1-r0)*u + (r2-r0)*v is used, where r is one of {x,y,z,R,G,B,A}. Variables u,v are determined for each point (x,y). Point plotted is u>0 and v>0 and u+v<1.*/ void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d) { if(!(Quality&3) && anorm) { fast_draw(p1,p2,d); fast_draw(p1,p3,d); fast_draw(p2,p3,d); return; } unsigned char r[4]; long y1,x1,y2,x2; mglPnt d1(p2-p1), d2(p3-p1); const float tmp = d2.x*d1.y - d1.x*d2.y; if(fabs(tmp)<1e-5) return; // points lies on the same line const float dyv =-d1.x/tmp, dxv = d1.y/tmp; const float dyu = d2.x/tmp, dxu =-d2.y/tmp; x1 = long(mgl_min(p1.xp2.x?p1.x:p2.x, p3.x)); y2 = long(mgl_max(p1.y>p2.y?p1.y:p2.y, p3.y)); x1=x1>d->x1?x1:d->x1; x2=x2x2?x2:d->x2; y1=y1>d->y1?y1:d->y1; y2=y2y2?y2:d->y2; if(x1>x2 || y1>y2) return; // default normale const mglPoint nr(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z)); const float x0 = p1.x, y0 = p1.y; // provide additional height to be well visible on the surfaces const float dz = anorm? 0 : (Width>2 ? 1 : 1e-5*Width); const int oi = d->ObjId, ang=d->angle; const mreal pw = d->PenWidth; const uint64_t pd = d->PDef; mglPnt tp(p1+d1+d2), pp(p1); if(mgl_isnan(tp.u) && mgl_isnum(tp.v)) { pp.u = nr.x; pp.v = nr.y; pp.w = nr.z; d1.u=d1.v=d1.w=d2.u=d2.v=d2.w=0; } if(Quality&MGL_DRAW_NORM) for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { int ms = (pd==MGL_SOLID_MASK) ? 4 : visible(i,j,d->m, pw,ang); if(ms!=0) { float xx = (i-x0), yy = (j-y0); float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; if(u<0 || v<0 || u+v>1) continue; mglPnt p(pp+d1*u+d2*v); col2int(p,r,oi); r[3] = ms*r[3]/MSV; if(r[3]) pnt_plot(i,j,p.z+dz,r,oi); } } else { col2int(p1,r,oi); float zz = p1.z+dz, dz1=d1.z, dz2=d2.z; unsigned char ra = r[3]; if(ra) for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { int ms = (pd==MGL_SOLID_MASK) ? 4 : visible(i,j,d->m, pw,ang); if(ms!=0) { float xx = (i-x0), yy = (j-y0); float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; if(u<0 || v<0 || u+v>1) continue; r[3] = ms*ra/MSV; pnt_plot(i,j,zz+dz1*u+dz2*v,r,oi); } } } } //----------------------------------------------------------------------------- inline unsigned char mgl_sline(unsigned char c,float x) { x*=x/2; return (unsigned char)(c/(1+x+x*x/5)); } void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr) { if((Quality&3)==MGL_DRAW_WIRE) { fast_draw(p1,p2,dr); return; } // previously was <2. This may slightly slow down for Quality=1 unsigned char r[4]; long y1,x1,y2,x2; const float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces const int oi = dr->ObjId; const float pw=dr->PenWidth*(oi==HighId?2:1), dpw=pen_delta*(oi==HighId?2:3); const mglPnt d(p2-p1); bool hor = fabs(d.x)>fabs(d.y); x1 = long(p1.xp2.x?p1.x:p2.x); y2 = long(p1.y>p2.y?p1.y:p2.y); x1 -= pw+10/dpw; x2 += pw+10/dpw; y1 -= pw+10/dpw; y2 += pw+10/dpw; x1=x1>dr->x1?x1:dr->x1; x2=x2x2?x2:dr->x2; y1=y1>dr->y1?y1:dr->y1; y2=y2y2?y2:dr->y2; const float dd = hypot(d.x, d.y); if(x1>x2 || y1>y2 || dd<1e-5) return; const float dxv = d.y/dd, dyv =-d.x/dd; const float dxu = d.x/dd, dyu = d.y/dd; const uint64_t pd = dr->PDef; const mreal pp = dr->pPos, V = (pw-1)*(pw-1)/4, S = (1-pw)/2; if(hor) for(long i=x1;i<=x2;i++) { y1 = int(p1.y+d.y*(i-p1.x)/d.x - pw - 10/dpw); y2 = int(p1.y+d.y*(i-p1.x)/d.x + pw + 10/dpw); y1=y1>dr->y1?y1:dr->y1; y2=y2y2?y2:dr->y2; for(long j=y1;j<=y2;j++) { float xx = (i-p1.x), yy = (j-p1.y); float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; v = v*v; if(u<0) { v += 16*u*u; u=0; } else if(u>dd) { v += 16*(u-dd)*(u-dd); u=dd; } if( pd & ((uint64_t)1<<(long(pp+u/pw)%16)) ) { mglPnt p(p1+d*(u/dd)); col2int(p,r,oi); r[3] = vdr->x1?x1:dr->x1; x2=x2x2?x2:dr->x2; for(long i=x1;i<=x2;i++) { float xx = (i-p1.x), yy = (j-p1.y); float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; v = v*v; if(u<0) { v += 16*u*u; u=0; } else if(u>dd) { v += 16*(u-dd)*(u-dd); u=dd; } if( pd & ((uint64_t)1<<(long(pp+u/pw)%16)) ) { mglPnt p(p1+d*(u/dd)); col2int(p,r,oi); r[3] = vZ[3*i0]) // point upper the background { Z[3*i0]=z; OI[i0]=obj_id; cc[0]=ci[0]; cc[1]=ci[1]; cc[2]=ci[2]; cc[3]=ci[3]; } } //----------------------------------------------------------------------------- void mglCanvas::fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr) { if(p1.x==p2.x && p1.y==p2.y) return; const mglPnt d(p2-p1); const int oi = dr->ObjId; unsigned char r[4]; col2int(p1,r,oi); long y1,x1,y2,x2; const bool hor = fabs(d.x)>fabs(d.y); x1 = long(p1.xp2.x?p1.x:p2.x); y2 = long(p1.y>p2.y?p1.y:p2.y); x1=x1>dr->x1?x1:dr->x1; x2=x2x2?x2:dr->x2; y1=y1>dr->y1?y1:dr->y1; y2=y2y2?y2:dr->y2; if(x1>x2 || y1>y2) return; const float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces if(hor) for(long i=x1;i<=x2;i++) { long c = long(p1.y+d.y*(i-p1.x)/d.x); if(c>=y1 && c<=y2) pnt_fast(i, c, p1.z+d.z*(i-p1.x)/d.x+dz, r,oi); } else for(long i=y1;i<=y2;i++) { long c = long(p1.x+d.x*(i-p1.y)/d.y); if(c>=x1 && c<=x2) pnt_fast(c, i, p1.z+d.z*(i-p1.y)/d.y+dz, r,oi); } } //----------------------------------------------------------------------------- void mglCanvas::pnt_draw(const mglPnt &p, const mglDrawReg *dr) { // if(k<0 || !dr) return; const int oi = dr->ObjId; const float pw=(oi==HighId?6:3)*dr->PenWidth,dpw=(oi==HighId?2:3)*pen_delta; unsigned char cs[4], cc; col2int(p,cs,oi); cc = cs[3]; if(cc==0) return; const long s = long(pw+10/dpw+fabs(pw)); const long i1=mgl_max(-s,dr->x1-p.x),i2=mgl_min(s,dr->x2-p.x); const long j1=mgl_max(-s,dr->y1-p.y),j2=mgl_min(s,dr->y2-p.y); const mreal V = (pw-1)*(pw-1)/4, S = (1-pw)/2; if(!(Quality&3)) for(long j=j1;j<=j2;j++) for(long i=i1;i<=i2;i++) // fast draw { float v = i*i+j*j; if(v>1+V) continue; if(cs[3]) pnt_plot(p.x+i,p.y+j,p.z,cs,oi); } else for(long j=j1;j<=j2;j++) for(long i=i1;i<=i2;i++) { float v = i*i+j*j; cs[3] = vObjId; unsigned char cs[4]; col2int(q,cs,oi); const unsigned char ca = cs[3];// = size>0 ? 255 : 255*q.t; const mreal ss=(strchr("xsSoO",type)?1:1.1)*fabs(size), dpw=(oi==HighId?2:3)*pen_delta; mreal PW=1; if(type=='.' || ss==0) { PW = 3*(ss?ss:sqrt(font_factor/400)); if(oi==HighId) PW *= 2; const mreal pw = PW; mreal dd = pw+10/dpw; long x1 = long(q.x-dd), y1 = long(q.y-dd); // bounding box long x2 = long(q.x+dd), y2 = long(q.y+dd); x1=x1>dr->x1?x1:dr->x1; x2=x2x2?x2:dr->x2; y1=y1>dr->y1?y1:dr->y1; y2=y2y2?y2:dr->y2; if(x1>x2 || y1>y2) return; const float V=(pw-1)*(pw-1)/4,S=(1-pw)/2; for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v=dx*dx+dy*dy; int sum = vPDef = MGL_SOLID_MASK; dr->angle = 0; PW = dr->PenWidth*sqrt(fabs(50*size)); if(PW<1) PW=1; if(oi==HighId) PW *= 2; const mreal pw = PW; mreal dd = ss+pw+10/dpw; long x1 = long(q.x-dd), y1 = long(q.y-dd); // bounding box long x2 = long(q.x+dd), y2 = long(q.y+dd); x1=x1>dr->x1?x1:dr->x1; x2=x2x2?x2:dr->x2; y1=y1>dr->y1?y1:dr->y1; y2=y2y2?y2:dr->y2; if(x1>x2 || y1>y2) return; const float V=(pw-1)*(pw-1)/4,S=(1-pw)/2; switch(type) { case 'P': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy)-ss; v = (dx-ss)*(dx-ss)+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case '+': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy)-ss; v = dx*dx+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'X': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy)-ss; v = (dx-ss)*(dx-ss)+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'x': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dx+dy)-2*ss; v = dx-dy; v = v*v+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'S': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; u = fabs(dy)-ss; if(u<0) u=0; v = fabs(dx)-ss; if(v<0) v=0; v = u*u+v*v; int sum = v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'D': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; u = fabs(dx-dy)-ss; if(u<0) u=0; v = fabs(dx+dy)-ss; if(v<0) v=0; v = u*u+v*v; int sum = v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'Y': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy+ss/2)-ss/2; v = dx*dx+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case '*': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy)-ss; v = dx*dx+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'T': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; u=dy/1.5+ss/3; v=(dx+ss-u)/2; if(u>0 && v>0 && u+v255?255:sum; cs[3] = ca*sum/255; } if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case '^': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dx)-ss; v = dy+ss/2; v = v*v+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'V': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; u=-dy/1.5+ss/3; v=(dx+ss-u)/2; if(u>0 && v>0 && u+v255?255:sum; cs[3] = ca*sum/255; } if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'v': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dx)-ss; v = dy-ss/2; v = v*v+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'L': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; u=-dx/1.5+ss/3; v=(dy+ss-u)/2; if(u>0 && v>0 && u+v255?255:sum; cs[3] = ca*sum/255; } if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case '<': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy)-ss; v = dx-ss/2; v = v*v+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'R': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; u=dx/1.5+ss/3; v=(dy+ss-u)/2; if(u>0 && v>0 && u+v255?255:sum; cs[3] = ca*sum/255; } if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case '>': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v,u; int sum=0; u = fabs(dy)-ss; v = dx+ss/2; v = v*v+(u<0?0:u*u); sum += v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; case 'O': for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float dx=i-q.x, dy=j-q.y, v; v = hypot(dx,dy)-ss; v=v<0?0:v*v; int sum = v255?255:sum; cs[3] = ca*sum/255; if(cs[3]) pnt_plot(i,j,q.z+1,cs,oi); } break; } } } //----------------------------------------------------------------------------- // scale direction for new view/zoom float mglCanvas::GetGlyphPhi(const mglPnt &q, float phi) { float x,y,z,ll; if(q.sub<0) { x = q.u; y = q.v; z = q.w; } else { x = Bp.b[0]*q.u + Bp.b[1]*q.v + Bp.b[2]*q.w; y = Bp.b[3]*q.u + Bp.b[4]*q.v + Bp.b[5]*q.w; z = Bp.b[6]*q.u + Bp.b[7]*q.v + Bp.b[8]*q.w; float dv= get_persp(Bp.pf,q.z,Depth); float c = get_pfact(Bp.pf,Depth); x += (q.x-Width/2)*z*c*dv; y += (q.y-Height/2)*z*c*dv; } ll = x*x+y*y; if(ll < 1e-10) return NAN; if(ll==ll && phi<1e4) { phi = -atan2(y,x)*180/M_PI; // if(fabs(phi)>90) phi+=180; // NOTE this is 2nd part of rotation changes (see also text_plot()) } else phi=0; return phi; } //----------------------------------------------------------------------------- void mglCanvas::glyph_draw(const mglPrim &P, mglDrawReg *d) { float phi = GetGlyphPhi(Pnt[P.n2],P.w); if(mgl_isnan(phi)) return; if(d) { d->PDef = MGL_SOLID_MASK; d->angle = 0; d->PenWidth=(P.n3&4)?1.2:0.8; } mglPnt p=Pnt[P.n1]; p.a=1; mreal fact = get_persp(Bp.pf,p.z,Depth); mreal pf=p.sub<0?1:sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2)*fact; mreal size=P.s, f = P.p*pf*P.s; p.u *= pf*size; p.v *= pf*size; const mglGlyph &g = Glf[P.n4]; if(P.n3&8) { if(!(P.n3&4)) glyph_line(phi,p,f,true, d); glyph_line(phi,p,f,false, d); } else { if(!(P.n3&4)) glyph_fill(phi,p,f,g, d); glyph_wire(phi,p,f,g, d); } } //----------------------------------------------------------------------------- void static mgl_addpnts(mreal x1,mreal y1,mreal x2,mreal y2, std::vector *b) { // if(x1>x2) { mreal t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; } if(y1=0 && d<=1) b[i].push_back(x1+d*(x2-x1)); } else for(int i=long(y2);i<=long(y1)+1;i++) { // mreal xx1 = x1+(x2-x1)*(i-y1)/(y2-y1); // mreal xx2 = x1+(x2-x1)*(i+1-y1)/(y2-y1); // if(xx1>xx2) { mreal t=xx1; xx1=xx2; xx2=t; } // if(xx1x2) xx2=x2; // if(i>y1 && i=xx1+1) { b[i].push_back(xx2); b[i].push_back(xx2); } // } mreal d = (i-y1)/(y2-y1); if(d>=0 && d<=1) b[i].push_back(x1+d*(x2-x1)); } } void mglCanvas::glyph_fill(mreal phi, const mglPnt &pp, mreal f, const mglGlyph &g, const mglDrawReg *d) { if(g.trig && g.nt>0) // slow but look very nice :( { const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180); mglPnt q0=pp, q1=pp, q2=pp; q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=NAN; for(long ik=0;ikx2) x2=xx; if(yyy2) y2=yy; } x1-=2; x2+=2; y1-=2; y2+=2; long w = long(x2-x1+1), h = long(y2-y1+1), il=0; long x0=long(x1), y0=long(y1),i1=1,i2=w-2,j1=1,j2=h-2; if(d) // apply mglDrawReg { if(x0+i1x1) i1 = d->x1-x0; if(x0+i2>d->x2) i2 = d->x2-x0; if(y0+j1y1) j1 = d->y1-y0; if(y0+j2>d->y2) j2 = d->y2-y0; } else { if(x0+i1<0) i1 = -x0; if(x0+i2>Width) i2 = Width-x0; if(y0+j1<0) j1 = -y0; if(y0+j2>Height)j2 = Height-y0; } if(i1>=i2 || j1>=j2) return; std::vector *b = new std::vector[h]; const float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces const int oi = d?d->ObjId:-1; unsigned char r[4]; col2int(pp,r,oi); if(r[3]) for(long i=0;ifabs(yy2-yy1)) // horizontal line { mreal d = (yy2-yy1)/(xx2-xx1), a = yy1-d*xx1+0.5; if(xx1>xx2) { mreal t=xx1; xx1=xx2; xx2=t; } for(long k=xx1;k<=xx2;k++) { long ii = long(k), jj = long(a+d*k); if(ii>=i1 && ii<=i2 && jj>=j1 && jj<=j2) pnt_plot(x0+ii,y0+jj,pp.z+dz,r,oi); } } else // vertical line { mreal d = (xx2-xx1)/(yy2-yy1), a = xx1-d*yy1+0.5; if(yy1>yy2) { mreal t=yy1; yy1=yy2; yy2=t; } for(long k=yy1;k<=yy2;k++) { long jj = long(k), ii = long(a+d*k); if(ii>=i1 && ii<=i2 && jj>=j1 && jj<=j2) pnt_plot(x0+ii,y0+jj,pp.z+dz,r,oi); } } } // TODO add smoothing -- if 3 neighbors >0 => set 1; if 3 neighbors=0 => set 0 ??? for(long j=j1;j<=j2;j++) // draw glyph { if(b[j].size()<2) continue; std::sort(b[j].begin(),b[j].end()); for(size_t k=0;ki2) ii2=i2; for(long i=ii1;i<=ii2;i++) pnt_plot(x0+i,y0+j,pp.z+dz,r,oi); } } delete []b; } //----------------------------------------------------------------------------- void mglCanvas::glyph_wire(mreal phi, const mglPnt &pp, mreal f, const mglGlyph &g, const mglDrawReg *d) { if(!g.line || g.nl<=0) return; long il=0; const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180); mglPnt q0=pp, q1=pp; q0.u=q0.v=q1.u=q1.v=NAN; mglPoint p1,p2; for(long ik=0;ik0 && i0) quad_plot(nn[j-1], nn[j], nn[j+n-1], nn[j+n]); } delete []nn; break; } } } //----------------------------------------------------------------------------- bool mglCanvas::quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const { long y1,x1,y2,x2; mglPnt d1(p2-p1), d2(p3-p1), d3(p4+p1-p2-p3); if(d1.x==0 && d1.y==0) return trig_vis(p1,p3,p4); if(d2.x==0 && d2.y==0) return trig_vis(p1,p2,p4); x1 = long(mgl_min(mgl_min(p1.x,p2.x), mgl_min(p3.x,p4.x))); // bounding box y1 = long(mgl_min(mgl_min(p1.y,p2.y), mgl_min(p3.y,p4.y))); x2 = long(mgl_max(mgl_max(p1.x,p2.x), mgl_max(p3.x,p4.x))); y2 = long(mgl_max(mgl_max(p1.y,p2.y), mgl_max(p3.y,p4.y))); x1=mgl_imax(x1,0); x2=mgl_imin(x2,Width); y1=mgl_imax(y1,0); y2=mgl_imin(y2,Height); // if(x1>x2 || y1>y2) return; const float dd = d1.x*d2.y-d1.y*d2.x; const float dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y; const float dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x; const float x0 = p1.x, y0 = p1.y; bool vis = false; for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float xx = (i-x0), yy = (j-y0), s; s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy); if(s>=0) { s = sqrt(s); float qu = d3.x*yy - d3.y*xx + dd + s; float qv = d3.y*xx - d3.x*yy + dd + s; float u = 2.f*(d2.y*xx - d2.x*yy)/qu; float v = 2.f*(d1.x*yy - d1.y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad { qu = d3.x*yy - d3.y*xx + dd - s; qv = d3.y*xx - d3.x*yy + dd - s; // u = v = -1.f; u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv; if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad } float zz = p1.z+d1.z*u+d2.z*v+d3.z*(u*v); if(zz>=Z[3*(i+Width*(Height-1-j))]-2) vis=true; } } return vis; } //----------------------------------------------------------------------------- bool mglCanvas::trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const { long y1,x1,y2,x2; const mglPnt d1(p2-p1), d2(p3-p1); const float tmp = d2.x*d1.y - d1.x*d2.y; if(fabs(tmp)<1e-5) return false; // points lies on the same line const float dyv =-d1.x/tmp, dxv = d1.y/tmp; const float dyu = d2.x/tmp, dxu =-d2.y/tmp; x1 = long(mgl_min(p1.xp2.x?p1.x:p2.x, p3.x)); y2 = long(mgl_max(p1.y>p2.y?p1.y:p2.y, p3.y)); x1=x1>0?x1:0; x2=x20?y1:0; y2=y2x2 || y1>y2) return; // default normale const float x0 = p1.x, y0 = p1.y; bool vis=false; // provide additional height to be well visible on the surfaces for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++) { float xx = (i-x0), yy = (j-y0); float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; if(u<0 || v<0 || u+v>1) continue; float zz = p1.z+d1.z*u+d2.z*v; if(zz>=Z[3*(i+Width*(Height-1-j))]-2) vis=true; } return vis; } //----------------------------------------------------------------------------- ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/data_ex.cpp������������������������������������������������������������������������0000644�0001750�0001750�00000124753�13513030041�016061� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * data_new.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "mgl2/data.h" #include "mgl2/eval.h" #include "mgl2/thread.h" #include "interp.hpp" void MGL_NO_EXPORT mgl_txt_func(const mreal *x, mreal *dx, void *par); HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector &head); //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_trace(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx); if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;ia[i] = d->v(i,i,i); else if(ny>=nx) #pragma omp parallel for for(long i=0;ia[i] = d->v(i,i); else #pragma omp parallel for for(long i=0;ia[i] = d->v(i); return r; } uintptr_t MGL_EXPORT mgl_data_trace_(uintptr_t *d) { return uintptr_t(mgl_data_trace(_DT_)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz) { if(!xx || !yy || !zz) { mglData tmp; tmp.a[0]=-1; return mgl_data_subdata_ext(d,xx?xx:&tmp,yy?yy:&tmp,zz?zz:&tmp); } long n=0,m=0,l=0,j,k; bool ix=false, iy=false, iz=false; if(xx->GetNz()>1) // 3d data { n = xx->GetNx(); m = xx->GetNy(); l = xx->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNz()>1) { n = yy->GetNx(); m = yy->GetNy(); l = yy->GetNz(); j = xx->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNz()>1) { n = zz->GetNx(); m = zz->GetNy(); l = zz->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = xx->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } else if(xx->GetNy()>1) // 2d data { n = xx->GetNx(); m = xx->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNy()>1) { n = yy->GetNx(); m = yy->GetNy(); l = 1; j = xx->GetNx()*xx->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNy()>1) { n = zz->GetNx(); m = zz->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = xx->GetNx()*xx->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); long vx=long(xx->v(0)), vy=long(yy->v(0)), vz=long(zz->v(0)); mglData *r; if(n*m*l>1) // this is 2d or 3d data { mglDataV tx(n,m,l),ty(n,m,l),tz(n,m,l); if(!ix) { xx = &tx; if(vx>=0) tx.Fill(vx); else tx.All(); } if(!iy) { yy = &ty; if(vy>=0) ty.Fill(vy); else ty.All(); } if(!iz) { zz = &tz; if(vz>=0) tz.Fill(vz); else tz.All(); } r=new mglData(n,m,l); #pragma omp parallel for for(long i0=0;i0vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x=0 && y=0 && zv(x,y,z):NAN; } } else // this is 1d data -> try as normal SubData() { mglDataV tx(nx),ty(ny),tz(nz); tx.All(); ty.All(); tz.All(); if(xx->GetNx()>1 || vx>=0) n=xx->GetNx(); else { n=nx; xx = &tx; } if(yy->GetNx()>1 || vy>=0) m=yy->GetNx(); else { m=ny; yy = &ty; } if(zz->GetNx()>1 || vz>=0) l=zz->GetNx(); else { l=nz; zz = &tz; } r=new mglData(n,m,l); #pragma omp parallel for collapse(3) for(long k=0;kv(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x=0 && y=0 && zv(x,y,z):NAN; } if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} } return r; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_subdata(HCDT d, long xx,long yy,long zz) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1; int dx=0,dy=0,dz=0; if(xx<0) { xx=0; dx=1; n=nx; } if(yy<0) { yy=0; dy=1; m=ny; } if(zz<0) { zz=0; dz=1; l=nz; } mglData *r=new mglData(n,m,l); if(xxa[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k); else #pragma omp parallel for for(long i=0;ia[i] = NAN; if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_data_subdata_(uintptr_t *d, int *xx,int *yy,int *zz) { return uintptr_t(mgl_data_subdata(_DT_,*xx,*yy,*zz)); } uintptr_t MGL_EXPORT mgl_data_subdata_ext_(uintptr_t *d, uintptr_t *xx, uintptr_t *yy, uintptr_t *zz) { return uintptr_t(mgl_data_subdata_ext(_DT_,_DA_(xx),_DA_(yy),_DA_(zz))); } //----------------------------------------------------------------------------- static void *mgl_resize(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0]+0.1, ny=t->p[1]+0.1; mreal *b=t->a; const mreal *c=t->c; HCDT dat = (HCDT)(t->v); #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0n;i0+=mglNumThr) { long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny); b[i0] = dat->value(c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]); } return 0; } HMDT MGL_EXPORT mgl_data_resize_box(HCDT dat, long mx,long my,long mz, mreal x1,mreal x2, mreal y1,mreal y2, mreal z1,mreal z2) { long nx = dat->GetNx(), ny = dat->GetNy(), nz = dat->GetNz(); mx = mx<1 ? nx:mx; my = my<1 ? ny:my; mz = mz<1 ? nz:mz; mglData *r=new mglData(mx,my,mz); mreal par[6]={nx*x1,0,ny*y1,0,nz*z1,0}; long nn[6]={mx,my,mz,nx,ny,nz}; if(mx>1) par[1] = (nx-1)*(x2-x1)/(mx-1); if(my>1) par[3] = (ny-1)*(y2-y1)/(my-1); if(mz>1) par[5] = (nz-1)*(z2-z1)/(mz-1); mglStartThread(mgl_resize,0,mx*my*mz,r->a,0,par,nn,dat); return r; } HMDT MGL_EXPORT mgl_data_resize(HCDT d, long mx,long my,long mz) { return mgl_data_resize_box(d, mx,my,mz,0,1,0,1,0,1); } uintptr_t MGL_EXPORT mgl_data_resize_(uintptr_t *d, int *mx,int *my,int *mz) { return uintptr_t(mgl_data_resize(_DT_,*mx,*my,*mz)); } uintptr_t MGL_EXPORT mgl_data_resize_box_(uintptr_t *d, int *mx,int *my,int *mz, mreal *x1,mreal *x2, mreal *y1,mreal *y2, mreal *z1,mreal *z2) { return uintptr_t(mgl_data_resize_box(_DT_,*mx,*my,*mz,*x1,*x2,*y1,*y2,*z1,*z2)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_combine(HCDT d1, HCDT d2) { long n1=d1->GetNy(),n2=d2->GetNx(),nx=d1->GetNx(); if(d1->GetNz()>1 || (n1>1 && d2->GetNy()>1) || d2->GetNz()>1) return 0; // wrong dimensions mglData *r=new mglData; bool dim2=true; if(n1==1) { n1=n2; n2=d2->GetNy(); dim2 = false; } r->Create(nx,n1,n2); if(dim2) n1*=nx; else { n2*=n1; n1=nx; } #pragma omp parallel for collapse(2) for(long j=0;ja[i+n1*j] = d1->vthr(i)*d2->vthr(j); return r; } uintptr_t MGL_EXPORT mgl_data_combine_(uintptr_t *a, uintptr_t *b) { return uintptr_t(mgl_data_combine(_DA_(a),_DA_(b))); } //----------------------------------------------------------------------------- static void *mgl_sum_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;iGetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; mreal *b = new mreal[nx*ny*nz]; mreal *c = new mreal[nx*ny*nz]; const mglData *d=dynamic_cast(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ivthr(i); if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_sum_z,0,nx*ny,b,c,0,p); memcpy(c,b,nx*ny*sizeof(mreal)); p[2] = 1; } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_sum_y,0,nx*p[2],b,c,0,p); memcpy(c,b,nx*p[2]*sizeof(mreal)); p[1] = p[2]; p[2] = 1; } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_sum_x,0,p[1]*p[2],b,c,0,p); p[0] = p[1]; p[1] = p[2]; p[2] = 1; memcpy(c,b,p[0]*p[1]*sizeof(mreal)); } mglData *r=new mglData(p[0],p[1],p[2]); memcpy(r->a,c,p[0]*p[1]*p[2]*sizeof(mreal)); delete []b; delete []c; return r; } uintptr_t MGL_EXPORT mgl_data_sum_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; uintptr_t r=uintptr_t(mgl_data_sum(_DT_,s)); delete []s; return r; } //----------------------------------------------------------------------------- static void *mgl_max_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], ny=t->p[1], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ip[0], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;iGetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; mreal *b = new mreal[nx*ny*nz]; mreal *c = new mreal[nx*ny*nz]; const mglData *d=dynamic_cast(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ivthr(i); if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_max_z,0,nx*ny,b,c,0,p); memcpy(c,b,nx*ny*sizeof(mreal)); p[2] = 1; } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_max_y,0,nx*p[2],b,c,0,p); memcpy(c,b,nx*p[2]*sizeof(mreal)); p[1] = p[2]; p[2] = 1; } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_max_x,0,p[1]*p[2],b,c,0,p); p[0] = p[1]; p[1] = p[2]; p[2] = 1; memcpy(c,b,p[0]*p[1]*sizeof(mreal)); } mglData *r=new mglData(p[0],p[1],p[2]); memcpy(r->a,c,p[0]*p[1]*p[2]*sizeof(mreal)); delete []b; delete []c; return r; } uintptr_t MGL_EXPORT mgl_data_max_dir_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; uintptr_t r=uintptr_t(mgl_data_max_dir(_DT_,s)); delete []s; return r; } //----------------------------------------------------------------------------- static void *mgl_min_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ia[i+nn*j]) b[i] = a[i+nn*j]; } return 0; } static void *mgl_min_y(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], ny=t->p[1], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ia[k+nx*j]) b[i]=a[k+nx*j]; } return 0; } static void *mgl_min_x(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ia[j+k]) b[i]=a[j+k]; } return 0; } HMDT MGL_EXPORT mgl_data_min_dir(HCDT dat, const char *dir) { if(!dir || *dir==0) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; mreal *b = new mreal[nx*ny*nz]; mreal *c = new mreal[nx*ny*nz]; const mglData *d=dynamic_cast(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ivthr(i); if(strchr(dir,'z') && nz>1) { mglStartThread(mgl_min_z,0,nx*ny,b,c,0,p); memcpy(c,b,nx*ny*sizeof(mreal)); p[2] = 1; } if(strchr(dir,'y') && ny>1) { mglStartThread(mgl_min_y,0,nx*p[2],b,c,0,p); memcpy(c,b,nx*p[2]*sizeof(mreal)); p[1] = p[2]; p[2] = 1; } if(strchr(dir,'x') && nx>1) { mglStartThread(mgl_min_x,0,p[1]*p[2],b,c,0,p); p[0] = p[1]; p[1] = p[2]; p[2] = 1; memcpy(c,b,p[0]*p[1]*sizeof(mreal)); } mglData *r=new mglData(p[0],p[1],p[2]); memcpy(r->a,c,p[0]*p[1]*p[2]*sizeof(mreal)); delete []b; delete []c; return r; } uintptr_t MGL_EXPORT mgl_data_min_dir_(uintptr_t *d, const char *dir,int l) { char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0; uintptr_t r=uintptr_t(mgl_data_min_dir(_DT_,s)); delete []s; return r; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_minmax(HCDT dat) { long n=dat->GetNx(), m=dat->GetNy(), l=dat->GetNz(); std::vector imax, jmax, kmax; HMDT res=NULL; if(n>3 && m==1 && l==1) { std::vector imax; for(long i=1;iv(i); if(v > dat->v(i-1) && v >= dat->v(i+1)) imax.push_back(i); if(v < dat->v(i-1) && v <= dat->v(i+1)) imax.push_back(i); } size_t nn = imax.size(); if(nn>0) { res = new mglData(nn); for(size_t i=0;ia[i] = imax[i]/(n-1.); } } else if(n>3 && m>3 && l==1) { std::vector imax, jmax; for(long j=1;jv(i,j); long di[] = {-1,0,1, -1,1, -1,0,1}, dj[] = {-1,-1, -1,0, 0,1,1,1}, vmax=0, vmin=0; for(int ii=0;ii<8;ii++) { mreal u = dat->v(i+di[ii],j+dj[ii]); if(mgl_isnan(u)) { vmax=vmin=0; break; } if(v < u) vmin++; if(v > u) vmax++; } if(vmin>0 && vmax==0) { imax.push_back(i); jmax.push_back(j); } if(vmax>0 && vmin==0) { imax.push_back(i); jmax.push_back(j); } } size_t nn = imax.size(); if(nn>0) { res = new mglData(2,nn); for(size_t i=0;ia[2*i] = imax[i]/(n-1.); res->a[2*i+1] = jmax[i]/(m-1.); } } } else if(n>3 && m>3 && l>3) { std::vector imax, jmax; for(long k=1;kv(i,j,k); long di[] = {-1,0,1,-1,0,1,-1,0,1, -1,0,1,-1,1,-1,0,1, -1,0,1,-1,0,1,-1,0,1}; long dj[] = {-1,-1,-1,0,0,0,1,1,1, -1,-1,-1,0,0,1,1,1, -1,-1,-1,0,0,0,1,1,1}; long dk[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1}, vmax=0, vmin=0; for(int ii=0;ii<26;ii++) { mreal u = dat->v(i+di[ii],j+dj[ii],k+dk[ii]); if(mgl_isnan(u)) { vmax=vmin=0; break; } if(v < u) vmin++; if(v > u) vmax++; } if(vmin>0 && vmax==0) { imax.push_back(i); jmax.push_back(j); kmax.push_back(k); } if(vmax>0 && vmin==0) { imax.push_back(i); jmax.push_back(j); kmax.push_back(k); } } size_t nn = imax.size(); if(nn>0) { res = new mglData(3,nn); for(size_t i=0;ia[3*i] = imax[i]/(n-1.); res->a[3*i+1] = jmax[i]/(m-1.); res->a[3*i+2] = kmax[i]/(l-1.); } } } return res; } uintptr_t MGL_EXPORT mgl_data_minmax_(uintptr_t *d) { return uintptr_t(mgl_data_minmax(_DT_)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how) { if(!how || !(*how) || !strchr("xyz",dir)) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); mglDataV x(nx,ny,nz, 0,1,'x'); x.Name(L"x"); mglDataV y(nx,ny,nz, 0,1,'y'); y.Name(L"y"); mglDataV z(nx,ny,nz, 0,1,'z'); z.Name(L"z"); mglData u(dat); u.Name(L"u"); // NOTE slow !!! std::vector list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&u); HMDT res=mglFormulaCalc(how,list), b=0; if(dir=='x') { b=new mglData(nx); #pragma omp parallel for for(long i=0;ivthr(i+nx*j); i0 += u; i1 += u*res->a[i+nx*j]; } b->a[i] = i0>0 ? i1/i0 : 0; } } if(dir=='y') { b=new mglData(ny); #pragma omp parallel for for(long i=0;iv(j,i,k); i0 += u; i1 += u*res->a[j+nx*(i+ny*k)]; } b->a[i] = i0>0 ? i1/i0 : 0; } } if(dir=='z') { long nn=nx*ny; b=new mglData(nz); #pragma omp parallel for for(long i=0;ivthr(j+nn*i); i0 += u; i1 += u*res->a[j+nn*i]; } b->a[i] = i0>0 ? i1/i0 : 0; } } mgl_delete_data(res); return b; } uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *d, char *dir, const char *how, int,int l) { char *s=new char[l+1]; memcpy(s,how,l); s[l]=0; uintptr_t r=uintptr_t(mgl_data_momentum(_DT_,*dir, s)); delete []s; return r; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_mul_dat(HMDT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); if(mz==1 && my==1 && mx==1) { mreal v=a->v(0); #pragma omp parallel for collapse(3) for(long k=0;ka[i+nx*(j+ny*k)] *= v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] *= a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_mul_num(HMDT d, mreal a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] *= a; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_div_dat(HMDT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); if(mz==1 && my==1 && mx==1) { mreal v=a->v(0); #pragma omp parallel for collapse(3) for(long k=0;ka[i+nx*(j+ny*k)] /= v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] /= a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_div_num(HMDT d, mreal a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] /= a; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_add_dat(HMDT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); if(mz==1 && my==1 && mx==1) { mreal v=a->v(0); #pragma omp parallel for collapse(3) for(long k=0;ka[i+nx*(j+ny*k)] += v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] += a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_add_num(HMDT d, mreal a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] += a; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_sub_dat(HMDT d, HCDT a) { long nx=d->nx, ny=d->ny, nz=d->nz; long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz(); if(mz==1 && my==1 && mx==1) { mreal v=a->v(0); #pragma omp parallel for collapse(3) for(long k=0;ka[i+nx*(j+ny*k)] -= v; } else { long n=0, m=0; if(nz*ny*nx==mz*my*mx) { n=nx*ny*nz; m=1; } else if(ny*nx==my*mx) { n=nx*ny; m=nz; } else if(nx==mx) { n=nx; m=ny*nz; } #pragma omp parallel for collapse(2) for(long k=0;ka[i+n*k] -= a->vthr(i); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_sub_num(HMDT d, mreal a) { long n=d->GetNN(); #pragma omp parallel for for(long i=0;ia[i] -= a; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_mul_dat_(uintptr_t *d, uintptr_t *b) { mgl_data_mul_dat(_DT_, _DA_(b)); } void MGL_EXPORT mgl_data_div_dat_(uintptr_t *d, uintptr_t *b) { mgl_data_div_dat(_DT_, _DA_(b)); } void MGL_EXPORT mgl_data_add_dat_(uintptr_t *d, uintptr_t *b) { mgl_data_add_dat(_DT_, _DA_(b)); } void MGL_EXPORT mgl_data_sub_dat_(uintptr_t *d, uintptr_t *b) { mgl_data_sub_dat(_DT_, _DA_(b)); } void MGL_EXPORT mgl_data_mul_num_(uintptr_t *d, mreal *b) { mgl_data_mul_num(_DT_, *b); } void MGL_EXPORT mgl_data_div_num_(uintptr_t *d, mreal *b) { mgl_data_div_num(_DT_, *b); } void MGL_EXPORT mgl_data_add_num_(uintptr_t *d, mreal *b) { mgl_data_add_num(_DT_, *b); } void MGL_EXPORT mgl_data_sub_num_(uintptr_t *d, mreal *b) { mgl_data_sub_num(_DT_, *b); } //----------------------------------------------------------------------------- void static mgl_hist_p(mglThreadD *t,mreal *a) { long n=t[0].p[0]; memset(a,0,n*sizeof(mreal)); #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=0;in, n = t->p[0]; mreal *b=new mreal[n]; memset(b,0,n*sizeof(mreal)); HCDT a = (HCDT)(t->b), c = (HCDT)(t->c); const mreal *v=(const mreal *)t->v; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ivthr(i)-v[0])/(v[1]-v[0])); if(k>=0 && kvthr(i):1.; } t->a = b; return 0; } static void *mgl_hist_2(void *par) { mglThreadD *t=(mglThreadD *)par; long nn=t->n, n = t->p[0]; long ns=t->p[1], nx=t->p[2], ny=t->p[3]; mreal *b=new mreal[n], d=1./ns; memset(b,0,n*sizeof(mreal)); HCDT a = (HCDT)(t->b), c = (HCDT)(t->c); const mreal *v=(const mreal *)t->v; bool sp = n>0; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;ivalue(x,y,z) : a->linear(x,y,z), w=1; if(c) w = sp ? c->value(x,y,z) : c->linear(x,y,z); if(mgl_isnan(f) || mgl_isnan(w)) continue; long k = long(n*(f-v[0])/(v[1]-v[0])); if(k>=0 && ka = b; return 0; } HMDT MGL_EXPORT mgl_data_hist(HCDT dat, long n, mreal v1, mreal v2, long nsub) { if(n<2 || v1==v2) return 0; mglData *b=new mglData(n); mreal v[2]={v1,v2}; long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz(); long ns=labs(nsub)+1, p[5]={n,ns,nx,ny,nz}; if(nsub==0) mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,(const mreal *)dat,0,p,v); else mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,(const mreal *)dat,0,p,v); return b; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_hist_w(HCDT dat, HCDT weight, long n, mreal v1, mreal v2, long nsub) { if(n<2 || v1==v2) return 0; mglData *b=new mglData(n); mreal v[2]={v1,v2}; long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz(); long ns=labs(nsub)+1, p[5]={n,ns,nx,ny,nz}; if(nsub==0) mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,(const mreal *)dat,(const mreal *)weight,p,v); else mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,(const mreal *)dat,(const mreal *)weight,p,v); return b; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_data_hist_(uintptr_t *d, int *n, mreal *v1, mreal *v2, int *nsub) { return uintptr_t(mgl_data_hist(_DT_,*n,*v1,*v2,*nsub)); } uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *d, uintptr_t *w, int *n, mreal *v1, mreal *v2, int *nsub) { return uintptr_t(mgl_data_hist_w(_DT_,_DA_(w),*n,*v1,*v2,*nsub)); } //----------------------------------------------------------------------------- long MGL_NO_EXPORT mgl_idx_var; int MGL_LOCAL_PURE mgl_cmd_idx(const void *a, const void *b) { mreal *aa = (mreal *)a, *bb = (mreal *)b; return (aa[mgl_idx_var]>bb[mgl_idx_var] ? 1:(aa[mgl_idx_var](dat); if(!d || idx>=d->nx || idx<0) return; bool single = (d->nz==1 || idy<0); if(idy<0 || idy>d->ny) idy=0; mgl_idx_var = idx+d->nx*idy; // NOTE: not thread safe!!! if(single) qsort(d->a, d->ny*d->nz, d->nx*sizeof(mreal), mgl_cmd_idx); else qsort(d->a, d->nz, d->ny*d->nx*sizeof(mreal), mgl_cmd_idx); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_sort_(uintptr_t *d, int *idx, int *idy) { mgl_data_sort(_DT_,*idx,*idy); } //----------------------------------------------------------------------------- // // Find roots series // // //----------------------------------------------------------------------------- #if MGL_HAVE_GSL #include struct mglRoots { mreal *x, *f; size_t n; void (*func)(const mreal *x, mreal *f, void *par); void *par; }; int static mgl_root(const gsl_vector *x, void *params, gsl_vector *f) { mglRoots *p = (mglRoots *)params; for(size_t i=0;in;i++) p->x[i] = gsl_vector_get (x, i); p->func(p->x,p->f,p->par); bool ok = true; for(size_t i=0;in;i++) { gsl_vector_set (f, i, p->f[i]); if(mgl_isbad(p->f[i])) ok=false; } return ok?GSL_SUCCESS:GSL_FAILURE; } bool MGL_EXPORT mgl_find_roots(size_t n, void (*func)(const mreal *x, mreal *f, void *par), mreal *x0, void *par) { for(size_t i=0;if, 1e-7); } for(size_t i=0;ix, i); gsl_multiroot_fsolver_free(s); gsl_vector_free(x); delete []y; return status==GSL_SUCCESS; } #else bool MGL_EXPORT mgl_find_roots(size_t , void (*)(const mreal *, mreal *, void *), mreal *, void *) { return false; } #endif // MGL_HAVE_GSL //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_find_roots_txt(const char *func, const char *vars, HCDT ini) { if(!vars || !(*vars) || !func || !ini) return 0; mglEqTxT par; par.var=vars; par.FillReal(func); size_t n = par.str.size(); if(ini->GetNx()!=long(n)) return 0; mreal *xx = new mreal[n]; mglData *res = new mglData(ini); for(long j=0;jGetNy()*ini->GetNz();j++) { for(size_t i=0;ivthr(i+n*j); bool ok=mgl_find_roots(n,mgl_txt_func,xx,&par); for(size_t i=0;ia[i+n*j] = ok?xx[i]:NAN; } delete []xx; return res; } uintptr_t MGL_EXPORT mgl_find_roots_txt_(const char *func, const char *vars, uintptr_t *ini,int l,int m) { char *s=new char[l+1]; memcpy(s,func,l); s[l]=0; char *v=new char[m+1]; memcpy(v,vars,m); v[m]=0; uintptr_t r = uintptr_t(mgl_find_roots_txt(s,v,_DA_(ini))); delete []s; delete []v; return r; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_find_root(mreal (*func)(mreal x, void *par), mreal x0, void *par) { mreal x1=x0+1e-2*(x0?x0:1), f0=func(x0,par), f1=func(x1,par), x, f; if(fabs(f0)<1e-7) return x0; if(fabs(f1)<1e-7) return x1; if(f0==f1) return NAN; for(long i=0;i<20;i++) { x = x1-f1*(x1-x0)/(f1-f0); f = func(x,par); if(fabs(f)<1e-7) return x; /* if(fabs(f-f1)>0.5*mgl_min(fabs(f),fabs(f1))) // TODO switch to bisection if slow { x = (x1+x0)/2; f = func(x,par); if(fabs(f)<1e-7) return x; }*/ x0=x1; f0=f1; x1=x; f1=f; // new points } return NAN; // no roots found } //----------------------------------------------------------------------------- struct MGL_NO_EXPORT mglFuncV { mglFormula *eq; char var; }; mreal static mgl_funcv(mreal v, void *par) { mglFuncV *f = (mglFuncV *)par; mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal)); var[f->var-'a'] = v; return f->eq->Calc(var); } HMDT MGL_EXPORT mgl_data_roots(const char *func, HCDT ini, char var) { if(!ini) return 0; mglData *res = new mglData(ini); mglFormula eq(func); mglFuncV f; f.eq = &eq; f.var = var; long n = res->nx*res->ny*res->nz; #pragma omp parallel for for(long i=0;ia[i] = mgl_find_root(mgl_funcv,res->a[i],&f); return res; } //----------------------------------------------------------------------------- mreal MGL_EXPORT mgl_find_root_txt(const char *func, mreal ini, char var) { mglFormula eq(func); mglFuncV f; f.eq = &eq; f.var = var; return mgl_find_root(mgl_funcv,ini,&f); } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_data_roots_(const char *func, uintptr_t *ini, const char *var,int l,int) { char *s=new char[l+1]; memcpy(s,func,l); s[l]=0; uintptr_t r = uintptr_t(mgl_data_roots(s,_DA_(ini),*var)); delete []s; return r; } mreal MGL_EXPORT mgl_find_root_txt_(const char *func, mreal *ini, const char *var,int l,int) { char *s=new char[l+1]; memcpy(s,func,l); s[l]=0; mreal r = mgl_find_root_txt(s,*ini,*var); delete []s; return r; } //----------------------------------------------------------------------------- static void *mgl_pulse_z(void *par) { mglThreadD *t=(mglThreadD *)par; long nz=t->p[2], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;i0 && j00;j--) { long i0=i+nn*j; if((a[i0]-C)*(a[i0-nn]-C)<0) j1 = j - (a[i0]-C)/(a[i0]-a[i0-nn]); } b[i+3*nn]=j2-j1; b[i+4*nn]=0; if(j2>j1) for(long j = j1;j<=j2;j++) b[i+4*nn] += a[i+nn*j]; } else // maximum at the edges { b[i]=m; b[i+nn]=j0; b[i+2*nn]=b[i+3*nn]=b[i+4*nn]=NAN; } } return 0; } static void *mgl_pulse_y(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], ny=t->p[1], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;i0 && j00;j--) { long i0=k+nx*j; if((a[i0]-C)*(a[i0-nx]-C)<0) j1 = j - (a[i0]-C)/(a[i0]-a[i0-nx]); } b[ki+3*nx]=j2-j1; b[ki+4*nx]=0; if(j2>j1) for(long j = j1;j<=j2;j++) b[ki+4*nx] += a[k+nx*j]; } else // maximum at the edges { b[ki]=m; b[ki+nx]=j0; b[ki+2*nx]=b[ki+3*nx]=b[ki+4*nx]=NAN; } } return 0; } static void *mgl_pulse_x(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0], nn=t->n; mreal *b=t->a; const mreal *a=t->b; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i=t->id;i0 && j00;j--) { long i0=j+k; if((a[i0]-C)*(a[i0-1]-C)<0) j1 = j - (a[i0]-C)/(a[i0]-a[i0-1]); } b[5*i+3]=j2-j1; b[5*i+4]=0; if(j2>j1) for(long j = j1;j<=j2;j++) b[5*i+4] += a[j+k]; } else // maximum at the edges { b[5*i]=m; b[5*i+1]=j0; b[5*i+2]=b[5*i+3]=b[5*i+4]=NAN; } } return 0; } HMDT MGL_EXPORT mgl_data_pulse(HCDT dat, char dir) { // if(!dir || *dir==0) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; mreal *c = new mreal[nx*ny*nz], *b=0; const mglData *d=dynamic_cast(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(mreal)); else #pragma omp parallel for for(long i=0;ivthr(i); if(dir=='z' && nz>1) { b = new mreal[nx*ny*5]; mglStartThread(mgl_pulse_z,0,nx*ny,b,c,0,p); p[2] = 5; } else if(dir=='y' && ny>1) { b = new mreal[5*nx*nz]; mglStartThread(mgl_pulse_y,0,nx*p[2],b,c,0,p); p[1] = 5; } else if(dir=='x' && nx>1) { b = new mreal[5*ny*nz]; mglStartThread(mgl_pulse_x,0,p[1]*p[2],b,c,0,p); p[0] = 5; } mglData *r=0; if(b) { r=new mglData(p[0],p[1],p[2]); memcpy(r->a,b,p[0]*p[1]*p[2]*sizeof(mreal)); delete []b; } delete []c; return r; } uintptr_t MGL_EXPORT mgl_data_pulse_(uintptr_t *d, const char *dir,int) { return uintptr_t(mgl_data_pulse(_DT_,dir[0])); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_section(HCDT dat, HCDT ids, char dir, mreal val) { long di = 1, n = dat->GetNx(); if(dir=='y') { di = dat->GetNx(); n = dat->GetNy(); } if(dir=='z') { di = dat->GetNx()*dat->GetNy(); n = dat->GetNz(); } // first collect position of key values std::vector pos; pos.push_back(0); if(mgl_isnan(val)) for(long i=1;ivthr(i*di))) pos.push_back(i); } else for(long i=0;ivthr(i*di)==val) pos.push_back(i); } pos.push_back(n); // add last point (size of data) // now collect required position from section and its lengths std::vector ls, ps; long np = pos.size()-1, nl=0; if(np<1) return NULL; // nothing to do for(long i=0;iGetNN();i++) { long j = mgl_int(ids->vthr(i)+0.5); j = j<0?np+j:j; if(j>=0 && jGetNx(), nz=dat->GetNz(), sh=0; r = new mglData(nx,nl,nz); for(size_t s=0;sa[i+nx*(sh+j+nl*k)] = dat->v(i,pp+j,k); sh += ls[s]; } } else if(dir=='x') { long ny=dat->GetNy(), nz=dat->GetNz(), sh=0; r = new mglData(nl,ny,nz); for(size_t s=0;sa[sh+i+nl*(j+ny*k)] = dat->v(pp+i,j,k); sh += ls[s]; } } else if(dir=='z') { long nx=dat->GetNx(), ny=dat->GetNy(), sh=0; r = new mglData(nx,ny,nl); for(size_t s=0;sa[i+nx*(j+ny*(sh+k))] = dat->v(i,j,pp+k); sh += ls[s]; } } return r; } HMDT MGL_EXPORT mgl_data_section_val(HCDT dat, long id, char dir, mreal val) { mglData v; v.a[0]=id; return mgl_data_section(dat,&v,dir,val); } uintptr_t MGL_EXPORT mgl_data_section_(uintptr_t *d, uintptr_t *ids, const char *dir, mreal *val,int) { return uintptr_t(mgl_data_section(_DT_,_DA_(ids),dir[0],*val)); } uintptr_t MGL_EXPORT mgl_data_section_val_(uintptr_t *d, int *id, const char *dir, mreal *val,int) { return uintptr_t(mgl_data_section_val(_DT_,*id,dir[0],*val)); } //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_closest(mreal *res, long n, long i0, long i1, HCDT a, HCDT b) { mreal *rr = new mreal[n*n]; for(long k0=0;k0vthr(k0+i0)-a->vthr(k1+i1), b->vthr(k0+i0)-b->vthr(k1+i1)); std::set ids, idk; for(long k=0;k=0) { for(long i=0;iGetNx(), ny = a->GetNy(), nz = a->GetNz(); HMDT res = new mglData(nx,ny,nz); for(long j=0;ja[i+nx*j] = i; for(long j=0;j0) { long i0 = nx*(ny-1+ny*j); mgl_closest(res->a, nx, i0, i0-nx*ny, a, b); } for(long i=ny-1;i>0;i--) // TODO optimized for QHCU_dh case only!!! { long i0 = nx*(i+ny*j); mgl_closest(res->a, nx, i0-nx, i0, a, b); } } return res; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_data_connect_(uintptr_t *a, uintptr_t *b) { return uintptr_t(mgl_data_connect(_DA_(a),_DA_(b))); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_connect_r(HMDT a, HMDT b) { int nx = a->GetNx(), ny = a->GetNy(), nz = a->GetNz(); HMDT res = mgl_data_connect(a,b); mreal *buf = new mreal[2*nx]; for(long j=0;ja+i0,nx*sizeof(mreal)); memcpy(buf+nx,b->a+i0,nx*sizeof(mreal)); for(long i=0;ia[i0+i]; a->a[i0+i1] = buf[i]; b->a[i0+i1] = buf[i+nx]; } } delete []buf; delete res; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_connect_r_(uintptr_t *a, uintptr_t *b) { mgl_data_connect_r(_DM_(a),_DM_(b)); } //----------------------------------------------------------------------------- ���������������������mathgl-2.4.4/src/exec_set.cpp�����������������������������������������������������������������������0000644�0001750�0001750�00000107556�13513030041�016255� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * exec_set.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef WIN32 #include #include #else #include #endif #include "mgl2/base.h" #include "mgl2/parser.h" //#pragma GCC diagnostic ignored "-Wmisleading-indentation" wchar_t *mgl_str_copy(const char *s); //----------------------------------------------------------------------------- int static mgls_addlegend(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"ss")) gr->AddLegend(a[0].s.w,a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_addsymbol(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"sdd")) gr->DefineSymbol(a[0].s[0],*(a[1].d),*(a[2].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_adjust(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->Adjust(); else if(!strcmp(k,"s")) gr->Adjust(a[0].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_alpha(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->Alpha(true); else if(!strcmp(k,"n")) gr->Alpha(a[0].v!=0); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_alphadef(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetAlphaDef(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ambient(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetAmbient(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_arrowsize(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetArrowSize(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_aspect(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->Aspect(a[0].v, a[1].v, 1); else if(!strcmp(k,"nnn")) gr->Aspect(a[0].v, a[1].v, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_attachlight(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->AttachLight(a[0].v!=0); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_axisstl(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->SetAxisStl(); else if(!strcmp(k,"s")) gr->SetAxisStl(a[0].s.s); else if(!strcmp(k,"ss")) gr->SetAxisStl(a[0].s.s, a[1].s.s); else if(!strcmp(k,"sss")) gr->SetAxisStl(a[0].s.s, a[1].s.s, a[2].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_barwidth(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetBarWidth(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_bbox(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn") && a[1].v>=0 && a[0].v>=0) gr->SetBBox(mgl_int(a[0].v), mgl_int(a[1].v)); else if(!strcmp(k,"nnnn")) gr->SetBBox(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), mgl_int(a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_chdir(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) { if(chdir(a[0].s.s)) gr->SetWarn(mglWarnFile,"chdir"); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_clearlegend(mglGraph *gr, long , mglArg *, const char *k, const char *) { int res=0; if(k[0]==0) gr->ClearLegend(); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_clf(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->Clf(); else if(!strcmp(k,"s")) gr->Clf(a[0].s.s); else if(!strcmp(k,"nnn")) gr->Clf(a[0].v,a[1].v,a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_columnplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->ColumnPlot(mgl_int(a[0].v), mgl_int(a[1].v)); else if(!strcmp(k,"nnn")) gr->ColumnPlot(mgl_int(a[0].v), mgl_int(a[1].v), a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_crange(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) gr->SetRange('c',*(a[0].d)); else if(!strcmp(k,"dn")) gr->SetRange('c',*(a[0].d),a[1].v); else if(!strcmp(k,"nn")) gr->SetRange('c', a[0].v, a[1].v); else if(!strcmp(k,"nnn")) { if(a[2].v) gr->AddRange('c', a[0].v, a[1].v); else gr->SetRange('c', a[0].v, a[1].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ctick(mglGraph *gr, long n, mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) gr->SetTickTempl('c',a[0].s.w); else if(!strcmp(k,"n")) gr->SetTicks('c',a[0].v,0,0); else if(!strcmp(k,"ns")) gr->SetTicks('c',a[0].v,0,0,a[1].s.w); else if(!strcmp(k,"ds")) gr->SetTicksVal('c', *(a[0].d), a[1].s.w); else if(!strcmp(k,"dsn")) gr->SetTicksVal('c', *(a[0].d), a[1].s.w, a[2].v); else if(!strncmp(k,"ns",2)) { std::wstring s; std::vector v; for(long i=0;iSetTicksVal('c',mglDataS(v),s.c_str(),v.size()==1?true:false); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_cut(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetCut(a[0].v != 0); else if(!strcmp(k,"nnnnnn")) gr->SetCutBox(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v)); else if(!strcmp(k,"s")) gr->CutOff(a[0].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_diffuse(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetDiffuse(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_drawreg(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->SetDrawReg(); else if(!strcmp(k,"nnn")) gr->SetDrawReg(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_facenum(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetFaceNum(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_fog(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->Fog(a[0].v); else if(!strcmp(k,"nn")) gr->Fog(a[0].v,a[1].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_font(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) gr->SetFontDef(a[0].s.s); else if(!strcmp(k,"sn")) { gr->SetFontDef(a[0].s.s); gr->SetFontSize(a[1].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_gray(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->Gray(true); else if(!strcmp(k,"n")) gr->Gray(a[0].v!=0); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_gridplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnn")) gr->GridPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v)); else if(!strcmp(k,"nnnn")) gr->GridPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), a[3].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_inplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnn")) gr->InPlot(a[0].v, a[1].v, a[2].v, a[3].v); else if(!strcmp(k,"nnnnn")) gr->InPlot(a[0].v, a[1].v, a[2].v, a[3].v, a[4].v!=0); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_legendmarks(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetLegendMarks(mgl_int(a[0].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_light(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->Light(true); else if(!strcmp(k,"n")) gr->Light(a[0].v!=0); else if(!strcmp(k,"nn")) gr->Light(mgl_int(a[0].v),a[1].v!=0); else if(!strcmp(k,"nnnn")) gr->AddLight(mgl_int(a[0].v),mglPoint(a[1].v,a[2].v,a[3].v)); else if(!strcmp(k,"nnnns")) gr->AddLight(mgl_int(a[0].v),mglPoint(a[1].v,a[2].v,a[3].v), a[4].s.s[0]); else if(!strcmp(k,"nnnnsn"))gr->AddLight(mgl_int(a[0].v),mglPoint(a[1].v,a[2].v,a[3].v), a[4].s.s[0],a[5].v); else if(!strcmp(k,"nnnnsnn")) gr->AddLight(mgl_int(a[0].v), mglPoint(a[1].v,a[2].v,a[3].v), a[4].s.s[0],a[5].v,a[6].v); else if(!strcmp(k,"nnnnnnn")) gr->AddLight(mgl_int(a[0].v), mglPoint(a[1].v,a[2].v,a[3].v), mglPoint(a[4].v,a[5].v,a[6].v)); else if(!strcmp(k,"nnnnnnns")) gr->AddLight(mgl_int(a[0].v), mglPoint(a[1].v,a[2].v,a[3].v), mglPoint(a[4].v,a[5].v,a[6].v), a[7].s.s[0]); else if(!strcmp(k,"nnnnnnnsn")) gr->AddLight(mgl_int(a[0].v), mglPoint(a[1].v,a[2].v,a[3].v), mglPoint(a[4].v,a[5].v,a[6].v), a[7].s.s[0],a[8].v); else if(!strcmp(k,"nnnnnnnsnn")) gr->AddLight(mgl_int(a[0].v), mglPoint(a[1].v,a[2].v,a[3].v), mglPoint(a[4].v,a[5].v,a[6].v), a[7].s.s[0],a[8].v,a[9].v); return res; } //----------------------------------------------------------------------------- int static mgls_load(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s") && gr->pr) mgl_parser_load(gr->pr, a[0].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_loadfont(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0 || (!strcmp(k,"s") && a[0].s[0]==0)) gr->RestoreFont(); else if(!strcmp(k,"s")) gr->LoadFont(a[0].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_marksize(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetMarkSize(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_mask(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"sn")) gr->SetMask(a[0].s[0],a[1].v); else if(!strcmp(k,"ss")) gr->SetMask(a[0].s[0],a[1].s.s); else if(!strcmp(k,"snn")) { gr->SetMask(a[0].s[0],a[1].v); gr->SetMaskAngle(mgl_int(a[2].v)); } else if(!strcmp(k,"ssn")) { gr->SetMask(a[0].s[0],a[1].s.s);gr->SetMaskAngle(mgl_int(a[2].v)); } else if(!strcmp(k,"n")) gr->SetMaskAngle(mgl_int(a[0].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_meshnum(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetMeshNum(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_multiplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnnn")) gr->MultiPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), mgl_int(a[3].v), mgl_int(a[4].v)); else if(!strcmp(k,"nnnnns")) gr->MultiPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), mgl_int(a[3].v), mgl_int(a[4].v), a[5].s.s); else if(!strcmp(k,"nnnnnsnn")) gr->MultiPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), mgl_int(a[3].v), mgl_int(a[4].v), a[5].s.s, a[6].v,a[7].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_origin(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->SetOrigin(a[0].v,a[1].v,NAN); else if(!strcmp(k,"nnn")) gr->SetOrigin(a[0].v,a[1].v,a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_origintick(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetOriginTick(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_palette(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) gr->SetPalette(a[0].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_pendelta(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetPenDelta(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_perspective(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->Perspective(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_plotid(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) gr->SetPlotId(a[1].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_quality(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->SetQuality(); else if(!strcmp(k,"n")) gr->SetQuality(mgl_int(a[0].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ranges(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnn")) gr->SetRanges(a[0].v,a[1].v, a[2].v,a[3].v); else if(!strcmp(k,"nnnnnn"))gr->SetRanges(a[0].v,a[1].v,a[2].v, a[3].v,a[4].v,a[5].v); else if(!strcmp(k,"dd")) gr->SetRanges(*(a[0].d),*(a[1].d)); else if(!strcmp(k,"ddd")) gr->SetRanges(*(a[0].d),*(a[1].d), *(a[2].d)); else if(!strcmp(k,"dddd")) gr->SetRanges(*(a[0].d),*(a[1].d), *(a[2].d),*(a[3].d)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_rasterize(mglGraph *gr, long , mglArg *, const char *, const char *) { gr->Rasterize(); return 0; } //----------------------------------------------------------------------------- int static mgls_reset(mglGraph *gr, long , mglArg *, const char *k, const char *) { int res=0; if(k[0]==0) gr->DefaultPlotParam(); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_rotate(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->Rotate(a[0].v, a[1].v, 0); else if(!strcmp(k,"nnn")) gr->Rotate(a[0].v, a[1].v, a[2].v); else if(!strcmp(k,"nnnn")) gr->RotateN(a[0].v, a[1].v, a[2].v, a[3].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_rotatetext(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetRotatedText(a[0].v!=0); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_scaletext(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetScaleText(a[0].v!=0); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_setsize(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn") && a[1].v>1 && a[0].v>1) gr->SetSize(mgl_int(a[0].v), mgl_int(a[1].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_setsizescl(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetSizeScl(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_setup(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->SetFlagAdv(mgl_int(a[0].v), mgl_int(a[1].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_shear(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->Shear(a[0].v, a[1].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_shearplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnn")) gr->ShearPlot(mgl_int(a[0].v), mgl_int(a[1].v), a[2].v, a[3].v); else if(!strcmp(k,"nnnnnn")) gr->ShearPlot(mgl_int(a[0].v), mgl_int(a[1].v), a[2].v, a[3].v, a[4].v, a[5].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_stickplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnn")) gr->StickPlot(mgl_int(a[0].v), mgl_int(a[1].v), a[2].v, a[3].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_subplot(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnn")) gr->SubPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v)); else if(!strcmp(k,"nnns")) gr->SubPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), a[3].s.s); else if(!strcmp(k,"nnnsnn")) gr->SubPlot(mgl_int(a[0].v), mgl_int(a[1].v), mgl_int(a[2].v), a[3].s.s, a[4].v,a[5].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ternary(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->Ternary(int(a[0].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ticklen(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTickLen(a[0].v); else if(!strcmp(k,"nn")) gr->SetTickLen(a[0].v, a[1].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tickshift(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTickShift(mglPoint(a[0].v)); else if(!strcmp(k,"nn")) gr->SetTickShift(mglPoint(a[0].v, a[1].v)); else if(!strcmp(k,"nnn")) gr->SetTickShift(mglPoint(a[0].v, a[1].v, a[2].v)); else if(!strcmp(k,"nnnn")) gr->SetTickShift(mglPoint(a[0].v, a[1].v, a[2].v, a[3].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ticktime(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"s")) gr->SetTicksTime(a[0].s[0]); else if(!strcmp(k,"sn")) gr->SetTicksTime(a[0].s[0],a[1].v); else if(!strcmp(k,"sns")) gr->SetTicksTime(a[0].s[0],a[1].v,a[2].s.s); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_transptype(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTranspType(a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_tuneticks(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTuneTicks(mgl_int(a[0].v)); else if(!strcmp(k,"nn")) gr->SetTuneTicks(mgl_int(a[0].v),a[1].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_variant(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n") && gr->pr) mgl_parser_variant(gr->pr, a[0].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_version(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; char buf[32]; sprintf(buf,"MathGL version is 2.%g",MGL_VER2); if(k[0]==0) gr->SetWarn(-1,buf); else if(!strcmp(k,"s")) res = mgl_check_version(a[0].s.s)?1:0; else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_view(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->View(a[0].v, a[1].v); else if(!strcmp(k,"nnn")) gr->View(a[0].v, a[1].v, a[2].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_write(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(k[0]==0) gr->WriteFrame("", "MathGL"); else if(!strcmp(k,"s")) gr->WriteFrame(a[0].s.s, "MathGL"); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_xrange(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) gr->SetRange('x',*(a[0].d)); else if(!strcmp(k,"dn")) gr->SetRange('x',*(a[0].d),a[1].v); else if(!strcmp(k,"nn")) gr->SetRange('x', a[0].v, a[1].v); else if(!strcmp(k,"nnn")) { if(a[2].v) gr->AddRange('x', a[0].v, a[1].v); else gr->SetRange('x', a[0].v, a[1].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_xtick(mglGraph *gr, long n, mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTicks('x', a[0].v); // else if(!strcmp(k,"ns")) gr->SetTicks('x', a[0].v, 0, NAN, a[1].s.w); else if(!strcmp(k,"nn")) gr->SetTicks('x', a[0].v, mgl_int(a[1].v)); else if(!strcmp(k,"nns")) gr->SetTicks('x', a[0].v, mgl_int(a[1].v), NAN, a[2].s.w); else if(!strcmp(k,"nnn")) gr->SetTicks('x', a[0].v, mgl_int(a[1].v), a[2].v); else if(!strcmp(k,"nnns")) gr->SetTicks('x', a[0].v, mgl_int(a[1].v), a[2].v, a[3].s.w); else if(!strcmp(k,"s")) gr->SetTickTempl('x',a[0].s.w); else if(!strcmp(k,"ds")) gr->SetTicksVal('x', *(a[0].d), a[1].s.w); else if(!strcmp(k,"dsn")) gr->SetTicksVal('x', *(a[0].d), a[1].s.w, a[2].v); else if(!strncmp(k,"ns",2)) { std::wstring s; std::vector v; for(long i=0;iSetTicksVal('x',mglDataS(v),s.c_str(),v.size()==1?true:false); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_yrange(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) gr->SetRange('y',*(a[0].d)); else if(!strcmp(k,"dn")) gr->SetRange('y',*(a[0].d),a[1].v); else if(!strcmp(k,"nn")) gr->SetRange('y', a[0].v, a[1].v); else if(!strcmp(k,"nnn")) { if(a[2].v) gr->AddRange('y', a[0].v, a[1].v); else gr->SetRange('y', a[0].v, a[1].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ytick(mglGraph *gr, long n, mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTicks('y', a[0].v); // else if(!strcmp(k,"ns")) gr->SetTicks('y', a[0].v, 0, NAN, a[1].s.w); else if(!strcmp(k,"nn")) gr->SetTicks('y', a[0].v, mgl_int(a[1].v)); else if(!strcmp(k,"nns")) gr->SetTicks('y', a[0].v, mgl_int(a[1].v), NAN, a[2].s.w); else if(!strcmp(k,"nnn")) gr->SetTicks('y', a[0].v, mgl_int(a[1].v), a[2].v); else if(!strcmp(k,"nnns")) gr->SetTicks('y', a[0].v, mgl_int(a[1].v), a[2].v, a[3].s.w); else if(!strcmp(k,"s")) gr->SetTickTempl('y',a[0].s.w); else if(!strcmp(k,"ds")) gr->SetTicksVal('y', *(a[0].d), a[1].s.w); else if(!strcmp(k,"dsn")) gr->SetTicksVal('y', *(a[0].d), a[1].s.w, a[2].v); else if(!strncmp(k,"ns",2)) { std::wstring s; std::vector v; for(long i=0;iSetTicksVal('y',mglDataS(v),s.c_str(),v.size()==1?true:false); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_zoom(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nnnn")) gr->Zoom(a[0].v, a[1].v, a[2].v, a[3].v); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_zoomaxis(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"nn")) gr->ZoomAxis(mglPoint(a[0].v), mglPoint(a[1].v)); else if(!strcmp(k,"nnnn")) gr->ZoomAxis(mglPoint(a[0].v, a[1].v), mglPoint(a[2].v, a[3].v)); else if(!strcmp(k,"nnnnnn")) gr->ZoomAxis(mglPoint(a[0].v, a[1].v, a[2].v), mglPoint(a[3].v, a[4].v, a[5].v)); else if(!strcmp(k,"nnnnnnnn")) gr->ZoomAxis(mglPoint(a[0].v, a[1].v, a[2].v, a[3].v), mglPoint(a[4].v, a[5].v, a[6].v, a[7].v)); else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_zrange(mglGraph *gr, long , mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"d")) gr->SetRange('z',*(a[0].d)); else if(!strcmp(k,"dn")) gr->SetRange('z',*(a[0].d),a[1].v); else if(!strcmp(k,"nn")) gr->SetRange('z', a[0].v, a[1].v); else if(!strcmp(k,"nnn")) { if(a[2].v) gr->AddRange('z', a[0].v, a[1].v); else gr->SetRange('z', a[0].v, a[1].v); } else res = 1; return res; } //----------------------------------------------------------------------------- int static mgls_ztick(mglGraph *gr, long n, mglArg *a, const char *k, const char *) { int res=0; if(!strcmp(k,"n")) gr->SetTicks('z', a[0].v); // else if(!strcmp(k,"ns")) gr->SetTicks('z', a[0].v, 0, NAN, a[1].s.w); else if(!strcmp(k,"nn")) gr->SetTicks('z', a[0].v, mgl_int(a[1].v)); else if(!strcmp(k,"nns")) gr->SetTicks('z', a[0].v, mgl_int(a[1].v), NAN, a[2].s.w); else if(!strcmp(k,"nnn")) gr->SetTicks('z', a[0].v, mgl_int(a[1].v), a[2].v); else if(!strcmp(k,"nnns")) gr->SetTicks('z', a[0].v, mgl_int(a[1].v), a[2].v, a[3].s.w); else if(!strcmp(k,"s")) gr->SetTickTempl('z',a[0].s.w); else if(!strcmp(k,"ds")) gr->SetTicksVal('z', *(a[0].d), a[1].s.w); else if(!strcmp(k,"dsn")) gr->SetTicksVal('z', *(a[0].d), a[1].s.w, a[2].v); else if(!strncmp(k,"ns",2)) { std::wstring s; std::vector v; for(long i=0;iSetTicksVal('z',mglDataS(v),s.c_str(),v.size()==1?true:false); } else res = 1; return res; } //----------------------------------------------------------------------------- mglCommand mgls_set_cmd[] = { {"addlegend",_("Add legend entry"),"addlegend 'txt' 'fmt'", mgls_addlegend,15}, {"addsymbol",_("Add user-defined symbol"),"addsymbol 'id' Xdat Ydat", mgls_addsymbol,15}, {"adjust",_("Adjust ticks for best view"),"adjust ['dir']", mgls_adjust ,14}, {"alpha",_("Switch on/off transparency"),"alpha [val]", mgls_alpha ,2}, {"alphadef",_("Set default transparency"),"alphadef val", mgls_alphadef ,2}, {"ambient",_("Set ambient light brightness"),"ambient val", mgls_ambient ,2}, {"arrowsize",_("Set size of arrows"),"arrowsize val", mgls_arrowsize ,2}, {"aspect",_("Set aspect ration"),"aspect valx valy [valz]", mgls_aspect ,5}, {"attachlight",_("Attach light settings to inplot"),"attachlight val", mgls_attachlight ,2}, {"axisstl",_("Set axis and tick style"),"axisstl 'stl' ['tick' 'sub']", mgls_axisstl ,14}, {"barwidth",_("Set default bars width"),"barwidth val", mgls_barwidth ,2}, {"bbox",_("Set bounding box for 2d export"),"bbox x1 y1 [x2 y2]", mgls_bbox ,2}, {"chdir",_("Change current directory"),"chdir 'path'", mgls_chdir ,2}, {"clearlegend",_("Clear legend entries"),"clearlegend", mgls_clearlegend ,15}, {"clf",_("Clear picture"),"clf|'col'|r g b", mgls_clf ,12}, {"columnplot",_("Set position of plot inside cell of column"), "columnplot num ind [d]", mgls_columnplot ,5}, {"crange",_("Set color range"),"crange Dat [add]|c1 c2 [add]", mgls_crange ,14}, {"ctick",_("Set ticks for colorbar"),"ctick 'tmpl'|dc ['factor']", mgls_ctick ,14}, {"cut",_("Setup plot points cutting"),"cut val|x1 y1 z1 x2 y2 z2|'cond'", mgls_cut ,2}, {"diffuse",_("Set diffusive light brightness"),"diffuse val", mgls_diffuse ,2}, {"drawreg",_("Set draw region for quality&4"),"drawreg|nx ny m", mgls_drawreg ,2}, {"facenum",_("Set number of visible faces"),"facenum val", mgls_facenum ,2}, {"fog",_("Switch on/off fog"),"fog val [dz]", mgls_fog ,2}, {"font",_("Setup font"),"font 'fmt' [size]", mgls_font ,15}, {"gray",_("Switch on/off gray-scale mode"),"gray [val]", mgls_gray ,2}, {"gridplot",_("Set position of plot inside cell of matrix"), "gridplot nx ny ind [d]", mgls_gridplot ,5}, {"inplot",_("Set arbitrary position of plot in picture"),"x1 x2 y1 y2 [rel]", mgls_inplot ,5}, {"legendmarks",_("Set number of marks in the legend"),"legendmarks val", mgls_legendmarks ,15}, {"light",_("Setup light"),"light [val]|num val|num xpos ypos zpos ['fmt' br ap]|num xpos ypos zpos px py pz ['fmt' br ap]", mgls_light ,2}, {"load",_("Load commands from external DLL"),"load 'fname'", mgls_load, 6}, {"loadfont",_("Load fontfaces"),"loadfont ['face']", mgls_loadfont ,15}, {"marksize",_("Set size of markers"),"marksize val", mgls_marksize ,2}, {"mask",_("Set brush for given mask id"),"mask 'id' 'val'|'id' val|angle", mgls_mask ,2}, {"meshnum",_("Set number of lines in mesh/fall/vect and so on"),"meshnum val", mgls_meshnum ,2}, {"multiplot",_("Set position of plot block in matrix"),"multiplot m n pos dx dy 'style' [sx sy]", mgls_multiplot ,5}, {"origin",_("Set axis origin"),"origin x0 y0 [z0]", mgls_origin ,14}, {"origintick",_("Set tick labels drawing at origin"),"origintick val", mgls_origintick ,14}, {"palette",_("Set palette for 1D plots"),"palette 'colors'", mgls_palette ,2}, {"pendelta",_("Set size of semi-transparent area around line"),"pendelta val", mgls_pendelta ,2}, {"perspective",_("Set perspective"),"perspective val", mgls_perspective ,2}, {"plotid",_("Set default filename"),"plotid 'name'", mgls_plotid ,2}, {"quality",_("Set plot quality"),"quality [val]", mgls_quality ,2}, {"ranges",_("Set axis ranges"),"ranges x1 x2 y1 y2 [z1 z2]|Xdat Ydat [Zdat Cdat]", mgls_ranges ,14}, {"rasterize",_("Rasterize plot and save to background"),"rasterize", mgls_rasterize ,12}, {"reset",_("Reset settings and clear picture"),"reset", mgls_reset ,12}, {"rotate",_("Rotate plot"),"rotate tetz tetx [tety]|tet x y z", mgls_rotate ,5}, {"rotatetext",_("Set to auto rotate text or not"),"rotatetext val", mgls_rotatetext ,15}, {"scaletext",_("Set scale text in relative subplots too"),"scaletext val", mgls_scaletext ,15}, {"setsize",_("Set picture size"),"setsize width height", mgls_setsize ,2}, {"setsizescl",_("Set scaling factor for further setsize"),"setsizescl val", mgls_setsizescl ,2}, {"setup",_("Set bit-flags (for advanced users only)"),"setup val flag", mgls_setup ,2}, {"shear",_("Shear plot"),"shear valx valy", mgls_shear ,5}, {"shearplot",_("Set position of plot inside cell of sheared stick"), "shearplot num ind sx sy [xd yd]", mgls_shearplot ,5}, {"stickplot",_("Set position of plot inside cell of rotated stick"), "stickplot num ind tet phi", mgls_stickplot ,5}, {"subplot",_("Set position of plot as cell of matrix"),"subplot m n pos ['style' dx dy]", mgls_subplot ,5}, {"ternary",_("Switch on/off to use ternary axis"),"ternary val", mgls_ternary ,14}, {"ticklen",_("Set tick length"),"ticklen val [stt]", mgls_ticklen ,14}, {"tickshift",_("Set additional tick and axis labels shift"),"tickshift dx [dy dz dc]", mgls_tickshift ,14}, {"ticktime",_("Set ticks in time format"),"ticktime 'dir' [dv 'tmpl']", mgls_ticktime ,14}, {"transptype",_("Set type transparency"),"transptype val", mgls_transptype ,2}, {"tuneticks",_("Set ticks tuning"),"tuneticks val [pos]", mgls_tuneticks ,14}, {"variant",_("Select variant of plot style(s)"),"variant var", mgls_variant, 6}, {"version",_("Print MathGL version or check if it is valid"),"version ['ver']", mgls_version, 2}, {"view",_("Change view angles - use 'rotate' for plot rotation"),"view tetz tetx [tety]", mgls_view ,5}, {"write",_("Write current image to graphical file"),"write ['fname']", mgls_write ,2}, {"xrange",_("Set range for x-axis"),"xrange Dat [add]|x1 x2 [add]", mgls_xrange ,14}, {"xtick",_("Set ticks for x-axis"),"xtick dx sx ['factor']|dx sx tx ['factor']|'tmpl'|Xdat 'lbl' [add]|v1 'lbl1' ...", mgls_xtick,14}, {"yrange",_("Set range for y-axis"),"yrange Dat [add]|y1 y2 [add]", mgls_yrange,14}, {"ytick",_("Set ticks for y-axis"),"ytick dy sy ['factor']|dy sy ty ['factor']|'tmpl'|Ydat 'lbl' [add]|v1 'lbl1' ...", mgls_ytick,14}, {"zoom",_("Zoom plot region"),"zoom x1 x2 y1 y2", mgls_zoom,5}, {"zoomaxis",_("Zoom axis range"),"zoomaxis x1 x2|x1 y1 x2 y2|x1 y1 z1 x2 y2 z2|x1 y1 z1 c1 x2 y2 z2 c2", mgls_zoomaxis,14}, {"zrange",_("Set range for z-axis"),"yrange Dat [add]|z1 z2 [add]", mgls_zrange ,14}, {"ztick",_("Set ticks for z-axis"),"ztick dz sz ['factor']|dz sz tz ['factor']|'tmpl'|Zdat 'lbl' [add]|v1 'lbl1' ...", mgls_ztick,14}, {"","","",NULL,0}}; //----------------------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/addon.cpp��������������������������������������������������������������������������0000644�0001750�0001750�00000021637�13513030041�015536� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * addon.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #ifdef WIN32 #include #else #include #endif #include #include "mgl2/addon.h" #include "mgl2/data.h" //----------------------------------------------------------------------------- void MGL_EXPORT mgl_strcls(char *str) { size_t len = strlen(str),i,n; char *tmp = new char[len+1]; memset(tmp,0,len); for(i=0;i0;i--) if(tmp[i]!=' ') break; tmp[i+1]=0; strcpy(str,&(tmp[n])); delete []tmp; } //----------------------------------------------------------------------------- long MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd) { const char *p=strstr(str,fnd); return p?p-str:-1L; } //----------------------------------------------------------------------------- long MGL_EXPORT_PURE mgl_chrpos(const char *str,char ch) { const char *p=str?strchr(str,ch):0; return p?p-str:-1L; } //----------------------------------------------------------------------------- int mgl_fgetstr_script = 0; void MGL_EXPORT mgl_fgetstr_mgl(int enable) { mgl_fgetstr_script = enable; } MGL_EXPORT char *mgl_fgetstr(FILE *fp) { const long size=10240; // NOTE: this set maximal length of string to be read static char s[size]; do { if(!fgets(s,size,fp)) break; mgl_strtrim(s); if(mgl_fgetstr_script && s[0]=='#' && s[1]=='M' && s[2]=='G' && s[3]=='L' && s[4]==' ') { std::string buf("mglconv -n "); buf+= s+5; system(buf.c_str()); } // strlwr(s); } while(!feof(fp) && (s[0]==0 || s[0]=='%' || s[0]=='#')); for(long i=0;s[i];i++) if(s[i]=='#') { s[i]=0; break; } mgl_strtrim(s); return s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...) { if(!str || !str[0]) return; const size_t len=strlen(str); char *s, *t; va_list lst; va_start(lst,str); t = mgl_fgetstr(fp); for(size_t i=0;i0) pos = p; if(fname==NULL) return NULL; if(pos==0) { if(!getcwd(path,256)) return 0; } // remember ini dyrectory else { if(chdir(path)==-1) return 0; } // read the initial (common) data FILE *fp=fopen(fname,"rt"); if(fp==NULL) return NULL; fseek(fp,0,SEEK_END); len = ftell(fp); if(pos>=len) // no more data { fclose(fp); return NULL; } fseek(fp,pos,SEEK_SET); //printf("pos 1 = %d\t",pos); do { s = mgl_fgetstr(fp); fflush(stdout); if(s[0]=='$' || s[1]=='$' || s[3]=='$') { fclose(fp); return NULL; } } while(!feof(fp) && (s[0]!='-' || s[1]!='-' || s[3]!='-')); if(feof(fp)) // no more data { fclose(fp); return NULL; } return fp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_difr_grid(dual *a,int n,int step,dual q,int Border,dual *tmp,int kk) { mgl_difr_grid_old(a,n,step,q,Border,tmp,tmp+n,kk); } void MGL_EXPORT mgl_difr_grid_old(dual *a,int n,int step,dual q,int Border,dual *b, dual *d,int kk) { const dual adt = dual(0.,1.)*q; if(step==1) memcpy(b,a,n*sizeof(dual)); else for(long i=0;i0;k--) // 3 iterations { for(long i=1;i0;k--) // kk iterations { d[ii] = a[ii] + adt*(b[ii+1]-b[ii])*(ff/k); for(long i=ii+1;inorm(b[n-2]) ? b[n-2]*b[n-2]/b[n-3] : mreal(2)*b[n-2]-b[n-3]; break; case -2: // gaussian at border b[n-1] = norm(b[n-3])>norm(b[n-2]) ? pow(b[n-2]/b[n-3],3)*b[n-4] : b[n-4] + mreal(3)*(b[n-2]-b[n-3]); break; } } if(step==1) memcpy(a,b,n*sizeof(dual)); else for(long i=0;i * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/other.h" #include "mgl2/data.h" MGL_NO_EXPORT char *mgl_read_gz(gzFile fp); //----------------------------------------------------------------------------- // // IFS series // //----------------------------------------------------------------------------- void static mgl_ifs_2d_point(HCDT A, mreal& x, mreal& y, mreal amax) { long i, n=A->GetNy(); mreal r = amax*mgl_rnd(), sum_prob = 0, x1; for(i=0;iv(6,i); if(rv(0,i)*x + A->v(1,i)*y + A->v(4,i); y = A->v(2,i)*x + A->v(3,i)*y + A->v(5,i); x = x1; } HMDT MGL_EXPORT mgl_data_ifs_2d(HCDT A, long n, long skip) { if(!A || A->GetNx()<7 || n<1) return 0; // incompatible dimensions mreal amax=0; for(long i=0; iGetNy(); i++) amax += A->v(6,i); if(amax<=0) return 0; mglData *f = new mglData(2,n); mreal x = 0, y = 0; for(long i=0; ia[2*i] = x; f->a[2*i+1] = y; } return f; } uintptr_t MGL_EXPORT mgl_data_ifs_2d_(uintptr_t *d, long *n, long *skip) { return uintptr_t(mgl_data_ifs_2d(_DT_,*n,*skip)); } //----------------------------------------------------------------------------- void static mgl_ifs_3d_point(HCDT A, mreal& x, mreal& y, mreal& z, mreal amax) { int i, n=A->GetNy(); mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1; for (i=0; iv(12,i); if(rv(0,i)*x + A->v(1,i)*y + A->v(2,i)*z + A->v(9,i); y1= A->v(3,i)*x + A->v(4,i)*y + A->v(5,i)*z + A->v(10,i); z = A->v(6,i)*x + A->v(7,i)*y + A->v(8,i)*z + A->v(11,i); x = x1; y = y1; } HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip) { if(!A || A->GetNx()<13 || n<1) return 0; // incompatible dimensions mreal amax = 0; for(int i=0; iGetNy(); i++) amax += A->v(12,i); if(amax <= 0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0, z = 0; for(long i=0; ia[3*i] = x; f->a[3*i+1] = y; f->a[3*i+2] = z; } return f; } uintptr_t MGL_EXPORT mgl_data_ifs_3d_(uintptr_t *d, long *n, long *skip) { return uintptr_t(mgl_data_ifs_3d(_DT_,*n,*skip)); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_data_ifs_file(const char *fname, const char *name, long n, long skip) { gzFile fp = gzopen(fname,"r"); if(!fp) return 0; // Couldn't open file file char *buf = mgl_read_gz(fp); gzclose(fp); char *s = strstr(buf,name); if(!s) return 0; // No data for fractal 'name' in the file char *p = strchr(s,'{'), *e; if(!p) return 0; // Wrong data format for fractal 'name' in the file bool ext3d = false; e = strstr(s,"(3D)"); if(e && e nums; for(size_t i=0;p[i] && p+i' ') i++; } } HMDT dat = new mglData, res; if(ext3d) { dat->Set(&(nums[0]), 13, nums.size()/13, 1); res = mgl_data_ifs_3d(dat, n, skip); } else { dat->Set(&(nums[0]), 7, nums.size()/7, 1); res = mgl_data_ifs_2d(dat, n, skip); } delete dat; free(buf); return res; } uintptr_t mgl_data_ifs_file_(const char *fname, const char *name, long *n, long *skip,int l,int m) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; char *t=new char[m+1]; memcpy(t,name,m); t[m]=0; uintptr_t r = uintptr_t(mgl_data_ifs_file(s,t,*n,*skip)); delete []s; delete []t; return r; } //----------------------------------------------------------------------------- // // Functions for flame fractal // //----------------------------------------------------------------------------- void static mgl_linear_var0(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*x; yNew += par[0]*y; } void static mgl_sinusoidal_var1(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*sin(x); yNew += par[0]*sin(y); } void static mgl_spherical_var2(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]/(x*x+y*y); xNew += c1*x; yNew += c1*y; } void static mgl_swirl_var3(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r2=x*x+y*y, c1=sin(r2), c2=cos(r2); xNew += par[0]*(x*c1 - y*c2); yNew += par[0]*(x*c2 + y*c1); } void static mgl_horseshoe_var4(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]/hypot(x,y); xNew += c1*(x*x-y*y); yNew += 2*c1*x*y; } void static mgl_polar_var5(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*atan2(x,y)/M_PI; yNew += par[0]*(hypot(x,y)-1); } void static mgl_handkerchief_var6(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), t=atan2(x,y), c1=par[0]*r; xNew += c1*sin(t+r); yNew += c1*cos(t-r); } void static mgl_heart_var7(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), c1=par[0]*r, c2=atan2(x,y)*r; xNew += c1*sin(c2); yNew -= c1*cos(c2); } void static mgl_disc_var8(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*atan2(x,y)/M_PI, c2=M_PI*hypot(x,y); xNew += c1*sin(c2); yNew += c1*cos(c2); } void static mgl_spiral_var9(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), t=atan2(x,y), c1=par[0]/r; xNew += c1*(cos(t)+sin(r)); yNew += c1*(sin(t)-cos(r)); } void static mgl_hyperbolic_var10(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), t=atan2(x,y); xNew += par[0]*sin(t)/r; yNew += par[0]*r*cos(t); } void static mgl_diamond_var11(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), t=atan2(x,y); xNew += par[0]*sin(t)*cos(r); yNew += par[0]*cos(t)*sin(r); } void static mgl_ex_var12(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), t=atan2(x,y), c1=par[0]*r; mreal c2=mgl_ipow(sin(t+r),3), c3 = mgl_ipow(cos(t-r), 3); xNew += c1*(c2 + c3); yNew += c1*(c2 - c3); } void static mgl_julia_var13(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*sqrt(hypot(x,y)), c2=atan2(x,y)/2, c3=(rand()%2)*M_PI; xNew += c1*cos(c2+c3); yNew += c1*sin(c2+c3); } void static mgl_bent_var14(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { if(x>=0 && y>=0) { xNew += par[0]*x; yNew += par[0]*y; } else if(x<0 && y>=0) { xNew += par[0]*2*x; yNew += par[0]*y; } else if(x>=0 && y<0) { xNew += par[0]*x; yNew += par[0]*y/2; } else { xNew += par[0]*2*x; yNew += par[0]*y/2; } } void static mgl_waves_var15(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { // NOTE: par[1]=b[i], par[2]=1/c[i]^2, par[3]=e[i], par[4]=1/f[i]^2 xNew += par[0]*(x + par[1]*sin(y*par[2])); yNew += par[0]*(y + par[3]*sin(x*par[4])); } void static mgl_fisheye_var16(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*2/(hypot(x,y) + 1); xNew += c1*y; yNew += c1*x; } void static mgl_popcorn_var17(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { // NOTE: par[1]=c[i], par[2]=f[i] xNew += par[0]*(x + par[1]*sin(tan(3*y))); yNew += par[0]*(y + par[2]*sin(tan(3*x))); } void static mgl_exponential_var18(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*exp(x-1); xNew += c1*cos(M_PI*y); yNew += c1*sin(M_PI*y); } void static mgl_power_var19(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal t=atan2(x,y), c1=par[0]*pow(hypot(x,y), sin(t)); xNew += c1*cos(t); yNew += c1*sin(t); } void static mgl_cosine_var20(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*cos(M_PI*x)*cosh(y); yNew -= par[0]*sin(M_PI*x)*sinh(y); } void static mgl_rings_var21(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { // NOTE: par[1]=c[i]^2 mreal t=atan2(x,y), r=hypot(x,y), c1=par[0]*(fmod(r+par[1],2*par[1])-par[1]+r*(1-par[1])); // convert to int? xNew += c1*cos(t); yNew += c1*sin(t); } void static mgl_fan_var22(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { // NOTE: par[1]=c[i]^2, par[2]=f[i] mreal t=atan2(x,y), c1=par[0]*hypot(x,y), c2; c2 = fmod(t+par[2], M_PI*par[1]); // convert to int? if(c2>M_PI_2*par[1]) c2 = t - M_PI_2*par[1]; else c2 += t; xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_blob_var23(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal t=atan2(x,y), c1=par[0]*hypot(x,y)*(par[2]+(par[1]-par[2])/2*(sin(par[3]*t))); xNew += c1*cos(t); yNew += c1*sin(t); } void static mgl_pdj_var24(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*(sin(par[1]*y) - cos(par[2]*x)); yNew += par[0]*(sin(par[3]*x) - cos(par[4]*y)); } void static mgl_fan2_var25(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal t=atan2(x,y), c1, c2; c1 = M_PI*par[1]*par[1]; c2 = t + par[2] - c1*int(2*t*par[2]/c1); c1 /= 2; c2 = c2>c1?t-c1:t+c1; c1 = par[0]*hypot(x,y); xNew += c1*sin(c2); yNew += c1*cos(c2); } void static mgl_rings2_var26(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), t=atan2(x,y), c1=par[1]*par[1]; c1 = par[0]*(r - 2*c1*int((r+c1)/(2*c1)) + r*(1-c1)); xNew += c1*cos(t); yNew += c1*sin(t); } void static mgl_eyefish_var27(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*2/(hypot(x,y)+1); xNew += c1*x; yNew += c1*y; } void static mgl_bubble_var28(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*4/(x*x+y*y+4); xNew += c1*x; yNew += c1*y; } void static mgl_cylinder_var29(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*sin(x); yNew += par[0]*y; } void static mgl_perspective_var30(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*par[2]/(par[2]-y*sin(par[1])); xNew += c1*x; yNew += c1*y*cos(par[1]); } void static mgl_noise_var31(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*mgl_rnd(), c2=2*M_PI*mgl_rnd(); xNew += c1*x*cos(c2); yNew += c1*y*sin(c2); } void static mgl_juliaN_var32(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=int(fabs(par[1])*mgl_rnd()), c2; c2 = (atan2(y,x) + 2*M_PI*c1)/par[1]; c1 = par[0]*pow(hypot(x,y), par[2]/par[1]); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_juliaScope_var33(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=int(fabs(par[1])*mgl_rnd()), c2; c2 = ((2*(rand()%2)-1)*atan2(y,x) + 2*M_PI*c1)/par[1]; c1 = par[0]*pow(hypot(x,y), par[2]/par[1]); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_blur_var34(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*mgl_rnd(), c2=2*M_PI*mgl_rnd(); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_gaussian_var35(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*(4*mgl_rnd()-2), c2=2*M_PI*mgl_rnd(); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_radialBlur_var36(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal r=hypot(x,y), c1=par[1]*M_PI_2, c2=par[0]*(4*mgl_rnd()-2), c3; c3 = c2*cos(c1) - 1; c2 = atan2(y,x) + c2 *sin(c1); xNew += r*cos(c2) + c3*x; yNew += r*sin(c2) + c3*y; } void static mgl_pie_var37(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=int(mgl_rnd()*par[1] + 0.5), c2; c2 = par[2] + 2*M_PI/par[1]*(c1 + mgl_rnd()*par[3]); c1 = par[0]*mgl_rnd(); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_ngon_var38(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=2*M_PI/par[2], c2; c2 = atan2(y,x) - c1*floor(atan2(y,x)/c1); if(c2 <= c1/2) c2 -= c1; c1 = par[0]*(par[3]*(1/cos(c2) - 1) + par[4])/pow(hypot(x,y), par[1]); xNew += c1*x; yNew += c1*y; } void static mgl_curl_var39(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=1 + par[1]*x + par[2]*(x*x - y*y); mreal c2 = par[1]*y + 2*par[2]*x*y; mreal c3 = par[0]/(c1*c1 + c2*c2); xNew += c3*(c1*x + c2*y); yNew += c3*(c1*x - c2*y); } void static mgl_rectangles_var40(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*((2*floor(x/par[1]) + 1)*par[1] - x); yNew += par[0]*((2*floor(y/par[2]) + 1)*par[2] - y); } void static mgl_arch_var41(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=mgl_rnd()*M_PI*par[0], c2=sin(c1); xNew += par[0]*c2; yNew += par[0]*c2*c2/cos(c1); } void static mgl_tangent_var42(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*sin(x)/cos(y); yNew += par[0]*tan(y); } void static mgl_square_var43(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*(mgl_rnd() - 0.5); yNew += par[0]*(mgl_rnd() - 0.5); } void static mgl_blade_var44(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*x, c2=mgl_rnd()*hypot(x,y)*par[0]; xNew += c1*(cos(c2) + sin(c2)); // TODO check use of c2 yNew += c1*(cos(c2) - sin(c2)); } void static mgl_secant_var45(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*x; yNew += 1/cos(par[0]*hypot(x,y)); } void static mgl_rays_var46(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*par[0]*tan(mgl_rnd()*M_PI*par[0])/(x*x+y*y); xNew += c1*cos(x); yNew += c1*sin(y); } void static mgl_twintrian_var47(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=par[0]*x, c2, c3; c2 = mgl_rnd()*hypot(x,y)*par[0]; c3 = log10(sin(c2)*sin(c2)) + cos(c2); xNew += c1*c3; yNew += c1*(c3 - M_PI*sin(c2)); } void static mgl_cross_var48(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]/fabs(x*x - y*y); xNew += c1*x; yNew += c1*y; } void static mgl_disc2_var49(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = cos(par[2])-1, c2 = sin(par[2]), c3; if(par[2]>2*M_PI) { c3 = 1+par[2]-2*M_PI; c1 *= c3; c2 *= c3; } else if(par[2]<-2*M_PI) { c3 = 1+par[2]+2*M_PI; c1 *= c3; c2 *= c3; } c3 = par[1]*M_PI*(x+y); mreal a = par[0]*atan2(x,y)/M_PI; xNew += a*(c1+sin(c3)); yNew += a*(c2+cos(c3)); } void static mgl_supershape_var50(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[2]/4*atan2(y,x)+M_PI_4, r = hypot(x,y); c1 = pow(fabs(sin(c1)), par[5])+pow(fabs(cos(c1)), par[4]); c1 = par[0]*((par[1]*mgl_rnd()+(1-par[1])*r)-par[6])*pow(c1, -1.0/par[3])/r; xNew += c1*x; yNew += c1*y; } void static mgl_flower_var51(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*(mgl_rnd()-par[2])*cos(par[1]*atan2(y,x))/hypot(x,y); xNew += c1*x; yNew += c1*y; } void static mgl_conic_var52(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = x/hypot(x,y); c1 = par[0]*(mgl_rnd()-par[2])*par[1]/(1+par[1]*c1)/hypot(x,y); xNew += c1*x; yNew += c1*y; } void static mgl_parabola_var53(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = hypot(x,y), c2; c2 = cos(c1); c1 = sin(c1); xNew += par[0]*par[1]*c1*c1 *mgl_rnd(); yNew += par[0]*par[2]*c2*mgl_rnd(); } void static mgl_bent2_var54(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = par[0]*x, c2 = par[0]*y; if(x<0.0) c1 *= par[1]; if(y<0.0) c2 *= par[2]; xNew += c1; yNew += c2; } void static mgl_bipolar_var55(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = 0.5*atan2(2*y, x*x+y*y-1)-M_PI_2*par[1], c2, c3, c4; if(c1>M_PI_2) c1 = -M_PI_2+fmod(c1+M_PI_2, M_PI); else if(y<-M_PI_2) c1 = M_PI_2-fmod(M_PI_2-y, M_PI); c2 = par[0]*M_2_PI; c3 = x*x+y*y+1; c4 = 2*x; xNew += 0.25*c2*log((c3+c4)/(c3-c4)); yNew += c1*c2; } void static mgl_boarders_var56(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = round(x), c2 = round(y), c3, c4; c3 = x-c1; c4 = y-c2; if(mgl_rnd()>=0.75) { xNew += par[0]*(c1+0.5*c3); yNew += par[0]*(c2+0.5*c4); } else { if(fabs(c3)>=fabs(c4)) { if(c3>=0) { xNew += par[0]*(c1+0.5*c3+0.25); yNew += par[0]*(c2+0.5*c4+0.25*c4/c3); } else { xNew += par[0]*(c1+0.5*c3-0.25); yNew += par[0]*(c2+0.5*c4-0.25*c4/c3); } } else { if(c4>=0) { xNew += par[0]*(c2+0.5*c4+0.25); yNew += par[0]*(c1+0.5*c3+0.25*c3/c4); } else { xNew += par[0]*(c2+0.5*c4-0.25); yNew += par[0]*(c1+0.5*c3-0.25*c3/c4); } } } } void static mgl_butterfly_var57(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = 4/sqrt(3*M_PI)*par[0], c2 = 2*y; // replace 4/sqrt(3*M_PI) for the result? c1 *= sqrt(fabs(x*y)/(x*x+c2*c2)); xNew += c1*x; yNew += c1*c2; } void static mgl_cell_var58(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=floor(x/par[1]), c2=floor(y/par[1]), c3=x-c1*par[1], c4=y-c2*par[1]; if(c2>=0) { if(c1>=0) { c1 *= 2; c2 *= 2; } else { c1=-2*c1-1; c2 *= 2; } } else { if(c1>=0) { c1 *= 2; c2=-2*c2-1; } else { c1=-2*c1-1; c2=-2*c2-1; } } xNew += par[0]*(par[1]*c1+c3); yNew += par[0]*(par[1]*c2+c4); } void static mgl_cpow_var59(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = atan2(y, x), c2, c3, c4, c5; c2 = par[1]/par[3]; c3 = par[2]/par[3]; c4 = 0.5*log(x*x+y*y); c5 = c1*c2+c3*c4+2*M_PI/par[3]*floor(par[3]*mgl_rnd()); c1 = par[0]*exp(c2*c4-c1*c3); c2 = cos(c5); c3 = sin(c5); xNew += c1*c2; yNew += c1*c3; } void static mgl_curve_var60(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { xNew += par[0]*(x+par[1]*exp(-(y*y)/(par[3]*par[3]))); yNew += par[0]*(y+par[2]*exp(-(x*x)/(par[4]*par[4]))); } void static mgl_edisc_var61(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = x*x+y*y+1, c2,c3,c4,c5; c2 = 2*x; c3 = sqrt(c1-c2); c1 = sqrt(c1+c2); c1 = (c1+c3)*0.5; c2 = log(c1+sqrt(c1-1)); c3 = -acos(x/c1); c1 = par[0]/11.57034632; c4 = cos(c2)*cosh(c3); c5 = sin(c2)*sinh(c3); xNew += c1*c4; yNew += c1*c5; } void static mgl_elliptic_var62(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = x*x+y*y+1, c2, c3, c4, c5; c2 = 2*x; c2 = 0.5*(sqrt(c1+c2)+sqrt(c1-c2)); c3 = x/c2; c4 = 1-c3*c3; c5 = c2-1; c1 = par[0]/M_PI_2; if(c4<0) c4 = 0; else c4 = sqrt(c4); if(c5<0) c5 = 0; else c5 = sqrt(c5); xNew += c1*atan2(c3, c4); if(y>0) yNew += c1*log(c2+c5); else yNew -= c1*log(c2+c5); } void static mgl_escher_var63(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = 0.5*(1+cos(par[1])), c2 = 0.5*sin(par[1]), c3, c4, c5; c3 = 0.5*log(x*x+y*y); c4 = atan2(y, x); c5 = c1*c4+c2*c3; c1 = par[0]*exp(c1*c3-c2*c4); xNew += c1*cos(c5); yNew += c1*sin(c5); } void static mgl_foci_var64(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1=0.5*exp(x), c2=0.25/c1, c3=par[0]/(c1+c2-cos(y)); // TODO Check this!!! xNew += c1*(c2-c3); yNew += c1*sin(y); } void static mgl_lazySusan_var65(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = hypot(x, y), c2; if(c1par[1]) xNew += par[0]*(-par[1]+fmod(x-par[1], 2*par[1])); else if(xpar[2]) yNew += par[0]*(-par[2]+fmod(y+par[2], 2*par[2])); else if(y0) xNew += par[0]*(sqrt(x*x+par[1]*par[1])-x*par[2]); else xNew -= par[0]*(sqrt(x*x+par[1]*par[1])+x*par[2]); if(y>0) yNew += par[0]*(sqrt(y*y+par[3]*par[3])-y*par[4]); else yNew -= par[0]*(sqrt(y*y+par[3]*par[3])+y*par[4]); } void static mgl_split_var74(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { if(cos(M_PI*x*par[1])>=0) xNew += par[0]*y; else xNew -= par[0]*y; if(cos(M_PI*y*par[2])>=0) yNew += par[0]*x; else yNew -= par[0]*x; } void static mgl_splits_var75(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { if(x>=0) xNew+= par[0]*(x+par[1]); else xNew += par[0]*(x-par[1]); if(y>=0) yNew += par[0]*(y+par[2]); else yNew += par[0]*(y-par[2]); } void static mgl_stripes_var76(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = floor(x+0.5), c2 = x-c1; xNew += par[0]*(c2*(1-par[1])+c1); yNew += par[0]*(y+c2*c2*par[2]); } void static mgl_wedge_var77(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = hypot(x, y), c2, c3, c4; c2 = atan2(y, x)+par[4]*c1; c3 = 1-0.5*M_1_PI*par[1]*par[3]; c4 = floor(0.5*M_1_PI*(par[2]*c2+M_PI)); c2 = c2*c3+c4*par[1]; c1 = par[0]*(c1+par[2]); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_wedgeJulia_var78(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = int(fabs(par[3])*mgl_rnd()), c2; c1 = (atan2(y, x)+2*M_PI*c1)/par[3]; c2 = floor(0.5*M_1_PI*(par[2]*c1+M_PI)); c2 = c1*(1-0.5*M_1_PI*par[1]*par[2]+c1*par[1]); // TODO Check this!!! c1 = par[0]*pow(x*x +y*y, par[4]/(2*par[3])); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_wedgeSph_var79(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = 1/hypot(x, y), c2, c3, c4; c2 = atan2(y, x)+par[4]*c1; c3 = 1-0.5*M_1_PI*par[1]*par[2]; c4 = floor(0.5*M_1_PI*(par[2]*c2+M_PI)); c2 = c2*c3+c4*par[1]; c1 = par[0]*(c1+par[3]); xNew += c1*cos(c2); yNew += c1*sin(c2); } void static mgl_whorl_var80(mreal &xNew, mreal &yNew, mreal x, mreal y, const mreal *par) { mreal c1 = hypot(x, y), c2; if(c1GetNy(), m=F->GetNy(), last_func=0, l=F->GetNx(); l = l>6?6:l; mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1; for(i=0;iv(6,i); if(rv(0,i)*x+A->v(1,i)*y+A->v(4,i); y1 = A->v(2,i)*x+A->v(3,i)*y+A->v(5,i); x = y = 0; for(long j=0;jv(0,j,i)+0.5); mreal par[5] = {F->v(1,j,i),0,0,0,0}; for(int k=2;kv(k,j,i); if(v<0 || v>=mglFlame2dLAST) { v=0; par[0]=1; } ffunc[v](x,y,x1,y1,par); last_func=v; } return last_func; } HMDT MGL_EXPORT mgl_data_flame_2d(HCDT A, HCDT F, long n, long skip) { if(!A || A->GetNx()<7 || n<1) return 0; // incompatible dimensions if(!F || F->GetNx()<2 || F->GetNz()!=A->GetNy()) return 0; // incompatible dimensions mreal amax=0; for(long i=0; iGetNy(); i++) amax += A->v(6,i); if(amax<=0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0; for(long i=0; ia[3*i+2] = mgl_flame_2d_point(A, F, x, y, amax); // TODO color information ?!! f->a[3*i] = x; f->a[3*i+1] = y; } return f; } uintptr_t MGL_EXPORT mgl_data_flame_2d_(uintptr_t *d, uintptr_t *f, long *n, long *skip) { return uintptr_t(mgl_data_flame_2d(_DT_,_DA_(f),*n,*skip)); } //----------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/mpi.cpp����������������������������������������������������������������������������0000644�0001750�0001750�00000003672�13513030041�015235� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "mgl2/mpi.h" #include "mgl2/canvas.h" #include #define MCW MPI_COMM_WORLD #define TAG_DATA_Z 0 #define TAG_DATA_C 1 //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mpi_send(HMGL gr, int id) { mglCanvas *g = dynamic_cast(gr); if(!g) return; g->Finish(); long n = g->GetWidth()*g->GetHeight(); MPI_Send(g->Z,3*n,MPI_FLOAT,id,TAG_DATA_Z,MCW); MPI_Send(g->C,12*n,MPI_CHAR,id,TAG_DATA_C,MCW); MPI_Send(g->OI,n,MPI_INT,id,TAG_DATA_C,MCW); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mpi_recv(HMGL gr, int id) { mglCanvas *g = dynamic_cast(gr); if(!g) return; g->Finish(); MPI_Status status; long w = g->GetWidth(), h = g->GetHeight(), n = w*h; float *zz = new float[3*n]; int *oi = new int[n]; unsigned char *cc = new unsigned char[12*n]; MPI_Recv(zz,3*n,MPI_FLOAT,id,TAG_DATA_Z,MCW,&status); MPI_Recv(cc,12*n,MPI_CHAR,id,TAG_DATA_C,MCW,&status); MPI_Recv(oi,n,MPI_INT,id,TAG_DATA_C,MCW,&status); // NOTE: No need for check errors. The matter is MPI docs: // "All MPI routines return an error value. Before the value is returned, // the current MPI error handler is called. By default, this error handler aborts the MPI job." #pragma omp parallel for for(long k=0;kGetQuality()&MGL_DRAW_NORM) { g->pnt_plot(i,j,zz[3*k+2],cc+12*k+8,oi[k]); g->pnt_plot(i,j,zz[3*k+1],cc+12*k+4,oi[k]); } g->pnt_plot(i,j,zz[3*k],cc+12*k,oi[k]); } g->set(MGL_FINISHED); delete []oi; delete []zz; delete []cc; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mpi_send_(uintptr_t *gr, int *id) { mgl_mpi_send(_GR_, *id); } void MGL_EXPORT mgl_mpi_recv_(uintptr_t *gr, int *id) { mgl_mpi_recv(_GR_, *id); } //----------------------------------------------------------------------------- ����������������������������������������������������������������������mathgl-2.4.4/src/fit.cpp����������������������������������������������������������������������������0000644�0001750�0001750�00000062020�13513030041�015222� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * fit.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/fit.h" #include "mgl2/prim.h" #include "mgl2/eval.h" #include "mgl2/data.h" #include "mgl2/base.h" #if MGL_HAVE_GSL #include #include #endif HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector &head); //----------------------------------------------------------------------------- int mglFitPnts=100; ///< Number of output points in fitting char mglFitRes[1024]; ///< Last fitted formula mreal mglFitChi=NAN; ///< Chi value for last fitted formula mglData mglFitCovar; ///< Covar matrix for lat fitted formula //----------------------------------------------------------------------------- mreal MGL_EXPORT_PURE mgl_get_fit_chi() { return mglFitChi; } mreal MGL_EXPORT_PURE mgl_get_fit_chi_() { return mglFitChi; } //----------------------------------------------------------------------------- HCDT MGL_EXPORT_CONST mgl_get_fit_covar() { return &mglFitCovar; } uintptr_t MGL_EXPORT_CONST mgl_get_fit_covar_() { return (uintptr_t)&mglFitCovar; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_puts_fit(HMGL gr, double x, double y, double z, const char *pre, const char *font, double size) { long n = strlen(mglFitRes)+(pre?strlen(pre):0)+1; char *buf = new char[n]; if(pre) snprintf(buf,n,"%s%s",pre,mglFitRes); else mgl_strncpy(buf,mglFitRes,n); buf[n-1]=0; mgl_puts(gr,x,y,z,buf,font,size); delete []buf; } void MGL_EXPORT mgl_puts_fit_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, const char *prefix, const char *font, mreal *size, int l, int n) { char *s=new char[l+1]; memcpy(s,prefix,l); s[l]=0; char *d=new char[n+1]; memcpy(d,font,n); d[n]=0; mgl_puts_fit(_GR_, *x,*y,*z, s, d, *size); delete []s; delete []d; } //----------------------------------------------------------------------------- /// Structure for keeping data and precompiled fitted formula struct mglFitData { long n; ///< number of points mglDataA *x,*y,*z; ///< x, y, z values mreal *a; ///< function values mreal *s; ///< value dispersions (sigma) const char *eq; ///< approximation formula int m; ///< number of variables const char *var; ///< variables for fitting }; //----------------------------------------------------------------------------- #if MGL_HAVE_GSL int mgl_fit__f (const gsl_vector *x, void *data, gsl_vector *f) { mglFitData *fd = (mglFitData *)data; mglDataV *var = new mglDataV[fd->m]; std::vector list; for(long i=0;im;i++) { var[i].s = fd->var[i]; var[i].Fill(gsl_vector_get(x,i)); list.push_back(var+i); } if(fd->x) list.push_back(fd->x); if(fd->y) list.push_back(fd->y); if(fd->z) list.push_back(fd->z); HMDT res = mglFormulaCalc(fd->eq, list); #pragma omp parallel for for(long i=0;in;i++) { mreal aa = fd->a[i], ss = fd->s[i]; if(mgl_isnum(aa) && ss==ss && ss!=0) gsl_vector_set (f, i, (res->a[i] - aa)/ss); else gsl_vector_set (f, i, 0); } delete []var; mgl_delete_data(res); return GSL_SUCCESS; } //----------------------------------------------------------------------------- int static mgl_fit__df (const gsl_vector * x, void *data, gsl_matrix * J) { mglFitData *fd = (mglFitData *)data; mglDataV *var = new mglDataV[fd->m]; std::vector list; for(long i=0;im;i++) { var[i].s = fd->var[i]; var[i].Fill(gsl_vector_get(x,i)); list.push_back(var+i); } if(fd->x) list.push_back(fd->x); if(fd->y) list.push_back(fd->y); if(fd->z) list.push_back(fd->z); HMDT res = mglFormulaCalc(fd->eq, list); const mreal eps = 1e-5; for(long j=0;jm;j++) { var[j].Fill(gsl_vector_get(x,j)+eps); HMDT dif = mglFormulaCalc(fd->eq, list); var[j].Fill(gsl_vector_get(x,j)); #pragma omp parallel for for(long i=0;in;i++) { mreal aa = fd->a[i], ss = fd->s[i]; if(mgl_isnum(aa) && ss==ss && ss!=0) gsl_matrix_set (J, i, j, (dif->a[i]-res->a[i])/(eps*ss)); else gsl_matrix_set (J, i, j, 0); } mgl_delete_data(dif); } delete []var; mgl_delete_data(res); return GSL_SUCCESS; } //----------------------------------------------------------------------------- int static mgl_fit__fdf (const gsl_vector * x, void *data, gsl_vector * f, gsl_matrix * J) { mglFitData *fd = (mglFitData *)data; mglDataV *var = new mglDataV[fd->m]; std::vector list; for(long i=0;im;i++) { var[i].s = fd->var[i]; var[i].Fill(gsl_vector_get(x,i)); list.push_back(var+i); } if(fd->x) list.push_back(fd->x); if(fd->y) list.push_back(fd->y); if(fd->z) list.push_back(fd->z); HMDT res = mglFormulaCalc(fd->eq, list); #pragma omp parallel for for(long i=0;in;i++) { mreal aa = fd->a[i], ss = fd->s[i]; if(mgl_isnum(aa) && ss==ss && ss!=0) gsl_vector_set (f, i, (res->a[i] - aa)/ss); else gsl_vector_set (f, i, 0); } const mreal eps = 1e-5; for(long j=0;jm;j++) { var[j].Fill(gsl_vector_get(x,j)+eps); HMDT dif = mglFormulaCalc(fd->eq, list); var[j].Fill(gsl_vector_get(x,j)); #pragma omp parallel for for(long i=0;in;i++) { mreal aa = fd->a[i], ss = fd->s[i]; if(mgl_isnum(aa) && ss==ss && ss!=0) gsl_matrix_set (J, i, j, (dif->a[i]-res->a[i])/(eps*ss)); else gsl_matrix_set (J, i, j, 0); } mgl_delete_data(dif); } delete []var; mgl_delete_data(res); return GSL_SUCCESS; } #endif //----------------------------------------------------------------------------- /// GSL based fitting procedure for formula/arguments specified by string mreal static mgl_fit_base(mglFitData &fd, mreal *ini) { #if MGL_HAVE_GSL long m=fd.m,n=fd.n,iter=0; if(n<1 || ini==0) return -1; // setup data double *x_init = new double[fd.m]; for(long i=0;idx, s->x, 1e-4, 1e-4 ); } while ( status == GSL_CONTINUE && iter < 500 ); gsl_matrix *covar = gsl_matrix_alloc(m, m); #ifdef MGL_HAVE_GSL2 gsl_matrix *J = gsl_matrix_alloc(s->fdf->n, s->fdf->p); gsl_multifit_fdfsolver_jac(s, J); gsl_multifit_covar (J, 0.0, covar); gsl_matrix_free (J); #else gsl_multifit_covar(s->J, 0.0, covar); #endif mglFitCovar.Set(covar); gsl_matrix_free(covar); mreal res = gsl_blas_dnrm2(s->f); for(long i=0;ix, i); // free memory gsl_multifit_fdfsolver_free(s); delete []x_init; return res; #else return 0.0; #endif } //----------------------------------------------------------------------------- void mglPrepareFitEq(mglBase *gr,mreal chi, const char *eq, const char *var, mreal *par) { char buf[32]=""; mglFitChi = chi; snprintf(mglFitRes,1024,"chi=%g",chi); mglFitRes[1023]=0; size_t i,k,len=strlen(var); for(i=0;iSetWarn(-1,mglFitRes); memset(mglFitRes, 0, 1024); //mglFitRes[0] = 0; len=strlen(eq); for(i=k=0;iSaveState(opt); mglData x(y->GetNx()); x.Fill(gr->Min.x, gr->Max.x); mglData s(y); s.Fill(1,1); return mgl_fit_xys(gr,&x,y,&s,eq,var,ini,0); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_2(HMGL gr, HCDT z, const char *eq, const char *var, HMDT ini, const char *opt) { gr->SaveState(opt); mglData x(z->GetNx()); x.Fill(gr->Min.x, gr->Max.x); mglData y(z->GetNy()); y.Fill(gr->Min.y, gr->Max.y); mglData s(z); s.Fill(1,1); return mgl_fit_xyzs(gr,&x,&y,z,&s,eq,var,ini,0); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_3(HMGL gr, HCDT a, const char *eq, const char *var, HMDT ini, const char *opt) { gr->SaveState(opt); mglData x(a->GetNx()); x.Fill(gr->Min.x, gr->Max.x); mglData y(a->GetNy()); y.Fill(gr->Min.y, gr->Max.y); mglData z(a->GetNz()); z.Fill(gr->Min.z, gr->Max.z); mglData s(a); s.Fill(1,1); return mgl_fit_xyzas(gr,&x,&y,&z,a,&s,eq,var,ini,0); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_xy(HMGL gr, HCDT x, HCDT y, const char *eq, const char *var, HMDT ini, const char *opt) { mglData s(y); s.Fill(1,1); return mgl_fit_xys(gr,x,y,&s,eq,var,ini,opt); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *eq, const char *var, HMDT ini, const char *opt) { mglData s(z); s.Fill(1,1); return mgl_fit_xyzs(gr,x,y,z,&s,eq,var,ini,opt); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_xyza(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *eq, const char *var, HMDT ini, const char *opt) { mglData s(a); s.Fill(1,1); return mgl_fit_xyzas(gr,x,y,z,a,&s,eq,var,ini,opt); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_ys(HMGL gr, HCDT y, HCDT s, const char *eq, const char *var, HMDT ini, const char *opt) { gr->SaveState(opt); mglData x(y->GetNx()); x.Fill(gr->Min.x, gr->Max.x); return mgl_fit_xys(gr,&x,y,s,eq,var,ini,0); } //----------------------------------------------------------------------------- void static mgl_fill_fit(HMGL gr, mglData &fit, mglData &in, mglFitData &fd, const char *var, long nx, long ny, long nz, long k) { mglDataV *vv = new mglDataV[fd.m]; std::vector list; for(long i=0;iMin.x,gr->Max.x,'x'); x.Name(L"x"); list.push_back(&x); mglDataV y(nx,ny,nz, gr->Min.y,gr->Max.y,'y'); y.Name(L"y"); list.push_back(&y); mglDataV z(nx,ny,nz, gr->Min.z,gr->Max.z,'z'); z.Name(L"z"); list.push_back(&z); HMDT res = mglFormulaCalc(fd.eq, list); long nn = nx*ny*nz; memcpy(fit.a+k*nn,res->a,nn*sizeof(mreal)); delete []vv; mgl_delete_data(res); } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_xys(HMGL gr, HCDT xx, HCDT yy, HCDT ss, const char *eq, const char *var, HMDT ini, const char *opt) { long m = yy->GetNx(); mreal rr = gr->SaveState(opt); long nn = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5); if(xx->GetNx()!=m) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } if(m<2) { gr->SetWarn(mglWarnLow,"Fit[S]"); return 0; } if(ss->GetNN() != yy->GetNN()) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } if(!var || *var==0) { gr->SetWarn(mglWarnNull,"Fit[S]"); return 0; } mglData x(xx), y(yy), s(ss); x.Name(L"x"); long mm = yy->GetNy()*yy->GetNz(); #pragma omp parallel for for(long i=0;iGetNy(), yy->GetNz()); mreal res=-1; mglDataR xc(x); for(long i=0;iGetNy()*yy->GetNz();i++) { if(ini && ini->nx>=fd.m) in.Set(ini->a,fd.m); else in.Fill(0.,0); xc.SetInd(i%x.ny, L"x"); fd.a = y.a+i*m; fd.x = &xc; //x.a+(i%x.ny)*m; fd.s = s.a+i*m; res = mgl_fit_base(fd,in.a); mgl_fill_fit(gr,*fit,in,fd,var,nn,1,1,i); if(ini && ini->nx>=fd.m) memcpy(ini->a,in.a,fd.m*sizeof(mreal)); } mglPrepareFitEq(gr,res,eq,var,in.a); gr->LoadState(); return fit; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT ss, const char *eq, const char *var, HMDT ini, const char *opt) { long m=zz->GetNx(),n=zz->GetNy(); mreal rr = gr->SaveState(opt); long nn = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5); if(xx->GetNx()!=m) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } if(ss->GetNN() != zz->GetNN()) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } if(yy->GetNx()!=n && (xx->GetNy()!=n || yy->GetNx()!=m || yy->GetNy()!=n)) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } if(m<2|| n<2) { gr->SetWarn(mglWarnLow,"Fit[S]"); return 0; } if(!var || *var==0) { gr->SetWarn(mglWarnNull,"Fit[S]"); return 0; } mglData x(m, n), y(m, n), z(zz), s(ss); x.Name(L"x"); y.Name(L"y"); long nz = zz->GetNz(), mm = n*m; #pragma omp parallel for collapse(2) for(long j=0;jGetNz()); mreal res = -1; for(long i=0;inx>=fd.m) in.Set(ini->a,fd.m); else in.Fill(0.,0); fd.a = z.a+i*m*n; fd.s = s.a+i*m*n; res = mgl_fit_base(fd,in.a); mgl_fill_fit(gr,*fit,in,fd,var,nn,nn,1,i); if(ini && ini->nx>=fd.m) memcpy(ini->a,in.a,fd.m*sizeof(mreal)); } mglPrepareFitEq(gr,res, eq,var,in.a); gr->LoadState(); return fit; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT aa, HCDT ss, const char *eq, const char *var, HMDT ini, const char *opt) { long m=aa->GetNx(), n=aa->GetNy(), l=aa->GetNz(), i = n*m*l; mreal rr = gr->SaveState(opt); long nn = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5); if(m<2 || n<2 || l<2) { gr->SetWarn(mglWarnLow,"Fit[S]"); return 0; } if(ss->GetNN() != i) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } bool both = xx->GetNN()==i && yy->GetNN()==i && zz->GetNN()==i; if(!(both || (xx->GetNx()==m && yy->GetNx()==n && zz->GetNx()==l))) { gr->SetWarn(mglWarnDim,"Fit[S]"); return 0; } if(!var || *var==0) { gr->SetWarn(mglWarnNull,"Fit[S]"); return 0; } mglData x(m,n,l), y(m,n,l), z(m,n,l), a(aa), s(ss); x.Name(L"x"); y.Name(L"y"); z.Name(L"z"); #pragma omp parallel for collapse(3) for(long k=0;knx>=fd.m) in.Set(ini->a,fd.m); else in.Fill(0.,0); res = mgl_fit_base(fd,in.a); mgl_fill_fit(gr,*fit,in,fd,var,nn,nn,nn,0); if(ini && ini->nx>=fd.m) memcpy(ini->a,in.a,fd.m*sizeof(mreal)); mglPrepareFitEq(gr,res, eq,var,in.a); gr->LoadState(); return fit; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_hist_x(HMGL gr, HCDT x, HCDT a, const char *opt) { long nn=a->GetNN(); if(nn!=x->GetNN()) { gr->SetWarn(mglWarnDim,"Hist"); return 0; } mreal rr = gr->SaveState(opt); long n = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5); mglData *res = new mglData(n); mreal vx = n/(gr->Max.x-gr->Min.x); for(long i=0;ivthr(i)-gr->Min.x)*vx); if(j1>=0 && j1a[j1] += a->vthr(i); } gr->LoadState(); return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_hist_xy(HMGL gr, HCDT x, HCDT y, HCDT a, const char *opt) { long nn=a->GetNN(); if(nn!=x->GetNN() || nn!=y->GetNN()) { gr->SetWarn(mglWarnDim,"Hist"); return 0; } mreal rr = gr->SaveState(opt); long n = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5); mglData *res = new mglData(n, n); mreal vx = n/(gr->Max.x-gr->Min.x); mreal vy = n/(gr->Max.y-gr->Min.y); for(long i=0;ivthr(i)-gr->Min.x)*vx); long j2 = long((y->vthr(i)-gr->Min.y)*vy); if(j1>=0 && j1=0 && j2a[j1+n*j2] += a->vthr(i); } gr->LoadState(); return res; } //----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_hist_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *opt) { long nn=a->GetNN(); if(nn!=x->GetNN() || nn!=y->GetNN() || nn!=z->GetNN()) { gr->SetWarn(mglWarnDim,"Hist"); return 0; } mreal rr = gr->SaveState(opt); long n = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5); mglData *res = new mglData(n, n, n); mreal vx = n/(gr->Max.x-gr->Min.x), vy = n/(gr->Max.y-gr->Min.y), vz = n/(gr->Max.z-gr->Min.z); for(long i=0;ivthr(i)-gr->Min.x)*vx); long j2 = long((y->vthr(i)-gr->Min.y)*vy); long j3 = long((z->vthr(i)-gr->Min.z)*vz); if(j1>=0 && j1=0 && j2=0 && j3a[j1+n*(j2+n*j3)] += a->vthr(i); } gr->LoadState(); return res; } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_hist_x_(uintptr_t* gr, uintptr_t* x, uintptr_t* a, const char *opt, int lo) { char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_hist_x(_GR_, _DA_(x), _DA_(a), o); delete []o; return r; } uintptr_t MGL_EXPORT mgl_hist_xy_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* a, const char *opt, int lo) { char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_hist_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), o); delete []o; return r; } uintptr_t MGL_EXPORT mgl_hist_xyz_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* a, const char *opt, int lo) { char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_hist_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), o); delete []o; return r; } //----------------------------------------------------------------------------- MGL_EXPORT_CONST const char *mgl_get_fit(HMGL ) { return mglFitRes; } int MGL_EXPORT mgl_get_fit_(uintptr_t *gr, char *out, int len) { const char *res = mgl_get_fit(_GR_); if(out) mgl_strncpy(out,res,len); return strlen(res); } //----------------------------------------------------------------------------- uintptr_t MGL_EXPORT mgl_fit_1_(uintptr_t* gr, uintptr_t* y, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_1(_GR_, _DA_(y), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_2_(uintptr_t* gr, uintptr_t* z, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_2(_GR_, _DA_(z), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_3_(uintptr_t* gr, uintptr_t* a, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_3(_GR_, _DA_(a), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_xy_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_xy(_GR_, _DA_(x), _DA_(y), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_xyz_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_xyza_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* a, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_xyza(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_ys_(uintptr_t* gr, uintptr_t* y, uintptr_t* ss, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_ys(_GR_, _DA_(y), _DA_(ss), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_xys_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* ss, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_xys(_GR_, _DA_(x), _DA_(y), _DA_(ss), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_xyzs_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* ss, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_xyzs(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ss), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } uintptr_t MGL_EXPORT mgl_fit_xyzas_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* a, uintptr_t* ss, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo) { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0; char *d=new char[n+1]; memcpy(d,var,n); d[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; uintptr_t r = (uintptr_t)mgl_fit_xyzas(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(ss), s, d, _DM_(ini), o); delete []o; delete []s; delete []d; return r; } //----------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/parser.cpp�������������������������������������������������������������������������0000644�0001750�0001750�00000146100�13513030041�015736� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * parse.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/parser.h" #include "mgl2/canvas_cf.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- int MGL_LOCAL_PURE mgl_cmd_cmp(const void *a, const void *b) { const mglCommand *aa = (const mglCommand *)a; const mglCommand *bb = (const mglCommand *)b; return strcmp(aa->name, bb->name); } //----------------------------------------------------------------------------- mglCommand *mglParser::BaseCmd=NULL; ///< Base table of MGL commands. It MUST be sorted by 'name'!!! void mglParser::FillBaseCmd() { if(BaseCmd) return; size_t na=0, nd=0, ng=0, np=0, ns=0, nsum=0; while(mgls_prg_cmd[na].name[0]) na++; while(mgls_dat_cmd[nd].name[0]) nd++; while(mgls_grf_cmd[ng].name[0]) ng++; while(mgls_prm_cmd[np].name[0]) np++; while(mgls_set_cmd[ns].name[0]) ns++; BaseCmd = new mglCommand[na+nd+ng+np+ns+1]; memcpy(BaseCmd, mgls_prg_cmd, na*sizeof(mglCommand)); nsum+=na; memcpy(BaseCmd+nsum,mgls_dat_cmd, nd*sizeof(mglCommand)); nsum+=nd; memcpy(BaseCmd+nsum,mgls_grf_cmd, ng*sizeof(mglCommand)); nsum+=ng; memcpy(BaseCmd+nsum,mgls_prm_cmd, np*sizeof(mglCommand)); nsum+=np; memcpy(BaseCmd+nsum,mgls_set_cmd, (ns+1)*sizeof(mglCommand)); nsum+=ns; qsort(BaseCmd, nsum, sizeof(mglCommand), mgl_cmd_cmp); #if DEBUG long stat[17]; memset(stat,0,17*sizeof(long)); const char *name[17] = { _("0 - special plot"), _("1 - other plot"), _("2 - setup"), _("3 - data handle"), _("4 - data create"), _("5 - subplot"), _("6 - program flow"), _("7 - 1d plot"), _("8 - 2d plot"), _("9 - 3d plot"), _("10 - dd plot"), _("11 - vector plot"), _("12 - axis"), _("13 - primitives"), _("14 - axis setup"), _("15 - text/legend"), _("16 - data transform") }; for(size_t i=0;BaseCmd[i].name[0];i++) stat[BaseCmd[i].type]+=1; for(size_t i=0;i<17;i++) printf("%s: %ld\n",name[i],stat[i]); printf("\n"); fflush(stdout); #endif } //----------------------------------------------------------------------------- HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring string, mglParser *arg, const std::vector &head); HADT MGL_NO_EXPORT mglFormulaCalcC(std::wstring string, mglParser *arg, const std::vector &head); //----------------------------------------------------------------------------- MGL_EXPORT void (*mgl_ask_func)(const wchar_t *, wchar_t *)=0; void MGL_EXPORT mgl_ask_gets(const wchar_t *quest, wchar_t *res) { printf("%ls\n",quest); if(!fgetws(res,1024,stdin)) *res=0; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_progress_txt(int value, int maximal, HMGL) { static int prev = 0; if(value<=0 || value>=maximal) { printf("\n"); value=0; } else for(int i=prev;i9) narg=0; } //----------------------------------------------------------------------------- long mglParser::IsFunc(const wchar_t *name, int *na) { for(size_t i=0;i' ') return; long i; for(i=4;line[i]<=' ' || line[i]=='\'';i++); func.push_back(mglFunc(num-1, line+i)); } //----------------------------------------------------------------------------- MGL_NO_EXPORT wchar_t *mgl_str_copy(const char *s) { size_t i,l=strlen(s); wchar_t *str = new wchar_t[l+1]; for(i=0;i:")!=std::wstring::npos || s==L"rnd" || FindNum(s.c_str()); // return !isalpha(s[0])||s.find_first_of(L".:()")!=std::wstring::npos; } //----------------------------------------------------------------------------- const mglCommand *mglParser::FindCommand(const char *com) const { if(!AllowFileIO && ( !strncmp(com,"read",4) || !strncmp(com,"save",4) || !strcmp(com,"fgets") || !strcmp(com,"import") || !strcmp(com,"export") )) return 0; mglCommand tst, *rts, *cmd = Cmd; long i; for(i=0;cmd[i].name[0];i++); // determine the number of symbols tst.name = com; rts = (mglCommand *) bsearch(&tst, cmd, i, sizeof(mglCommand), mgl_cmd_cmp); return rts; } //----------------------------------------------------------------------------- const mglCommand *mglParser::FindCommand(const wchar_t *com) const { char cmd[33]=""; size_t s = wcstombs(0,com,0); // NOTE: command name should be less than 32 if(s<32) { wcstombs(cmd,com,s+1); cmd[s]=0; } return FindCommand(cmd); } //----------------------------------------------------------------------------- // return values : 0 -- OK, 1 -- wrong arguments, 2 -- wrong command, 3 -- unclosed string int mglParser::Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const std::wstring &/*var*/, const wchar_t *opt) { const char *id="dsn"; std::string k; for(long i=0;iexec) return 2; /* if(rts->type == 4) { if(n<1 || CheckForName(var)) return 2; a[0].type = 0; a[0].d = AddVar(var.c_str()); a[0].w = var; k[0] = 'd'; }*/ std::string vopt; if(opt && *opt) // TODO: parse arguments of options { size_t len = mgl_wcslen(opt); std::vector ss; std::wstring s, o; bool st = true, name = true; for(size_t i=0;i' ') alph=true; if(alph && s[k]<=' ') break; } HMDT d1 = mglFormulaCalc(s.substr(j+1,k-j),this, DataList); HMDT d2 = mglFormulaCalc(s.substr(k+1),this, DataList); mglprintf(buf,64,L" %g %g",d1->a[0],d2->a[0]); s = o+buf; delete d1; delete d2; } else if(o!=L"legend") // 1 argument { HMDT dd = mglFormulaCalc(s.substr(j+1),this, DataList); mglprintf(buf,64,L" %g",dd->a[0]); s = o+buf; delete dd; } st = name = true; ss.push_back(s); o.clear(); s.clear(); } } for(size_t i=0;iexec(gr, n, a, k.c_str(), vopt.c_str()); return res; } //----------------------------------------------------------------------------- mglParser::mglParser(bool setsize) { InUse = 1; curGr = 0; Variant = 0; Skip=Stop=false; StarObhID = 0; for(long i=0;i<40;i++) par[i]=L""; FillBaseCmd(); Cmd = BaseCmd; AllowSetSize=setsize; AllowFileIO=true; AllowDllCall=true; Once = true; mglNum *v; v = new mglNum(0); v->s = L"off"; NumList.push_back(v); v = new mglNum(1); v->s = L"on"; NumList.push_back(v); v = new mglNum(-1); v->s = L"all"; NumList.push_back(v); v = new mglNum(NAN); v->s = L"nan"; NumList.push_back(v); v = new mglNum(M_PI); v->s = L"pi"; NumList.push_back(v); v = new mglNum(INFINITY); v->s = L"inf"; NumList.push_back(v); #if MGL_HAVE_LTDL lt_dlinit(); #endif } //----------------------------------------------------------------------------- mglParser::~mglParser() { DeleteAll(); for(size_t i=0;is = L"off"; NumList.push_back(v); v = new mglNum(1); v->s = L"on"; NumList.push_back(v); v = new mglNum(-1); v->s = L"all"; NumList.push_back(v); v = new mglNum(NAN); v->s = L"nan"; NumList.push_back(v); v = new mglNum(M_PI); v->s = L"pi"; NumList.push_back(v); v = new mglNum(INFINITY); v->s = L"inf"; NumList.push_back(v); if(Cmd && Cmd!=BaseCmd) { delete []Cmd; Cmd = BaseCmd; } #if MGL_HAVE_LTDL for(size_t i=0;i=0 && n<40 && !wcschr(str,'$')) par[n] = str; if(str && n>=0 && n<40) par[n] = str; } //----------------------------------------------------------------------------- mglDataA *mglParser::FindVar(const wchar_t *name) { if(name[0]=='!') name = name+1; // ignore complex prefix for(size_t i=0;iName(),name)) return DataList[i]; return 0; } //----------------------------------------------------------------------------- mglDataA *mglParser::AddVar(const wchar_t *name) { // TODO add list of forbidden names (like function names) mglDataA *d=FindVar(name); if(name[0]=='!' && dynamic_cast(d)==0) { d = new mglDataC; d->Name(name+1); DataList.push_back(d); } else if(!d) { d = new mglData; d->Name(name); DataList.push_back(d); } return d; } //----------------------------------------------------------------------------- mglNum *mglParser::FindNum(const wchar_t *name) { for(size_t i=0;is==name) return NumList[i]; return 0; } //----------------------------------------------------------------------------- mglNum *mglParser::AddNum(const wchar_t *name) { mglNum *v = FindNum(name); if(!v) { v=new mglNum; v->s = name; NumList.push_back(v); } return v; } //----------------------------------------------------------------------------- int MGL_LOCAL_PURE mglFindArg(const std::wstring &str) { long l=0,k=0; const size_t s=str.length(); for(size_t i=0;i s; std::vector id; // 0 - string, 1 - cval, 2 - rval, 3 - plus, 4 - index for(long i=1;iii) { id.push_back(op); s.push_back(str.substr(ii,i-ii)); } na++; ii=i+1; op=0; } else if(na%2==0 && ns==0 && np==0) { if(str[i]=='+' && str[i-1]=='\'') { op=3; ii=i+1; } else if(str[i]==',' && str[i+1]=='!') { if(op && i>ii) { id.push_back(op); s.push_back(str.substr(ii,i-ii)); } op=1; ii=i+2; } else if(str[i]==',') { if(op && i>ii) { id.push_back(op); s.push_back(str.substr(ii,i-ii)); } op=2; ii=i+1; } else if(str[i]=='[' && str[i-1]=='\'') { ii=i+1; ns++; } else if(str[i]=='(') np++; } else if(na%2==0 && np==0 && str[i]==']' && ns==1) { id.push_back(4); s.push_back(str.substr(ii,i-ii)); op=0; ii=i+1; ns--; } else if(na%2==0 && np==1 && str[i]==')' && ns==0) np--; } if(op && ll>ii) { id.push_back(op); s.push_back(str.substr(ii,ll-ii)); } wchar_t buf[32]; for(size_t i=0;ia[0]), dr = real(d->a[0]); if(di>0) mglprintf(buf,32,L"%g+%gi",dr,di); else if(di<0) mglprintf(buf,32,L"%g-%gi",dr,-di); // TODO use \u2212 ??? else mglprintf(buf,32,L"%g",dr); a[n-1].s += buf; delete d; } else if(id[i]==2) { HMDT d = mglFormulaCalc(s[i], this, DataList); mglprintf(buf,32,L"%g",d->a[0]); a[n-1].s += buf; delete d; } else if(id[i]==3) { HMDT d = mglFormulaCalc(s[i], this, DataList); a[n-1].s[a[n-1].s.length()-1] += d->a[0]; delete d; } else if(id[i]==4) { HMDT d = mglFormulaCalc(s[i], this, DataList); long v = long(d->a[0]+0.5); delete d; if(v>=0 && vName(a[n-1].s.w); ParseDat(gr, s, *u); a[n-1].d = u; u->temp=true; DataList.push_back(u); } else if((v = FindVar(str.c_str()))!=0) // try to find normal variables (for data creation) { a[n-1].type=0; a[n-1].d=v; a[n-1].s=v->Name(); } else if((f = FindNum(str.c_str()))!=0) // try to find normal number (for data creation) { a[n-1].type=2; a[n-1].d=0; a[n-1].v=f->d; a[n-1].c=f->c; a[n-1].s = f->s; } else if(str[0]=='!') // complex array is asked { // parse all numbers and formulas by unified way HADT d = mglFormulaCalcC(str.substr(1), this, DataList); if(d->GetNN()==1) { if(CheckForName(str.substr(1))) { a[n-1].type = 2; a[n-1].v = d->v(0); a[n-1].c = d->a[0]; } else { a[n-1].type = 0; a[n-1].d = AddVar(str.c_str()); } delete d; } else { a[n-1].s = L"/*"+str+L"*/"; d->temp=true; DataList.push_back(d); a[n-1].type = 0; a[n-1].d = d; } } else { // parse all numbers and formulas by unified way HMDT d = mglFormulaCalc(str, this, DataList); if(d->GetNN()==1) { if(CheckForName(str)) { a[n-1].type = 2; a[n-1].c = a[n-1].v = d->v(0); } else { a[n-1].type = 0; a[n-1].d = AddVar(str.c_str()); } delete d; } else { a[n-1].s = L"/*"+str+L"*/"; d->temp=true; DataList.push_back(d); a[n-1].type = 0; a[n-1].d = d; } } } } //----------------------------------------------------------------------------- // return values: 0 - not found, 1 - OK, 2 - wrong arguments, 3 - wrong command, 4 - string too long int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a) { long n=0; if(!arg[0].compare(L"list")) // parse command "list" { if(k<3 || CheckForName(arg[1])) return 2; long nx=0, ny=1,j=0,i,t=0; for(i=2;inx ? j:nx; j=0; ny++; } } mglDataA *vv = AddVar(arg[1].c_str()); mglData *v = dynamic_cast(vv); mglDataC *vc = dynamic_cast(vv); if(v) { if(t==1) nx = j>nx ? j:nx; if(t==1) // list of numeric values { v->Create(nx,ny); j=t=0; for(i=2;ia[j+nx*t] = a[i-1].v; j++; } } } if(t==2) // list of data { v->Set(a[1].d); for(long i=2;iJoin(*(a[i].d)); } n=1; } if(vc) { if(t==1) nx = j>nx ? j:nx; if(t==1) // list of numeric values { vc->Create(nx,ny); j=t=0; for(i=2;ia[j+nx*t] = a[i-1].c; j++; } } } if(t==2) // list of data { vc->Set(a[1].d); for(long i=2;iJoin(*(a[i].d)); } n=1; } } return n; } //----------------------------------------------------------------------------- void mglParser::PutArg(std::wstring &str, bool def) { size_t pos = str.find('$',def?10:0); while(pos='0' && ch<='9') str.replace(pos,2,par[ch-'0'].w); else if(ch>='a' && ch<='z') str.replace(pos,2,par[ch-'a'+10].w); else if(ch=='$') str.replace(pos,2,L"\uffff"); else str.replace(pos,1,L"\uffff"); pos = str.find('$',def?10:0); } while((pos = str.find(L'\uffff'))' ') break; for(i=n;i>k;i--) if(str[i-1]>' ') break; return str.substr(k,i-k); } //----------------------------------------------------------------------------- int mglParser::ParseDef(std::wstring &str) { if(!skip() && !str.compare(0,3,L"def") && (str[6]==' ' || str[6]=='\t')) { int res = 1; mreal d; PutArg(str,true); size_t end; bool ss=false; for(end=7;str[end] && (str[end]!='#' || ss);end++) { if(str[end]=='\'') ss=!ss; } const std::wstring s = mgl_trim_ws(str.substr(7,end-7)); if(!str.compare(3,3,L"ine")) { int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1); if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10) { AddParam(nn, mgl_trim_ws(s.substr(2)).c_str()); return 1; } } if(!str.compare(3,3,L"num")) { int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1); if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10) { res = 0; HMDT dd = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList); d = dd->a[0]; delete dd; AddParam(nn, mgl_str_num(d).c_str()); } return res+1; } if(!str.compare(3,3,L"chr")) { int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1); if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10) { res = 0; HMDT dd = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList); d=dd->a[0]; delete dd; wchar_t buf[2]={0,0}; buf[0] = wchar_t(d); AddParam(nn, buf); } return res+1; } } if(!skip() && !str.compare(0,3,L"ask") && (str[3]==' ' || str[3]=='\t')) { PutArg(str,true); std::wstring s = mgl_trim_ws(str.substr(4)); int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1); if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10) { s = mgl_trim_ws(s.substr(2)); if(s[0]=='\'') s=s.substr(1,s.length()-2); if(mgl_ask_func) { static wchar_t res[1024]; mgl_ask_func(s.c_str(),res); if(*res) AddParam(nn, res); } return mgl_ask_func?1:2; } else return 2; } if(!skip() && !str.compare(0,3,L"for") && (str[3]==' ' || str[3]=='\t')) { size_t i; for(i=4;str[i]<=' ';i++); // if command have format 'for $N ...' then change it to 'for N ...' if(str[i]=='$' && str[i+1]>='0' && str[i+1]<='9') str[i] = ' '; if(str[i]=='$' && str[i+1]>='a' && str[i+1]<='z') str[i] = ' '; } return 0; } //----------------------------------------------------------------------------- // return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string int mglParser::Parse(mglGraph *gr, std::wstring str, long pos) { if(Stop || gr->NeedStop()) return 0; curGr = gr->Self(); gr->pr = this; str=mgl_trim_ws(str); long n,k=0,m=0,mm=0,res; // try parse ':' -- several commands in line for(n=0;n arg; while(!str.empty()) // parse string to substrings (by spaces) { n = mglFindArg(str); if(n<1) // this is option { if(str[-n]==';') opt = str.substr(-n+1); if(n<0) str = str.substr(0,-n); break; } arg.push_back(str.substr(0,n)); str = mgl_trim_ws(str.substr(n+1)); } // try to find last argument if(str[0]!=0 && str[0]!='#' && str[0]!=';') arg.push_back(str); k = arg.size(); if(k<1) n = 0; else { // fill arguments by its values mglArg *a = new mglArg[k]; FillArg(gr, k, &(arg[0]), a); // execute first special (program-flow-control) commands if(!skip() && !arg[0].compare(L"stop")) { Stop = true; delete []a; return 0; } if(!arg[0].compare(L"func")) { Stop = true; delete []a; return 0; } n = FlowExec(gr, arg[0].c_str(),k-1,a); if(n) { delete []a; return n-1; } if(skip()) { delete []a; return 0; } if(!arg[0].compare(L"define")) { if(k==3) { DeleteVar(arg[1].c_str()); // force to delete variable with the same name mglNum *v=AddNum(arg[1].c_str()); if(arg[2][0]=='!') // complex number is added { HADT dd = mglFormulaCalcC(arg[2].substr(1),this, DataList); v->d=NAN; v->c = dd->a[0]; delete dd; } else { HMDT dd = mglFormulaCalc(arg[2],this, DataList); v->c = v->d = dd->a[0]; delete dd; } } delete []a; return k==3?0:1; } if(!arg[0].compare(L"call")) { n = 1; if(a[0].type==1) { int na=0; n=-IsFunc(a[0].s.w,&na); if(n && k!=na+2) { char buf[64]; snprintf(buf,64,_("Bad arguments for %ls: %ld instead of %d\n"), a[0].s.w,k-2,na); buf[63]=0; gr->SetWarn(-1,buf); n = 1; } else if(n) { mglFnStack fn; fn.pos = pos; fn.stk = stack.size(); for(int i=0;i<10;i++) { fn.par[i] = par[i]; par[i]=L""; } for(int i=1;iDataList.swap(DataList); prs->NumList.swap(NumList); prs->Cmd=Cmd; for(int i=10;i<30;i++) prs->AddParam(i,par[i].w); prs->Execute(gr,fp); for(int i=10;i<30;i++) AddParam(i,prs->par[i].w); DataList.swap(prs->DataList); NumList.swap(prs->NumList); prs->Cmd=0; delete prs; fclose(fp); } else n=1; } } delete []a; return n; } if(!arg[0].compare(L"if") && k>3 && !arg[2].compare(L"then")) { bool cond=false; n=0; if(a[0].type==2) cond = (a[0].v!=0); else if(a[0].type==0) { cond = a[0].d->FindAny((m>1 && a[1].type==1) ? a[1].s.s:"u"); } if(cond) { // alocate new arrays and execute the command itself n = FlowExec(gr, arg[3].c_str(),k-4,a+3); if(!n && !skip()) { n = PreExec(gr, k-4, &(arg[3]), a+3); if(n>0) n--; else if(!arg[3].compare(L"setsize") && !AllowSetSize) n = 2; else n = Exec(gr, arg[3].c_str(),k-4,a+3, k>3?arg[4]:L"", opt.c_str()); } else n = skip()?0:n-1; } delete []a; DeleteTemp(); return n; } if(!arg[0].compare(L"do")) { mglPosStack st(MGL_ST_LOOP); st.pos = pos; st.par = -1; st.ind = -1; stack.push_back(st); delete []a; return n; } if(!arg[0].compare(L"for")) { if(k<2) { delete []a; return 1; } n = 1; char ch = arg[1][0]; int r = ch-'0'; if(ch>='a' && ch<='z') r = 10+ch-'a'; // int r = int(a[0].v); mglPosStack st(MGL_ST_LOOP); if(arg[1][1]==0 && (r>=0 && r<40)) { if(a[1].type==0) { st.v = *(a[1].d); n=0; } else if(a[1].type==2 && a[2].type==2 && a[2].v>=a[1].v) { mreal step = a[3].type==2?a[3].v:1; mm = int(step>0 ? (a[2].v-a[1].v)/step : 0); if(mm>=0) { n=0; st.v.Create(mm+1); for(int ii=0;ii0) n--; else if(!arg[0].compare(L"setsize") && !AllowSetSize) n = 2; else n = Exec(gr, arg[0].c_str(),k-1,a, k>1?arg[1]:L"", opt.c_str()); delete []a; } DeleteTemp(); return n; } //----------------------------------------------------------------------------- // return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string int mglParser::ParseDat(mglGraph *gr, std::wstring str, mglData &res) { std::wstring arg[32]; str = mgl_trim_ws(str); long n,k=0; for(k=0;k<32;k++) // parse string to substrings (by spaces) { n = mglFindArg(str); if(n<1) { if(n<0) str=str.substr(0,-n); break; } arg[k] = str.substr(0,n);// k++; str = str.substr(n+1); str = mgl_trim_ws(str); } // try to find last argument if(!str.empty() && k<32) { arg[k] = str; k++; } if(k<1) n = 0; else { // fill arguments by its values mglArg *a = new mglArg[k+1]; FillArg(gr, k, arg, a+1); a[0].type=0; a[0].d=&res; // alocate new arrays and execute the command itself int i; std::string kk; const char *id="dsn"; for(i=0;itype!=4) n = 2; else n = rts->exec(gr, k, a, kk.c_str(), 0); delete []a; } return n; } //----------------------------------------------------------------------------- int mglParser::FlowExec(mglGraph *, const std::wstring &com, long m, mglArg *a) { int n=-1; if(!ifskip() && !com.compare(L"once")) { if(a[0].type==2) { n = 0; if(a[0].v) Skip = !Once; else Skip = Once = false; } else n = 1; } else if(!Skip && !com.compare(L"if")) { bool cond=0; n=1; if(m>2 && a[1].type==0 && !wcscmp(a[1].d->Name(),L"then")) { n = -1; a[1].d->temp=true; } // NOTE: ugly hack :( else if(a[0].type==2) { n = 0; cond = (a[0].v!=0); } else n = TestCond(m, a[0], a[1], cond); if(n==0) { mglPosStack st(cond?MGL_ST_TRUE:MGL_ST_FALSE); stack.push_back(st); } } else if(!Skip && !com.compare(L"while")) { n=1; if(stack.size()) { mglPosStack &st = stack.back(); if(st.state==MGL_ST_LOOP) { bool cond = false; n = TestCond(m, a[0], a[1], cond); if(cond) { if(st.ind<0) n = -st.pos-1; // do-while loop else if(st.ind0;i--) if(stack[i-1].state==MGL_ST_LOOP) { nf=false; stack[i-1].state=MGL_ST_BREAK; break; } n = nf?1:0; } else if(!ifskip() && !Skip && !com.compare(L"next")) { n=1; if(stack.size()) { mglPosStack &st = stack.back(); if(st.state==MGL_ST_LOOP) { if(st.ind<0) n = -st.pos-1; // do-while loop else if(st.ind0;i--) { mglPosStack &st = stack[i-1]; if(st.state==MGL_ST_LOOP) { if(st.ind<0) n = -st.pos-1; // do-while loop else if(st.indMessage()); } //----------------------------------------------------------------------------- void mglParser::Execute(mglGraph *gr, int n, const wchar_t **text) { if(n<1 || text==0) return; long res=0; char buf[64]; Skip=false; ScanFunc(0); fn_stack.clear(); stack.clear(); for(long i=0;iSetWarn(-1, ""); gr->SetObjId(i+1+StarObhID); long r = Parse(gr,text[i],i+1); if(r<0) { i = -r-2; continue; } if(r==1) snprintf(buf,64,_("\nWrong argument(s) in line %ld"), i+1); else if(r==2) snprintf(buf,64,_("\nWrong command in line %ld"), i+1); else if(r==3) snprintf(buf,64,_("\nString too long in line %ld"), i+1); else if(r==4) snprintf(buf,64,_("\nUnbalanced ' in line %ld"), i+1); else if(r==5) snprintf(buf,64,_("\nChange temporary data in line %ld"), i+1); else if(gr->GetWarn()>0) snprintf(buf,64,_("in line %ld"), i+1); else *buf=0; buf[63] = 0; if(*buf) gr->SetWarn(-2,buf); if(r>0 && r<5) res=r; } int code[]={mglScrArg, mglScrCmd, mglScrLong, mglScrStr, mglScrTemp}; if(res>0) gr->SetWarn(code[res-1],_("MGL Parser")); } //----------------------------------------------------------------------------- void mglParser::Execute(mglGraph *gr, const wchar_t *text) { size_t s = mgl_wcslen(text)+1, n=1; wchar_t *wcs = new wchar_t[s]; const wchar_t **str; for(size_t i=0;i' ')next = 0; if(text[i]=='\n') { // if string need to be continued then I but ' ' instead of 0x0 and // pointer next string to 0x0. Last one for keeping number of strings. if(next) { for(size_t ii=next;ii<=i;ii++) wcs[ii]='\b'; str[n] = wcs+s-1; next=0; } else { wcs[i]=0; str[n] = wcs+i+1; } n++; } } Execute(gr, n, str); delete []wcs; free(str); } //----------------------------------------------------------------------------- void mglParser::Execute(mglGraph *gr, const char *text) { MGL_TO_WCS(text, Execute(gr, wcs)); } //----------------------------------------------------------------------------- void mglParser::DeleteVar(const char *name) { MGL_TO_WCS(name,DeleteVar(wcs)); } //----------------------------------------------------------------------------- void mglParser::DeleteVar(const wchar_t *name) { for(size_t i=0;iName(),name)) { mglDataA *u=DataList[i]; DataList[i]=0; delete u; } } //----------------------------------------------------------------------------- void mglParser::AddCommand(const mglCommand *cmd) { // determine the number of symbols size_t mp=0; while(Cmd[mp].name[0]) mp++; size_t mc=0; while(cmd[mc].name[0]) mc++; // copy all together mglCommand *buf = new mglCommand[mp+mc+1]; memcpy(buf, cmd, mc*sizeof(mglCommand)); memcpy(buf+mc, Cmd, (mp+1)*sizeof(mglCommand)); qsort(buf, mp+mc, sizeof(mglCommand), mgl_cmd_cmp); // sort it #pragma omp critical(cmd_parser) { if(Cmd!=BaseCmd) delete []Cmd; Cmd = buf; } } //----------------------------------------------------------------------------- HMPR MGL_EXPORT mgl_create_parser() { return new mglParser; } void MGL_EXPORT mgl_delete_parser(HMPR p) { delete p; } void MGL_EXPORT mgl_parser_add_param(HMPR p, int id, const char *str) { p->AddParam(id,str); } void MGL_EXPORT mgl_parser_add_paramw(HMPR p, int id, const wchar_t *str) { p->AddParam(id,str); } MGL_EXPORT mglDataA *mgl_parser_add_var(HMPR p, const char *name) { return p->AddVar(name); } MGL_EXPORT_PURE mglDataA *mgl_parser_find_var(HMPR p, const char *name) { return p->FindVar(name);} void MGL_EXPORT mgl_parser_del_var(HMPR p, const char *name) { p->DeleteVar(name); } MGL_EXPORT mglDataA *mgl_parser_add_varw(HMPR p, const wchar_t *name) { return p->AddVar(name); } MGL_EXPORT_PURE mglDataA *mgl_parser_find_varw(HMPR p, const wchar_t *name) { return p->FindVar(name);} void MGL_EXPORT mgl_parser_del_varw(HMPR p, const wchar_t *name) { p->DeleteVar(name); } int MGL_EXPORT mgl_parse_line(HMGL gr, HMPR p, const char *str, int pos) { return p->Parse(gr, str, pos); } int MGL_EXPORT mgl_parse_linew(HMGL gr, HMPR p, const wchar_t *str, int pos) { return p->Parse(gr, str, pos); } void MGL_EXPORT mgl_parse_text(HMGL gr, HMPR p, const char *str) { p->Execute(gr, str); } void MGL_EXPORT mgl_parse_textw(HMGL gr, HMPR p, const wchar_t *str) { p->Execute(gr, str); } void MGL_EXPORT mgl_parse_file(HMGL gr, HMPR p, FILE *fp, int print) { p->Execute(gr,fp,print); } void MGL_EXPORT mgl_parser_restore_once(HMPR p) { p->RestoreOnce(); } void MGL_EXPORT mgl_parser_stop(HMPR p) { p->Stop = true; } void MGL_EXPORT mgl_parser_allow_setsize(HMPR p, int a) { p->AllowSetSize= a; } void MGL_EXPORT mgl_parser_allow_file_io(HMPR p, int a) { p->AllowFileIO = a; } void MGL_EXPORT mgl_parser_allow_dll_call(HMPR p, int a){ p->AllowDllCall = a; } //----------------------------------------------------------------------------- #define _PR_ ((mglParser *)(*p)) uintptr_t MGL_EXPORT mgl_create_parser_() { return uintptr_t(new mglParser); } void MGL_EXPORT mgl_delete_parser_(uintptr_t* p) { delete _PR_; } void MGL_EXPORT mgl_parser_add_param_(uintptr_t* p, int *id, const char *str, int l) { char *s=new char[l+1]; memcpy(s,str,l); s[l]=0; _PR_->AddParam(*id, s); delete []s; } /*===!!! NOTE !!! You must not delete obtained data arrays !!!===============*/ uintptr_t MGL_EXPORT mgl_parser_add_var_(uintptr_t* p, const char *name, int l) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; mglDataA *v=_PR_->AddVar(s); delete []s; return uintptr_t(v); } /*===!!! NOTE !!! You must not delete obtained data arrays !!!===============*/ uintptr_t MGL_EXPORT mgl_parser_find_var_(uintptr_t* p, const char *name, int l) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; mglDataA *v=_PR_->FindVar(s); delete []s; return uintptr_t(v); } void MGL_EXPORT mgl_parser_del_var_(uintptr_t* p, const char *name, int l) { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0; _PR_->DeleteVar(s); delete []s; } int MGL_EXPORT mgl_parse_line_(uintptr_t* gr, uintptr_t* p, const char *str, int *pos, int l) { char *s=new char[l+1]; memcpy(s,str,l); s[l]=0; int r = _PR_->Parse(_GR_, s, *pos); delete []s; return r; } void MGL_EXPORT mgl_parse_text_(uintptr_t* gr, uintptr_t* p, const char *str, int l) { char *s=new char[l+1]; memcpy(s,str,l); s[l]=0; _PR_->Execute(_GR_, s); delete []s; } void MGL_EXPORT mgl_parser_restore_once_(uintptr_t* p) { _PR_->RestoreOnce(); } void MGL_EXPORT mgl_parser_allow_setsize_(uintptr_t* p, int *a) { _PR_->AllowSetSize= *a; } void MGL_EXPORT mgl_parser_allow_file_io_(uintptr_t* p, int *a) { _PR_->AllowFileIO = *a; } void MGL_EXPORT mgl_parser_allow_dll_call_(uintptr_t* p, int *a){ _PR_->AllowDllCall= *a; } void MGL_EXPORT mgl_parser_stop_(uintptr_t* p) { _PR_->Stop = true; } //----------------------------------------------------------------------------- long MGL_EXPORT mgl_use_parser(HMPR pr, int inc) { pr->InUse+=inc; return pr->InUse; } long MGL_EXPORT mgl_use_parser_(uintptr_t *p, int *inc) { _PR_->InUse+=*inc; return _PR_->InUse; } //--------------------------------------------------------------------------- MGL_EXPORT_PURE mglDataA *mgl_parser_get_var(HMPR p, unsigned long id) { return idDataList.size()?p->DataList[id]:0; } uintptr_t MGL_EXPORT_PURE mgl_parser_get_var_(uintptr_t* p, unsigned long *id) { return uintptr_t(mgl_parser_get_var(_PR_,*id)); } long MGL_EXPORT_PURE mgl_parser_num_var(HMPR p) { return p->DataList.size(); } long MGL_EXPORT_PURE mgl_parser_num_var_(uintptr_t* p) { return mgl_parser_num_var(_PR_); } long MGL_EXPORT_PURE mgl_parser_num_const(HMPR p) { return p->NumList.size(); } long MGL_EXPORT_PURE mgl_parser_num_const_(uintptr_t* p) { return mgl_parser_num_const(_PR_); } MGL_EXPORT_PURE mglNum *mgl_parser_get_const(HMPR p, unsigned long id) { return idNumList.size()?p->NumList[id]:0; } uintptr_t MGL_EXPORT_PURE mgl_parser_get_const_(uintptr_t* p, unsigned long *id) { return uintptr_t(mgl_parser_get_const(_PR_,*id)); } //--------------------------------------------------------------------------- int MGL_EXPORT_PURE mgl_parser_cmd_type(HMPR pr, const char *name) { const mglCommand *cmd = pr->FindCommand(name); return cmd ? cmd->type + 1 : 0; } int MGL_EXPORT_PURE mgl_parser_cmd_type_(uintptr_t* p, const char *str, int l) { char *s=new char[l+1]; memcpy(s,str,l); s[l]=0; l = mgl_parser_cmd_type(_PR_, s); delete []s; return l; } //--------------------------------------------------------------------------- MGL_EXPORT_PURE const char *mgl_parser_cmd_desc(HMPR pr, const char *name) { const mglCommand *cmd = pr->FindCommand(name); return cmd ? cmd->desc : 0; } MGL_EXPORT_PURE const char *mgl_parser_cmd_frmt(HMPR pr, const char *name) { const mglCommand *cmd = pr->FindCommand(name); return cmd ? cmd->form : 0; } //--------------------------------------------------------------------------- MGL_EXPORT_PURE const char *mgl_parser_cmd_name(HMPR pr, long id) { return (id=0) ? pr->Cmd[id].name:""; } long MGL_EXPORT_PURE mgl_parser_cmd_num(HMPR pr) { long i=0; while(pr->Cmd[i].name[0]) i++; return i; } //--------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_parser_calc(HMPR pr, const char *formula) { HMDT d=0; MGL_TO_WCS(formula,d = mgl_parser_calcw(pr,wcs)); return d; } HMDT MGL_EXPORT mgl_parser_calcw(HMPR pr, const wchar_t *formula) { return mglFormulaCalc(formula,pr, pr->DataList); } uintptr_t MGL_EXPORT mgl_parser_calc_(uintptr_t *p, const char *str,int l) { char *s=new char[l+1]; memcpy(s,str,l); s[l]=0; uintptr_t d = (uintptr_t)mgl_parser_calc(_PR_, s); delete []s; return d; } //--------------------------------------------------------------------------- HADT MGL_EXPORT mgl_parser_calc_complex(HMPR pr, const char *formula) { HADT d=0; MGL_TO_WCS(formula,d = mgl_parser_calc_complexw(pr,wcs)); return d; } HADT MGL_EXPORT mgl_parser_calc_complexw(HMPR pr, const wchar_t *formula) { return mglFormulaCalcC(formula,pr, pr->DataList); } uintptr_t MGL_EXPORT mgl_parser_calc_complex_(uintptr_t *p, const char *str,int l) { char *s=new char[l+1]; memcpy(s,str,l); s[l]=0; uintptr_t d = (uintptr_t)mgl_parser_calc_complex(_PR_, s); delete []s; return d; } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_parser_del_all(HMPR p) { p->DeleteAll(); } void MGL_EXPORT mgl_parser_del_all_(uintptr_t *p) { _PR_->DeleteAll(); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_parser_load(HMPR pr, const char *so_name) { if(!pr->AllowDllCall) return; #if MGL_HAVE_LTDL lt_dlhandle so = lt_dlopen(so_name); if(!so) return; const mglCommand *cmd = (const mglCommand *)lt_dlsym(so,"mgl_cmd_extra"); bool exist = true; if(cmd) for(size_t i=0;cmd[i].name[0];i++) if(!pr->FindCommand(cmd[i].name)) exist=false; if(exist) { lt_dlclose(so); return; } // all commands already presents else pr->DllOpened.push_back(so); pr->AddCommand(cmd); #endif } void MGL_EXPORT mgl_parser_load_(uintptr_t *p, const char *dll_name,int l) { char *s=new char[l+1]; memcpy(s,dll_name,l); s[l]=0; mgl_parser_load(_PR_, s); delete []s; } //--------------------------------------------------------------------------- struct mglRKdat { mglDataA *v; std::wstring e; bool cmplx; mglDataC cin,c1,c2,c3,c4, *cc; mglData din,d1,d2,d3,d4, *dd; mglRKdat(mglDataA *var, std::wstring &eq):v(var), e(eq) { cmplx = dynamic_cast(var); cc=0; dd=0; } void allocate() { if(cmplx) { cc = dynamic_cast(v); cin.Set(v); } else { dd = dynamic_cast(v); din.Set(v); } } }; void MGL_EXPORT mgl_rk_step_w(HMPR pr, const wchar_t *Eqs, const wchar_t *Vars, mreal dt) { const std::wstring eqs(Eqs); const std::wstring vars(Vars); std::vector rkv; size_t iv=0,jv=0,ie=0,je=0; while(1) { iv = vars.find(';',jv); ie = eqs.find(';',je); mglDataA *vv=mgl_parser_find_varw(pr,vars.substr(jv,iv-jv).c_str()); std::wstring eq = eqs.substr(je,ie-je).c_str(); if(vv) rkv.push_back(mglRKdat(vv, eq )); jv = iv+1; je = ie+1; if(iv==std::wstring::npos || ie==std::wstring::npos) break; } for(size_t i=0;iDataList)); else rk.d1.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;iGetNN(); dual a = hh*rk.c1.a[0]; if(rk.c1.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + hh*rk.c1.a[j]; else #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = hh*rk.d1.a[0]; if(rk.d1.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + hh*rk.d1.a[j]; else #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + a; } } for(size_t i=0;iDataList)); else rk.d2.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;iGetNN(); dual a = hh*rk.c2.a[0]; if(rk.c2.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + hh*rk.c2.a[j]; else #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = hh*rk.d2.a[0]; if(rk.d2.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + hh*rk.d2.a[j]; else #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + a; } } for(size_t i=0;iDataList)); else rk.d3.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;iGetNN(); dual a = dt*rk.c3.a[0]; if(rk.c3.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + dt*rk.c3.a[j]; else #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = dt*rk.d3.a[0]; if(rk.d3.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + dt*rk.d3.a[j]; else #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + a; } } for(size_t i=0;iDataList)); else rk.d4.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;iGetNN(); dual a = (rk.c1.a[0]+rk.c2.a[0]+mreal(2)*(rk.c3.a[0]+rk.c4.a[0]))*(dt/6); if(rk.c1.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + (rk.c1.a[j]+rk.c2.a[j]+mreal(2)*(rk.c3.a[j]+rk.c4.a[j]))*(dt/6); else #pragma omp parallel for for(long j=0;ja[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = (rk.d1.a[0]+rk.d2.a[0]+2*(rk.d3.a[0]+rk.d4.a[0]))*(dt/6); if(rk.d1.GetNN()==n) #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + (rk.d1.a[j]+rk.d2.a[j]+2*(rk.d3.a[j]+rk.d4.a[j]))*(dt/6); else #pragma omp parallel for for(long j=0;ja[j] = rk.din.a[j] + a; } } } void MGL_EXPORT mgl_rk_step(HMPR pr, const char *Eqs, const char *Vars, mreal dt) { if(Eqs && *Eqs && Vars && *Vars) { size_t s=mbstowcs(0,Eqs,0), w=mbstowcs(0,Vars,0); wchar_t *eqs=new wchar_t[s+1]; mbstowcs(eqs,Eqs ,s); eqs[s]=0; wchar_t *wcs=new wchar_t[s+1]; mbstowcs(wcs,Vars,s); wcs[w]=0; mgl_rk_step_w(pr,eqs,wcs,dt); delete []wcs; delete []eqs; } } void MGL_EXPORT mgl_rk_step_(uintptr_t *p, const char *eqs, const char *vars, double *dt,int l,int m) { char *e=new char[l+1]; memcpy(e,eqs,l); e[l]=0; char *s=new char[m+1]; memcpy(s,vars,m); s[m]=0; mgl_rk_step(_PR_,e,s,*dt); delete []e; delete []s; } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_parser_variant(HMPR p, int var) { p->SetVariant(var); } void MGL_EXPORT mgl_parser_variant_(uintptr_t *p, int *var) { mgl_parser_variant(_PR_,*var); } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_parser_openhdf(HMPR p, const char *fname) { const char * const *res = mgl_datas_hdf_str(fname); if(!res) return; for(size_t n=0;res[n][0];n++) { mglDataA *d = p->AddVar(res[n]); mglData *dr = dynamic_cast(d); mglDataC *dc = dynamic_cast(d); if(dr) dr->ReadHDF(fname,res[n]); if(dc) dc->ReadHDF(fname,res[n]); } } void MGL_EXPORT mgl_parser_openhdf_(uintptr_t *p, const char *fname,int l) { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0; mgl_parser_openhdf(_PR_,s); delete []s; } //--------------------------------------------------------------------------- void MGL_EXPORT mgl_parser_start_id(HMPR pr, int id) { pr->StarObhID = id; } void MGL_EXPORT mgl_parser_start_id_(uintptr_t* p, int *id) { mgl_parser_start_id(_PR_, *id); } //--------------------------------------------------------------------------- mglCommand mgls_prg_cmd[] = { {"ask",_("Define parameter from user input"),"ask $N 'question'", 0, 6}, {"break",_("Break for-loop"),"break", 0, 6}, {"call",_("Execute script in external file"),"call 'name' [args]", 0, 6}, {"continue",_("Skip commands and iterate for-loop again"),"continue", 0, 6}, {"do",_("Begin of do-while loop"),"do", 0, 6}, {"defchr",_("Define parameter as character"),"defchr $N val", 0, 6}, {"define",_("Define constant or parameter"),"define $N sth | Var val", 0, 6}, {"defnum",_("Define parameter as numerical value"),"defnum $N val", 0, 6}, // {"defpal",_("Define parameter as palette color"),"defpal $N val", 0, 6}, {"else",_("Execute if condition is false"),"else", 0, 6}, {"elseif",_("Conditional operator"),"elseif val|Dat ['cond']", 0, 6}, {"endif",_("Finish if/else block"),"endif", 0, 6}, {"for",_("For loop"),"for $N v1 v2 [dv] | $N Dat", 0, 6}, {"func",_("Start function definition and stop execution of main script"),"func 'name' [narg]", 0, 6}, {"if",_("Conditional operator"),"if val|Dat ['cond']", 0, 6}, {"list",_("Creates new variable from list of numbers or data"),"list Var v1 ...|Var D1 ...", 0, 4}, {"next",_("Start next for-loop iteration"),"next", 0, 6}, {"once",_("Start/close commands which should executed only once"),"once val", 0, 6}, {"return",_("Return from function"),"return", 0, 6}, {"stop",_("Stop execution"),"stop", 0, 6}, {"while",_("Condition of do-while loop"),"while val|Dat ['cond']", 0, 6}, {"","","",NULL,0}}; //----------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/base.cpp���������������������������������������������������������������������������0000644�0001750�0001750�00000163011�13513030041�015354� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * base.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mgl2/font.h" #include "mgl2/base.h" #include "mgl2/eval.h" #if MGL_HAVE_OMP #include #endif //----------------------------------------------------------------------------- static unsigned mgl_pb=0; unsigned MGL_EXPORT mgl_bsize(unsigned bsize) { if(!mgl_pb) mgl_pb = (bsize>0 && bsize<100)?bsize:16; return mgl_pb; } unsigned MGL_EXPORT mgl_bsize_(unsigned *bsize) { return mgl_bsize(*bsize); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mutex_unlock(void *mutex) { #if MGL_HAVE_PTHREAD pthread_mutex_unlock((pthread_mutex_t *)mutex); #elif MGL_HAVE_OMP omp_unset_lock((omp_lock_t *)mutex); #endif } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_mutex_lock(void *mutex) { #if MGL_HAVE_PTHREAD pthread_mutex_lock((pthread_mutex_t *)mutex); #elif MGL_HAVE_OMP omp_set_lock((omp_lock_t *)mutex); #endif } //----------------------------------------------------------------------------- char *mgl_strdup(const char *s) { char *r = (char *)malloc((strlen(s)+1)*sizeof(char)); if(r) memcpy(r,s,(strlen(s)+1)*sizeof(char)); return r; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_create_cpp_font(HMGL gr, const wchar_t *how) { unsigned long l=mgl_wcslen(how), i, n=0, m; wchar_t ch=*how; const mglFont *f = gr->GetFont(); std::vector s; s.push_back(ch); for(i=1;iInternal(s[i]); if(ch>=0) { l += 2*f->GetNl(0,ch); n += 6*f->GetNt(0,ch); } } printf("const unsigned long mgl_numg=%lu, mgl_cur=%lu;\n",(unsigned long)s.size(),l+n); printf("const float mgl_fact=%g;\n",f->GetFact(0)/mgl_fgen); printf("long mgl_gen_fnt[%lu][6] = {\n", (unsigned long)s.size()); for(i=m=0;iInternal(s[i]); if(ch<0) continue; int m1 = f->GetNl(0,ch), m2 = f->GetNt(0,ch); printf("\t{0x%x,%d,%d,%lu,%d,%lu},\n",unsigned(s[i]),f->GetWidth(0,ch),m1,m,m2,m+2*m1); m += 2*m1+6*m2; } if(m!=l+n) printf("#error \"%lu !=%lu + %lu\"",m,l,n); printf("};\nshort mgl_buf_fnt[%lu] = {\n",m); for(i=0;iInternal(s[i]); if(ch<0) continue; unsigned m1 = f->GetNl(0,ch), m2 = f->GetNt(0,ch); const short *ln = f->GetLn(0,ch), *tr = f->GetTr(0,ch); for(l=0;l<2*m1;l++) printf("%d,",ln[l]); printf("\n"); for(l=0;l<6*m2;l++) printf("%d,",tr[l]); printf("\n"); } printf("};\n"); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_strtrim(char *str) { if(!str || *str==0) return; size_t n=strlen(str), k, i; for(k=0;k' ') break; for(i=n;i>k;i--) if(str[i-1]>' ') break; memmove(str, str+k, (i-k)); str[i-k]=0; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_strlwr(char *str) { size_t l=strlen(str); for(size_t k=0;k='A' && str[k]<='Z') ? str[k]+'a'-'A' : str[k]; } //----------------------------------------------------------------------------- mglBase::mglBase() { Flag=0; saved=false; PrmInd=NULL; #if MGL_HAVE_PTHREAD pthread_mutex_init(&mutexPnt,0); pthread_mutex_init(&mutexTxt,0); pthread_mutex_init(&mutexSub,0); pthread_mutex_init(&mutexLeg,0); pthread_mutex_init(&mutexPrm,0); pthread_mutex_init(&mutexPtx,0); pthread_mutex_init(&mutexStk,0); pthread_mutex_init(&mutexGrp,0); pthread_mutex_init(&mutexGlf,0); pthread_mutex_init(&mutexAct,0); pthread_mutex_init(&mutexDrw,0); pthread_mutex_init(&mutexClf,0); Pnt.set_mutex(&mutexClf); Prm.set_mutex(&mutexClf); // Txt.set_mutex(&mutexClf); #endif #if MGL_HAVE_OMP lockClf = new omp_lock_t; omp_init_lock((omp_lock_t*)lockClf); Pnt.set_mutex(lockClf); Prm.set_mutex(lockClf); // Txt.set_mutex(&lockClf); #else lockClf = NULL; #endif fnt=0; *FontDef=0; fx=fy=fz=fa=fc=0; AMin.Set(0,0,0,0); AMax.Set(1,1,1,1); InUse = 1; SetQuality(); FaceNum = 0; // Always create default palette txt[0] and default scheme txt[1] mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1); Txt.reserve(3); MGL_PUSH(Txt,t1,mutexTxt); MGL_PUSH(Txt,t2,mutexTxt); strcpy(last_style,"__1 {dFFFF}k\0"); MinS.Set(-1,-1,-1); MaxS.Set(1,1,1); fnt = new mglFont; fnt->gr = this; PrevState=size_opt=NAN; } //----------------------------------------------------------------------------- mglBase::~mglBase() { ClearEq(); ClearPrmInd(); delete fnt; Pnt.set_mutex(0); Prm.set_mutex(0); //Txt.set_mutex(0); #if MGL_HAVE_PTHREAD pthread_mutex_destroy(&mutexPnt); pthread_mutex_destroy(&mutexTxt); pthread_mutex_destroy(&mutexSub); pthread_mutex_destroy(&mutexLeg); pthread_mutex_destroy(&mutexPrm); pthread_mutex_destroy(&mutexPtx); pthread_mutex_destroy(&mutexStk); pthread_mutex_destroy(&mutexGrp); pthread_mutex_destroy(&mutexGlf); pthread_mutex_destroy(&mutexAct); pthread_mutex_destroy(&mutexDrw); pthread_mutex_destroy(&mutexClf); #endif #if MGL_HAVE_OMP omp_destroy_lock((omp_lock_t*)lockClf); delete ((omp_lock_t*)lockClf); #endif } //----------------------------------------------------------------------------- void mglBase::RestoreFont() { fnt->Restore(); } void mglBase::LoadFont(const char *name, const char *path) { if(name && *name) fnt->Load(name,path); else fnt->Restore(); } void mglBase::CopyFont(mglBase *gr) { fnt->Copy(gr->GetFont()); } //----------------------------------------------------------------------------- mreal mglBase::TextWidth(const char *text, const char *font, mreal size) const { return (size<0?-size*FontSize:size)*font_factor*fnt->Width(text,(font&&*font)?font:FontDef)/20.16; } mreal mglBase::TextWidth(const wchar_t *text, const char *font, mreal size) const { return (size<0?-size*FontSize:size)*font_factor*fnt->Width(text,(font&&*font)?font:FontDef)/20.16; } mreal mglBase::TextHeight(const char *text, const char *font, mreal size) const { float y1,y2; fnt->Width(text,(font&&*font)?font:FontDef,&y1,&y2); return (size<0?-size*FontSize:size)*font_factor*(y2-y1)/20.16; } mreal mglBase::TextHeight(const wchar_t *text, const char *font, mreal size) const { float y1,y2; fnt->Width(text,(font&&*font)?font:FontDef,&y1,&y2); return (size<0?-size*FontSize:size)*font_factor*(y2-y1)/20.16; } mreal mglBase::TextHeight(const char *font, mreal size) const { return (size<0?-size*FontSize:size)*font_factor*fnt->Height(font?font:FontDef)/20.16; } void mglBase::AddActive(long k,int n) { if(k<0 || (size_t)k>=Pnt.size()) return; mglActivePos p; const mglPnt &q=Pnt[k]; int h=GetHeight(); p.x = int(q.x); p.y = h>1?h-1-int(q.y):int(q.y); p.id = ObjId; p.n = n; #pragma omp critical(act) MGL_PUSH(Act,p,mutexAct); } //----------------------------------------------------------------------------- mreal mglBase::GetRatio() const { return 1; } int mglBase::GetWidth() const { return 1; } int mglBase::GetHeight() const { return 1; } //----------------------------------------------------------------------------- void mglBase::StartGroup(const char *name, int id) { LightScale(&B); char buf[128]; snprintf(buf,128,"%s_%d",name,id); buf[127]=0; StartAutoGroup(buf); } //----------------------------------------------------------------------------- const char *mglWarn[mglWarnEnd] = {_("data dimension(s) is incompatible"), //mglWarnDim _("data dimension(s) is too small"), //mglWarnLow _("minimal data value is negative"), //mglWarnNeg _("no file or wrong data dimensions"), //mglWarnFile _("not enough memory"), //mglWarnMem _("data values are zero"), //mglWarnZero _("no legend entries"), //mglWarnLeg _("slice value is out of range"), //mglWarnSlc _("number of contours is zero or negative"),//mglWarnCnt _("couldn't open file"), //mglWarnOpen _("light: ID is out of range"), //mglWarnLId _("size(s) is zero or negative"), //mglWarnSize _("format is not supported for that build"),//mglWarnFmt _("axis ranges are incompatible"), //mglWarnTern _("pointer is NULL"), //mglWarnNull _("not enough space for plot"), //mglWarnSpc _("There is wrong argument(s) in script"), //mglScrArg _("There is wrong command(s) in script"), //mglScrCmd _("There is too long string(s) in script"), //mglScrLong _("There is unbalanced ' in script"), //mglScrStr _("There is changing temporary data in script")}; //mglScrTemp //----------------------------------------------------------------------------- extern bool mglPrintWarn; void mglBase::SetWarn(int code, const char *who) { std::string warn; WarnCode = code>0 ? code:0; if(code>0 && code0?new short[6*nt]:0; if(line) delete []line; line = nl>0?new short[2*nl]:0; } } //----------------------------------------------------------------------------- bool mglGlyph::operator==(const mglGlyph &g) const { if(nl!=g.nl || nt!=g.nt) return false; if(trig && memcmp(trig,g.trig,6*nt*sizeof(short))) return false; if(line && memcmp(line,g.line,2*nl*sizeof(short))) return false; return true; } //----------------------------------------------------------------------------- long mglBase::AddGlyph(int s, long j) { // first create glyph for current typeface s = s&3; mglGlyph g(fnt->GetNt(s,j), fnt->GetNl(s,j)); memcpy(g.trig, fnt->GetTr(s,j), 6*g.nt*sizeof(short)); memcpy(g.line, fnt->GetLn(s,j), 2*g.nl*sizeof(short)); // now let find the similar glyph for(size_t i=0;iGetNx(); if(y->GetNx()!=n || n<2) return; mglGlyph g(-id,n); mreal x1=1e10,x2=-1e10,y1=1e10,y2=-1e10; for(long i=0;iv(i), yy = y->v(i); x1=x1>xx?xx:x1; x2=x2yy?yy:y1; y2=y2v(i)*scale), sy = short(y->v(i)*scale); g.line[2*i] = sx; g.line[2*i+1] = sy; } UserGlf.push_back(g); } //----------------------------------------------------------------------------- // Add points to the buffer //----------------------------------------------------------------------------- long mglBase::PushPnts(size_t num, const mglPnt *qq) { long k; #pragma omp critical(pnt) MGL_PUSHs({k=Pnt.size();Pnt.push_back(num,qq);},mutexPnt); return k; } //----------------------------------------------------------------------------- long mglBase::AllocPnts(size_t num) { long k; #pragma omp critical(pnt) MGL_PUSHs({k=Pnt.allocate(num);},mutexPnt); return k; } //----------------------------------------------------------------------------- void inline mgl_put_inbox(mreal a1, mreal a2, mreal &a) { if(a1a2) a=a2; } else { if(aa1) a=a1; } } static void mgl_coor_box(HMGL gr, mglPoint &p) { mgl_put_inbox(gr->Min.x, gr->Max.x, p.x); mgl_put_inbox(gr->Min.y, gr->Max.y, p.y); mgl_put_inbox(gr->Min.z, gr->Max.z, p.z); } long mglBase::AddPnt(const mglMatrix *mat, mglPoint p, mreal c, mglPoint n, mreal a, int scl) { mglPnt q; if(!AddPntQ(q,mat,p,c,n,a,scl)) return -1; long k; #pragma omp critical(pnt) {k=Pnt.size(); MGL_PUSH(Pnt,q,mutexPnt);} return k; } bool mglBase::AddPntQ(mglPnt &q, const mglMatrix *mat, mglPoint p, mreal c, mglPoint n, mreal a, int scl) { // scl=0 -- no scaling // scl&1 -- usual scaling // scl&2 -- disable NAN at scaling // scl&4 -- disable NAN for normales if no light // scl&8 -- bypass palette for enabling alpha // scl&16 -- put points inside axis range if(mgl_isnan(c) || mgl_isnan(a)) { q.x=NAN; return false; } bool norefr = mgl_isnan(n.x) && mgl_isnan(n.y) && !mgl_isnan(n.z), res=true; if(scl>0) { if(scl&16) mgl_coor_box(this, p); res = ScalePoint(mat,p,n,!(scl&2)); } if(mgl_isnan(p.x)) { q.x=NAN; return false; } a = (a>=0 && a<=1) ? a : AlphaDef; c = (c>=0) ? c:CDef; if(get(MGL_REDUCEACC)) { q.x=q.xx=int(p.x*10)*0.1; q.y=q.yy=int(p.y*10)*0.1; q.z=q.zz=int(p.z*10)*0.1; q.c=int(c*100)*0.01; q.ta=int(a*100)*0.01; q.u=mgl_isnum(n.x)?int(n.x*100)*0.01:NAN; q.v=mgl_isnum(n.y)?int(n.y*100)*0.01:NAN; q.w=mgl_isnum(n.z)?int(n.z*100)*0.01:NAN; } else { q.x=q.xx=p.x; q.y=q.yy=p.y; q.z=q.zz=p.z; q.c=c; q.ta=a; q.u=n.x; q.v=n.y; q.w=n.z; } long ci=long(c); if(ci<0 || ci>=(long)Txt.size()) ci=0; // NOTE never should be here!!! const mglTexture &txt=Txt[ci]; txt.GetC(c,a,q); // RGBA color if(get(MGL_GRAY_MODE)) { float h = 0.3*q.r + 0.59*q.g + 0.11*q.b; q.r = q.g = q.b = h; } // add gap for texture coordinates for compatibility with OpenGL const mreal gap = 0./MGL_TEXTURE_COLOURS; q.c = ci+(q.c-ci)*(1-2*gap)+gap; q.ta = q.ta*(1-2*gap)+gap; if(scl&8 && scl>0) q.a=a; // bypass palette for enabling alpha in Error() if(!get(MGL_ENABLE_ALPHA)) { q.a=1; if(txt.Smooth!=2) q.ta=1-gap; } if(norefr) q.v=0; if(!get(MGL_ENABLE_LIGHT) && !(scl&4)) q.u=q.v=NAN; q.sub=mat->norot?-1*(int)Sub.size():Sub.size()-1; return (scl&16)?res:true; } //----------------------------------------------------------------------------- long mglBase::CopyNtoC(long from, mreal c) { mglPnt q; if(!CopyNtoC(q,from,c)) return -1; long k; #pragma omp critical(pnt) {k=Pnt.size(); MGL_PUSH(Pnt,q,mutexPnt);} return k; } //----------------------------------------------------------------------------- bool mglBase::CopyNtoC(mglPnt &q, long from, mreal c) { if(from<0) return false; q = Pnt[from]; if(mgl_isnum(c)) { q.c=c; q.ta=1; Txt[long(c)].GetC(c,0,q); q.a=1; } else q.x = NAN; return mgl_isnum(q.x); } //----------------------------------------------------------------------------- long mglBase::CopyProj(long from, mglPoint p, mglPoint n, short sub) { mglPnt q; if(!CopyProj(q,from,p,n,sub)) return -1; long k; #pragma omp critical(pnt) {k=Pnt.size(); MGL_PUSH(Pnt,q,mutexPnt);} return k; } //----------------------------------------------------------------------------- bool mglBase::CopyProj(mglPnt &q, long from, mglPoint p, mglPoint n, short sub) { if(from<0) return false; q=Pnt[from]; q.sub = sub; q.x=q.xx=p.x; q.y=q.yy=p.y; q.z=q.zz=p.z; q.u = n.x; q.v = n.y; q.w = n.z; return mgl_isnum(q.x); } //----------------------------------------------------------------------------- void mglBase::Reserve(long n) { if(TernAxis&12) n*=4; #pragma omp critical(pnt) Pnt.reserve(n); #pragma omp critical(prm) Prm.reserve(n); } //----------------------------------------------------------------------------- // Boundaries and scaling //----------------------------------------------------------------------------- bool mglBase::RecalcCRange() { bool wrong=false; if(!fa) { FMin.c = Min.c; FMax.c = Max.c; } else { FMin.c = INFINITY; FMax.c = -INFINITY; int n=30; for(int i=0;i<=n;i++) { mreal a = fa->Calc(0,0,0,Min.c+i*(Max.c-Min.c)/n); if(mgl_isbad(a)) wrong=true; if(aFMax.c) FMax.c=a; } } return wrong; } //----------------------------------------------------------------------------- void mglBase::RecalcBorder() { ZMin = 1.; bool wrong=false; if(!fx && !fy && !fz) { FMin = Min; FMax = Max; } else { FMin.Set( INFINITY, INFINITY, INFINITY); FMax.Set(-INFINITY,-INFINITY,-INFINITY); int n=30; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) // x range { if(SetFBord(Min.x, Min.y+i*(Max.y-Min.y)/n, Min.z+j*(Max.z-Min.z)/n)) wrong=true; if(SetFBord(Max.x, Min.y+i*(Max.y-Min.y)/n, Min.z+j*(Max.z-Min.z)/n)) wrong=true; } for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) // y range { if(SetFBord(Min.x+i*(Max.x-Min.x)/n, Min.y, Min.z+j*(Max.z-Min.z)/n)) wrong=true; if(SetFBord(Min.x+i*(Max.x-Min.x)/n, Max.y, Min.z+j*(Max.z-Min.z)/n)) wrong=true; } for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) // x range { if(SetFBord(Min.x+i*(Max.x-Min.x)/n, Min.y+j*(Max.y-Min.y)/n, Min.z)) wrong=true; if(SetFBord(Min.x+i*(Max.x-Min.x)/n, Min.y+j*(Max.y-Min.y)/n, Max.z)) wrong=true; } if(!fx) { FMin.x = Min.x; FMax.x = Max.x; } else { mreal d=0.01*(FMax.x-FMin.x); FMin.x-=d; FMax.x+=d; } if(!fy) { FMin.y = Min.y; FMax.y = Max.y; } else { mreal d=0.01*(FMax.y-FMin.y); FMin.y-=d; FMax.y+=d; } if(!fz) { FMin.z = Min.z; FMax.z = Max.z; } else { mreal d=0.01*(FMax.z-FMin.z); FMin.z-=d; FMax.z+=d; } } if(RecalcCRange()) wrong=true; if(wrong) SetWarn(mglWarnTern, "Curved coordinates"); } //----------------------------------------------------------------------------- bool mglBase::SetFBord(mreal x,mreal y,mreal z) { bool wrong=false; if(fx) { mreal v = fx->Calc(x,y,z); if(mgl_isbad(v)) wrong = true; if(FMax.x < v) FMax.x = v; if(FMin.x > v) FMin.x = v; } if(fy) { mreal v = fy->Calc(x,y,z); if(mgl_isbad(v)) wrong = true; if(FMax.y < v) FMax.y = v; if(FMin.y > v) FMin.y = v; } if(fz) { mreal v = fz->Calc(x,y,z); if(mgl_isbad(v)) wrong = true; if(FMax.z < v) FMax.z = v; if(FMin.z > v) FMin.z = v; } return wrong; } //----------------------------------------------------------------------------- bool mglBase::ScalePoint(const mglMatrix *, mglPoint &p, mglPoint &n, bool use_nan) const { mreal &x=p.x, &y=p.y, &z=p.z; if(mgl_isnan(x) || mgl_isnan(y) || mgl_isnan(z)) { x=NAN; return false; } mreal x1,y1,z1,x2,y2,z2; x1 = x>0?x*MGL_EPSILON:x/MGL_EPSILON; x2 = x<0?x*MGL_EPSILON:x/MGL_EPSILON; y1 = y>0?y*MGL_EPSILON:y/MGL_EPSILON; y2 = y<0?y*MGL_EPSILON:y/MGL_EPSILON; z1 = z>0?z*MGL_EPSILON:z/MGL_EPSILON; z2 = z<0?z*MGL_EPSILON:z/MGL_EPSILON; bool res = true; if(x2>CutMin.x && x1CutMin.y && y1CutMin.z && z1Calc(x,y,z)!=0) res = false; if(get(MGL_ENABLE_CUT) || !use_nan) { // if(x1Max.x || y1Max.y || z1Max.z) res = false; if((x1-Min.x)*(x1-Max.x)>0 && (x2-Min.x)*(x2-Max.x)>0) res = false; if((y1-Min.y)*(y1-Max.y)>0 && (y2-Min.y)*(y2-Max.y)>0) res = false; if((z1-Min.z)*(z1-Max.z)>0 && (z2-Min.z)*(z2-Max.z)>0) res = false; } else { if(Min.xMax.x) {x=Max.x; n.Set(1,0,0);} } else { if(x1Min.x) {x=Min.x; n.Set(1,0,0);} } if(Min.yMax.y) {y=Max.y; n.Set(0,1,0);} } else { if(y1Min.y) {y=Min.y; n.Set(0,1,0);} } if(Min.zMax.z) {z=Max.z; n.Set(0,0,1);} } else { if(z1Min.z) {z=Min.z; n.Set(0,0,1);} } } x1=x; y1=y; z1=z; mreal xx=1,xy=0,xz=0,yx=0,yy=1,yz=0,zx=0,zy=0,zz=1; if(fx) { x1 = fx->Calc(x,y,z); xx = fx->CalcD('x',x,y,z); xy = fx->CalcD('y',x,y,z); xz = fx->CalcD('z',x,y,z); } if(fy) { y1 = fy->Calc(x,y,z); yx = fy->CalcD('x',x,y,z); yy = fy->CalcD('y',x,y,z); yz = fy->CalcD('z',x,y,z); } if(fz) { z1 = fz->Calc(x,y,z); zx = fz->CalcD('x',x,y,z); zy = fz->CalcD('y',x,y,z); zz = fz->CalcD('z',x,y,z); } if(mgl_isnan(x1) || mgl_isnan(y1) || mgl_isnan(z1)) { x=NAN; return false; } mreal d; d = 1/(FMax.x - FMin.x); x = (2*x1 - FMin.x - FMax.x)*d; xx /= d; xy /= d; xz /= d; d = 1/(FMax.y - FMin.y); y = (2*y1 - FMin.y - FMax.y)*d; yx /= d; yy /= d; yz /= d; d = 1/(FMax.z - FMin.z); z = (2*z1 - FMin.z - FMax.z)*d; zx /= d; zy /= d; zz /= d; mreal nx=n.x, ny=n.y, nz=n.z; n.x = nx*xx+ny*xy+nz*xz; n.y = nx*yx+ny*yy+nz*yz; n.z = nx*zx+ny*zy+nz*zz; if((TernAxis&3)==1) // usual ternary axis { if(x+y>0) { if(get(MGL_ENABLE_CUT)) res = false; else y = -x; } x += (y+1)/2; n.x += n.y/2; } else if((TernAxis&3)==2) // quaternary axis { if(x+y+z>-1) { if(get(MGL_ENABLE_CUT)) res = false; else z = -1-y-x; } x += 1+(y+z)/2; y += (z+1)/3; n.x += (n.y+n.z)/2; n.y += n.z/3; } if(fabs(x)>MGL_FEPSILON || fabs(y)>MGL_FEPSILON || fabs(z)>MGL_FEPSILON) res = false; if(!res && use_nan) x = NAN; // extra sign that point shouldn't be plotted return res; } //----------------------------------------------------------------------------- // Ranges //----------------------------------------------------------------------------- void mglScaleAxis(mreal &v1, mreal &v2, mreal &v0, mreal x1, mreal x2) { if(!mgl_isrange(x1,x2) || !mgl_isrange(v1,v2)) return; mreal dv,d0; x2-=1; if(v1*v2>0 && (v2/v1>=100 || v2/v1<=0.01)) // log scale { dv=log(v2/v1); d0 = log(v0/v1)/log(v2/v1); v1*=exp(dv*x1); v2*=exp(dv*x2); v0=v1*exp(d0*log(v2/v1)); } else { dv=v2-v1; d0=(v0-v1)/(v2-v1); v1+=dv*x1; v2+=dv*x2; v0=v1+d0*(v2-v1); } } //----------------------------------------------------------------------------- void mglBase::SetOrigin(mreal x0, mreal y0, mreal z0, mreal c0) { Org.Set(x0,y0,z0,c0); if((TernAxis&3)==0) { Min = OMin; Max = OMax; mglScaleAxis(Min.x, Max.x, Org.x, AMin.x, AMax.x); mglScaleAxis(Min.y, Max.y, Org.y, AMin.y, AMax.y); mglScaleAxis(Min.z, Max.z, Org.z, AMin.z, AMax.z); mglScaleAxis(Min.c, Max.c, Org.c, AMin.c, AMax.c); } } //----------------------------------------------------------------------------- void mglBase::SetRanges(mglPoint m1, mglPoint m2) { if(mgl_isrange(m1.x, m2.x)) { Min.x=m1.x; Max.x=m2.x; } if(mgl_isrange(m1.y, m2.y)) { Min.y=m1.y; Max.y=m2.y; } if(mgl_isrange(m1.z, m2.z)) { Min.z=m1.z; Max.z=m2.z; } if(mgl_isrange(m1.c, m2.c)) { Min.c=m1.c; Max.c=m2.c; } else { Min.c=Min.z;Max.c=Max.z;} if(Org.xMax.x && mgl_isnum(Org.x)) Org.x = Max.x; if(Org.yMax.y && mgl_isnum(Org.y)) Org.y = Max.y; if(Org.zMax.z && mgl_isnum(Org.z)) Org.z = Max.z; if((TernAxis&3)==0) { OMax = Max; OMin = Min; mglScaleAxis(Min.x, Max.x, Org.x, AMin.x, AMax.x); mglScaleAxis(Min.y, Max.y, Org.y, AMin.y, AMax.y); mglScaleAxis(Min.z, Max.z, Org.z, AMin.z, AMax.z); mglScaleAxis(Min.c, Max.c, Org.c, AMin.c, AMax.c); } CutMin.Set(0,0,0); CutMax.Set(0,0,0); RecalcBorder(); } //----------------------------------------------------------------------------- void mglBase::CRange(HCDT a,bool add, mreal fact) { mreal v1=a->Minimal(), v2=a->Maximal(), dv; dv=(v2-v1)*fact; v1 -= dv; v2 += dv; CRange(v1,v2,add); } void mglBase::CRange(mreal v1,mreal v2,bool add) { if(!mgl_isrange(v1,v2) && !add) return; if(!add) { if(mgl_isnum(v1)) Min.c = v1; if(mgl_isnum(v2)) Max.c = v2; } else if(Min.cv1) Min.c=v1; if(Max.cdv ? v2:dv; } if(Org.cMax.c && mgl_isnum(Org.c)) Org.c = Max.c; if((TernAxis&3)==0) { OMax.c = Max.c; OMin.c = Min.c; mglScaleAxis(Min.c, Max.c, Org.c, AMin.c, AMax.c); } RecalcCRange(); } //----------------------------------------------------------------------------- void mglBase::XRange(HCDT a,bool add,mreal fact) { mreal v1=a->Minimal(), v2=a->Maximal(), dv; dv=(v2-v1)*fact; v1 -= dv; v2 += dv; XRange(v1,v2,add); } void mglBase::XRange(mreal v1,mreal v2,bool add) { if(!mgl_isrange(v1,v2) && !add) return; if(!add) { if(mgl_isnum(v1)) Min.x = v1; if(mgl_isnum(v2)) Max.x = v2; } else if(Min.xv1) Min.x=v1; if(Max.xdv ? v2:dv; } if(Org.xMax.x && mgl_isnum(Org.x)) Org.x = Max.x; if((TernAxis&3)==0) { OMax.x = Max.x; OMin.x = Min.x; mglScaleAxis(Min.x, Max.x, Org.x, AMin.x, AMax.x); } RecalcBorder(); } //----------------------------------------------------------------------------- void mglBase::YRange(HCDT a,bool add,mreal fact) { mreal v1=a->Minimal(), v2=a->Maximal(), dv; dv=(v2-v1)*fact; v1 -= dv; v2 += dv; YRange(v1,v2,add); } void mglBase::YRange(mreal v1,mreal v2,bool add) { if(!mgl_isrange(v1,v2) && !add) return; if(!add) { if(mgl_isnum(v1)) Min.y = v1; if(mgl_isnum(v2)) Max.y = v2; } else if(Min.yv1) Min.y=v1; if(Max.ydv ? v2:dv; } if(Org.yMax.y && mgl_isnum(Org.y)) Org.y = Max.y; if((TernAxis&3)==0) { OMax.y = Max.y; OMin.y = Min.y; mglScaleAxis(Min.y, Max.y, Org.y, AMin.y, AMax.y); } RecalcBorder(); } //----------------------------------------------------------------------------- void mglBase::ZRange(HCDT a,bool add,mreal fact) { mreal v1=a->Minimal(), v2=a->Maximal(), dv; dv=(v2-v1)*fact; v1 -= dv; v2 += dv; ZRange(v1,v2,add); } void mglBase::ZRange(mreal v1,mreal v2,bool add) { if(!mgl_isrange(v1,v2) && !add) return; if(!add) { if(mgl_isnum(v1)) Min.z = v1; if(mgl_isnum(v2)) Max.z = v2; } else if(Min.zv1) Min.z=v1; if(Max.zdv ? v2:dv; } if(Org.zMax.z && mgl_isnum(Org.z)) Org.z = Max.z; if((TernAxis&3)==0) { OMax.z = Max.z; OMin.z = Min.z; mglScaleAxis(Min.z, Max.z, Org.z, AMin.z, AMax.z); } RecalcBorder(); } //----------------------------------------------------------------------------- void mglBase::SetAutoRanges(mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2, mreal c1, mreal c2) { if(mgl_isrange(x1,x2)) { Min.x = x1; Max.x = x2; } if(mgl_isrange(y1,y2)) { Min.y = y1; Max.y = y2; } if(mgl_isrange(z1,z2)) { Min.z = z1; Max.z = z2; } if(mgl_isrange(c1,c2)) { Min.c = c1; Max.c = c2; } } //----------------------------------------------------------------------------- void mglBase::Ternary(int t) { static mglPoint x1(-1,-1,-1),x2(1,1,1),o(NAN,NAN,NAN); static bool c = true; TernAxis = t; if(t&3) { if(c) { x1 = Min; x2 = Max; o = Org; } SetRanges(mglPoint(0,0,0),mglPoint(1,1,(t&3)==1?0:1)); Org.Set(0,0,(t&3)==1?NAN:0); c = false; } else if(!c) { SetRanges(x1,x2); Org=o; c=true; } } //----------------------------------------------------------------------------- // Transformation functions //----------------------------------------------------------------------------- void mglBase::SetFunc(const char *EqX,const char *EqY,const char *EqZ,const char *EqA) { if(fa) delete fa; if(fx) delete fx; if(fy) delete fy; if(fz) delete fz; if(EqX && *EqX && (EqX[0]!='x' || EqX[1]!=0)) fx = new mglFormula(EqX); else fx = 0; if(EqY && *EqY && (EqY[0]!='y' || EqY[1]!=0)) fy = new mglFormula(EqY); else fy = 0; if(EqZ && *EqZ && (EqZ[0]!='z' || EqZ[1]!=0)) fz = new mglFormula(EqZ); else fz = 0; if(EqA && *EqA && ((EqA[0]!='c' && EqA[0]!='a') || EqA[1]!=0)) fa = new mglFormula(EqA); else fa = 0; RecalcBorder(); } //----------------------------------------------------------------------------- void mglBase::CutOff(const char *EqC) { #pragma omp critical(eq) { if(fc) delete fc; fc = (EqC && EqC[0])?new mglFormula(EqC):0; } } //----------------------------------------------------------------------------- void mglBase::SetCoor(int how) { switch(how) { case mglCartesian: SetFunc(0,0); break; case mglPolar: SetFunc("x*cos(y)","x*sin(y)"); break; case mglSpherical: SetFunc("x*sin(y)*cos(z)","x*sin(y)*sin(z)","x*cos(y)"); break; case mglParabolic: SetFunc("x*y","(x*x-y*y)/2"); break; case mglParaboloidal: SetFunc("(x*x-y*y)*cos(z)/2","(x*x-y*y)*sin(z)/2","x*y"); break; case mglOblate: SetFunc("cosh(x)*cos(y)*cos(z)","cosh(x)*cos(y)*sin(z)","sinh(x)*sin(y)"); break; // SetFunc("x*y*cos(z)","x*y*sin(z)","(x*x-1)*(1-y*y)"); break; case mglProlate: SetFunc("sinh(x)*sin(y)*cos(z)","sinh(x)*sin(y)*sin(z)","cosh(x)*cos(y)"); break; case mglElliptic: SetFunc("cosh(x)*cos(y)","sinh(x)*sin(y)"); break; case mglToroidal: SetFunc("sinh(x)*cos(z)/(cosh(x)-cos(y))","sinh(x)*sin(z)/(cosh(x)-cos(y))", "sin(y)/(cosh(x)-cos(y))"); break; case mglBispherical: SetFunc("sin(y)*cos(z)/(cosh(x)-cos(y))","sin(y)*sin(z)/(cosh(x)-cos(y))", "sinh(x)/(cosh(x)-cos(y))"); break; case mglBipolar: SetFunc("sinh(x)/(cosh(x)-cos(y))","sin(y)/(cosh(x)-cos(y))"); break; case mglLogLog: SetFunc("lg(x)","lg(y)"); break; case mglLogX: SetFunc("lg(x)",""); break; case mglLogY: SetFunc("","lg(y)"); break; default: SetFunc(0,0); break; } } //----------------------------------------------------------------------------- void mglBase::ClearEq() { #pragma omp critical(eq) { if(fx) delete fx; if(fy) delete fy; if(fz) delete fz; if(fa) delete fa; if(fc) delete fc; fx = fy = fz = fc = fa = 0; } RecalcBorder(); } //----------------------------------------------------------------------------- // Colors ids //----------------------------------------------------------------------------- MGL_EXPORT mglColorID mglColorIds[31] = {{'k', mglColor(0,0,0)}, {'r', mglColor(1,0,0)}, {'R', mglColor(0.5,0,0)}, {'g', mglColor(0,1,0)}, {'G', mglColor(0,0.5,0)}, {'b', mglColor(0,0,1)}, {'B', mglColor(0,0,0.5)}, {'w', mglColor(1,1,1)}, {'W', mglColor(0.7,0.7,0.7)}, {'c', mglColor(0,1,1)}, {'C', mglColor(0,0.5,0.5)}, {'m', mglColor(1,0,1)}, {'M', mglColor(0.5,0,0.5)}, {'y', mglColor(1,1,0)}, {'Y', mglColor(0.5,0.5,0)}, {'h', mglColor(0.5,0.5,0.5)}, {'H', mglColor(0.3,0.3,0.3)}, {'l', mglColor(0,1,0.5)}, {'L', mglColor(0,0.5,0.25)}, {'e', mglColor(0.5,1,0)}, {'E', mglColor(0.25,0.5,0)}, {'n', mglColor(0,0.5,1)}, {'N', mglColor(0,0.25,0.5)}, {'u', mglColor(0.5,0,1)}, {'U', mglColor(0.25,0,0.5)}, {'q', mglColor(1,0.5,0)}, {'Q', mglColor(0.5,0.25,0)}, {'p', mglColor(1,0,0.5)}, {'P', mglColor(0.5,0,0.25)}, {' ', mglColor(-1,-1,-1)}, {0, mglColor(-1,-1,-1)} // the last one MUST have id=0 }; //----------------------------------------------------------------------------- void MGL_EXPORT mgl_chrrgb(char p, float c[3]) { c[0]=c[1]=c[2]=-1; for(long i=0; mglColorIds[i].id; i++) if(mglColorIds[i].id==p) { c[0]=mglColorIds[i].col.r; c[1]=mglColorIds[i].col.g; c[2]=mglColorIds[i].col.b; break; } } //----------------------------------------------------------------------------- size_t MGL_EXPORT_PURE mgl_get_num_color(const char *s, int smooth) { if(!s || !s[0]) return 0; size_t l=strlen(s), n=0; long j=0; for(size_t i=0;i=0 && s[i]==':' && j<1) break; if(s[i]=='{' && strchr(MGL_COLORS"x",s[i+1]) && j<1) n++; if(s[i]=='[' || s[i]=='{') j++; if(s[i]==']' || s[i]=='}') j--; if(strchr(MGL_COLORS,s[i]) && j<1) n++; // if(smooth && s[i]==':') break; // NOTE: should use [] } return n; } //----------------------------------------------------------------------------- void mglTexture::Set(const char *s, int smooth, mreal alpha) { // NOTE: New syntax -- colors are CCCCC or {CNCNCCCN}; options inside [] if(!s || !s[0]) return; mgl_strncpy(Sch,s,259); Smooth=smooth; Alpha=alpha; Clear(); long l=strlen(s); bool map = smooth==2 || mglchr(s,'%'), sm = smooth>=0 && !strchr(s,'|'); // Use mapping, smoothed colors n = mgl_get_num_color(s,smooth); if(!n) { if(strchr(s,'|') && !smooth) // sharp colors { n=l=6; s=MGL_DEF_SCH; sm = false; } else if(smooth==0) // none colors but color scheme { n=l=6; s=MGL_DEF_SCH; } } if(n<=0) return; bool man=sm; c0 = new mglColor[2*n]; // Colors itself val = new float[n]; for(long i=0, m=0, j=n=0;i=0 && s[i]==':' && j<1) break; if(s[i]=='[') j++; if(s[i]==']') j--; if(s[i]=='{') m++; if(s[i]=='}') m--; if(strchr(MGL_COLORS,s[i]) && j<1 && (m==0 || s[i-1]=='{')) // {CN,val} format, where val in [0,1] { if(m>0 && s[i+1]>'0' && s[i+1]<='9')// ext color { c0[2*n].Set(s[i],(s[i+1]-'0')/5.f); i++; } else c0[2*n].Set(s[i]); // usual color val[n]=-1; c0[2*n].a = -1; n++; } if(s[i]=='x' && i>0 && s[i-1]=='{' && j<1) // {xRRGGBB,val} format, where val in [0,1] { uint32_t id = strtoul(s+1+i,0,16); if(memchr(s+i+1,'}',8) || memchr(s+i+1,',',8)) c0[2*n].a = -1; else { c0[2*n].a = (id%256)/255.; id /= 256; } c0[2*n].b = (id%256)/255.; id /= 256; c0[2*n].g = (id%256)/255.; id /= 256; c0[2*n].r = (id%256)/255.; while(strchr("0123456789abcdefABCDEFx",s[i])) i++; val[n]=-1; n++; i--; } if(s[i]==',' && m>0 && j<1 && n>0) val[n-1] = atof(s+i+1); // NOTE: User can change alpha if it placed like {AN} if(s[i]=='A' && j<1 && m>0 && s[i+1]>'0' && s[i+1]<='9') { man=false; alpha = 0.1*(s[i+1]-'0'); i++; } } for(long i=0;i1) // map texture { if(n==2) { c0[1]=c0[2]; c0[2]=c0[0]; c0[0]=BC; c0[3]=c0[1]+c0[2]; } else if(n==3) { c0[1]=c0[2]; c0[2]=c0[0]; c0[0]=BC; c0[3]=c0[4]; n=2;} else { c0[1]=c0[4]; c0[3]=c0[6]; n=2; } c0[0].a = c0[1].a = c0[2].a = c0[3].a = alpha; val[0]=val[1]=-1; } // TODO if(!sm && n==1) then try to find color in palette ??? // fill missed values of val[] float v1=0,v2=1; std::vector def; val[0]=0; val[n-1]=1; // boundary have to be [0,1] for(long i=0;i0 && val[i]<1) def.push_back(i); def.push_back(n-1); long i1=0; for(size_t j=0;j0?def[j-1]:0; long i2 = def[j]; v1 = val[i1]; v2 = val[i2]; v2 = i2-i1>1?(v2-v1)/(i2-i1):0; val[i]=v1+v2*(i-i1); } // fill texture itself mreal v=sm?(n-1)/255.:n/256.; if(!sm) for(long i=0;i<256;i++) { long j = 2*long(v*i); //u-=j; col[2*i] = c0[j]; col[2*i+1] = c0[j+1]; } else for(long i=i1=0;i<256;i++) { mreal u = v*i; long j = long(u); //u-=j; if(j=255*val[i1];i1++); v2 = i1=0) SetMask(cols); mglTexture t(cols,smooth,smooth==2?AlphaDef:1); if(t.n==0) return smooth<0 ? 0:1; if(smooth<0) CurrPal=0; // check if already exist for(size_t i=0;i=0) { p=(p+1)%n; id = 256*i+p; } CDef = i + (n>0 ? (p+0.5)/n : 0); CurrPal++; sprintf(last_style+11,"{&%g}",CDef); if(!leg_str.empty()) { AddLegend(leg_str.c_str(),last_style); leg_str.clear(); } return CDef; } //----------------------------------------------------------------------------- mreal mglBase::NextColor(long id, long sh) { long i=labs(id)/256, n=Txt[i].n, p=labs(id)&0xff; if(id>=0) p=(p+sh)%n; mreal cc = i + (n>0 ? (p+0.5)/n : 0); sprintf(last_style+11,"{&%g}",cc); return cc; } //----------------------------------------------------------------------------- MGL_EXPORT_PURE const char *mglchrs(const char *str, const char *chr) { if(!str || !str[0] || !chr || !chr[0]) return NULL; size_t l=strlen(chr); for(size_t i=0;i0 && p[i]=='d') PDef = strtol(p+i+1,0,16); if(m>0) continue; s = mglchr(stl,p[i]); if(s) { PDef = val[s-stl]; sprintf(last_style+6,"%04x",PDef); last_style[10]='}'; } else if(mglchr(mrk,p[i])) { mk = p[i]; last_style[3] = mk; } else if(mglchr(wdh,p[i])) { PenWidth = p[i]-'0'; last_style[2] = p[i]; } else if(mglchr(arr,p[i])) { if(!Arrow2) Arrow2 = p[i]; else Arrow1 = p[i]; } } if(!Arrow1) Arrow1='_'; if(!Arrow2) Arrow2='_'; if(mglchr(p,'#')) { s = mglchr(mrk,mk); if(s) { mk = MRK[s-mrk]; last_style[3] = mk; } } if((s=strstr(p,"{&"))!=0) { mk = last_style[3] = p[3]; strcpy(last_style+11,s); } else if(mk && mglchr(p,'&')) { mk += 128; last_style[3] = mk; } last_style[0] = Arrow1; last_style[1] = Arrow2; } if(pal) { if(p && (s=strstr(p,"{&"))!=0) { CDef = atof(s+2); // if(Id) *Id=long(tt)*256+(n+CurrPal-1)%n; } else { long tt, n; tt = AddTexture(p?p:MGL_DEF_PAL,-1); n=Txt[tt].n; CDef = tt+((n+CurrPal-1)%n+0.5)/n; if(Id) *Id=long(tt)*256+(n+CurrPal-1)%n; sprintf(last_style+11,"{&%g}",CDef); } } if(Arrow1=='_') Arrow1=0; if(Arrow2=='_') Arrow2=0; return mk; } //----------------------------------------------------------------------------- // keep this for restore default mask MGL_EXPORT uint64_t mgl_mask_def[16]={ 0x000000FF00000000, 0x080808FF08080808, 0x0000FF00FF000000, 0x0000000F00000000, 0x0000182424180000, 0x0000183C3C180000, 0x00003C24243C0000, 0x00003C3C3C3C0000, 0x0000060990600000, 0x0060584658600000, 0x00061A621A060000, 0x0000002700000000, 0x0008083E08080000, 0x0139010010931000, 0x0000001818000000, 0x101010FF010101FF}; MGL_EXPORT uint64_t mgl_mask_val[16]={ 0x000000FF00000000, 0x080808FF08080808, 0x0000FF00FF000000, 0x0000000F00000000, 0x0000182424180000, 0x0000183C3C180000, 0x00003C24243C0000, 0x00003C3C3C3C0000, 0x0000060990600000, 0x0060584658600000, 0x00061A621A060000, 0x0000002700000000, 0x0008083E08080000, 0x0139010010931000, 0x0000001818000000, 0x101010FF010101FF}; // 0x000000FF00000000, 0x080808FF08080808, 0x0000FF00FF000000, 0x0000007700000000, // 0x0000182424180000, 0x0000183C3C180000, 0x00003C24243C0000, 0x00003C3C3C3C0000, // 0x0000060990600000, 0x0060584658600000, 0x00061A621A060000, 0x0000005F00000000, // 0x0008142214080000, 0x00081C3E1C080000, 0x8142241818244281, 0x0000001824420000}; void mglBase::SetMask(const char *p) { mask = MGL_SOLID_MASK; // reset to solid face PenWidth = 1; MaskAn=DefMaskAn; if(p && *p) { const char *msk = MGL_MASK_ID, *s; const char *wdh = "123456789"; long m=0, l=strlen(p); for(long i=0;i0 && p[i]=='s') mask = strtoull(p+i+1,0,16); if(m>0) continue; if(p[i]==':') break; s = mglchr(msk, p[i]); if(s) mask = mgl_mask_val[s-msk]; else if(mglchr(wdh,p[i])) PenWidth = p[i]-'0'; else if(p[i]=='I') MaskAn=90; else if(p[i]=='/') MaskAn=315; // =360-45 else if(p[i]=='\\') MaskAn=45; } // use line if rotation only specified if(mask==MGL_SOLID_MASK && MaskAn!=0) mask = mgl_mask_val[0]; } } //----------------------------------------------------------------------------- mreal mglBase::GetA(mreal a) const { if(fa) a = fa->Calc(0,0,0,a); a = (a-FMin.c)/(FMax.c-FMin.c); a = (a>1?1:(a<0?0:a))/MGL_FEPSILON; // for texture a must be <1 always!!! // a = (a<1?(a>0?a:0):1)/MGL_FEPSILON; // for texture a must be <1 always!!! return a; } //----------------------------------------------------------------------------- mglPoint GetX(HCDT x, int i, int j, int k) { k = kGetNz() ? k : 0; if(x->GetNy()>1) return mglPoint(x->v(i,j,k),x->dvx(i,j,k),x->dvy(i,j,k)); else return mglPoint(x->v(i),x->dvx(i),0); } //----------------------------------------------------------------------------- mglPoint GetY(HCDT y, int i, int j, int k) { k = kGetNz() ? k : 0; if(y->GetNy()>1) return mglPoint(y->v(i,j,k),y->dvx(i,j,k),y->dvy(i,j,k)); else return mglPoint(y->v(j),0,y->dvx(j)); } //----------------------------------------------------------------------------- mglPoint GetZ(HCDT z, int i, int j, int k) { if(z->GetNy()>1) return mglPoint(z->v(i,j,k),z->dvx(i,j,k),z->dvy(i,j,k)); else return mglPoint(z->v(k),0,0); } //----------------------------------------------------------------------------- void mglBase::vect_plot(long p1, long p2, mreal s) { if(p1<0 || p2<0) return; const mglPnt &q1=Pnt[p1], &q2=Pnt[p2]; mglPnt s1=q2,s2=q2; s = s<=0 ? 0.1 : s*0.1; s1.x=s1.xx = q2.x - 3*s*(q2.x-q1.x) + s*(q2.y-q1.y); s2.x=s2.xx = q2.x - 3*s*(q2.x-q1.x) - s*(q2.y-q1.y); s1.y=s1.yy = q2.y - 3*s*(q2.y-q1.y) - s*(q2.x-q1.x); s2.y=s2.yy = q2.y - 3*s*(q2.y-q1.y) + s*(q2.x-q1.x); s1.z=s1.zz=s2.z=s2.zz = q2.z - 3*s*(q2.z-q1.z); long n1,n2; #pragma omp critical(pnt) { n1=Pnt.size(); MGL_PUSH(Pnt,s1,mutexPnt); n2=Pnt.size(); MGL_PUSH(Pnt,s2,mutexPnt); } line_plot(p1,p2); line_plot(n1,p2); line_plot(p2,n2); } //----------------------------------------------------------------------------- int MGL_LOCAL_PURE mglFindArg(const char *str) { long l=0,k=0,len=strlen(str); for(long i=0;i0) Sub[n-1].AmbBr=bright; } void mglBase::SetDiffuse(mreal bright) { DifBr=bright; size_t n=Sub.size(); if(n>0) Sub[n-1].DifBr=bright; } //----------------------------------------------------------------------------- mreal mglBase::SaveState(const char *opt) { if(saved) return PrevState; if(!opt || !opt[0]) return NAN; MSS=MarkSize; ASS=ArrowSize; FSS=FontSize; ADS=AlphaDef; MNS=MeshNum; CSS=Flag; LSS=AmbBr; MinS=Min; MaxS=Max; saved=true; // parse option char *qi=mgl_strdup(opt),*q=qi, *s; mgl_strtrim(q); // NOTE: not consider '#' inside legend entry !!! s=strchr(q,'#'); if(s) *s=0; mreal res=NAN; while(q && *q) { s=q; q=strchr(s,';'); if(q) { *q=0; q++; } mgl_strtrim(s); char *a=s; long n=mglFindArg(s); if(n>0) { s[n]=0; s=s+n+1; } mgl_strtrim(a); char *b=s; n=mglFindArg(s); if(n>0) { s[n]=0; s=s+n+1; } mgl_strtrim(b); mreal ff=atof(b),ss; size_opt = NAN; if(!strcmp(b,"on")) ff=1; if(!strcmp(a+1,"range")) { n=mglFindArg(s); char *c=s; if(n>0) { s[n]=0; s=s+n+1; } mgl_strtrim(c); ss = atof(c); if(a[0]=='x') { Min.x=ff; Max.x=ss; } else if(a[0]=='y') { Min.y=ff; Max.y=ss; } else if(a[0]=='z') { Min.z=ff; Max.z=ss; } // else if(a[0]=='c') { Min.c=ff; Max.c=ss; } // Bad idea since there is formula for coloring } else if(!strcmp(a,"cut")) SetCut(ff!=0); else if(!strcmp(a,"meshnum")) SetMeshNum(ff); else if(!strcmp(a,"alpha")) {Alpha(true); SetAlphaDef(ff);} else if(!strcmp(a,"light")) Light(ff!=0); else if(!strcmp(a,"ambient")) SetAmbient(ff); else if(!strcmp(a,"diffuse")) SetDifLight(ff); else if(!strcmp(a,"size")) { SetMarkSize(ff); SetFontSize(ff); SetArrowSize(ff); size_opt=ff; } else if(!strcmp(a,"num") || !strcmp(a,"number") || !strcmp(a,"value")) res=ff; else if(!strcmp(a,"legend")) { if(*b=='\'') { b++; b[strlen(b)-1]=0; } leg_str = b; } } free(qi); PrevState=res; return res; } //----------------------------------------------------------------------------- void mglBase::LoadState() { if(!saved) return; MarkSize=MSS; ArrowSize=ASS; FontSize=FSS; AlphaDef=ADS; MeshNum=MNS; Flag=CSS; AmbBr=LSS; Min=MinS; Max=MaxS; saved=false; } //----------------------------------------------------------------------------- void mglBase::AddLegend(const wchar_t *text,const char *style) { if(text) #pragma omp critical(leg) MGL_PUSH(Leg,mglText(text,style),mutexLeg); } //----------------------------------------------------------------------------- void mglBase::AddLegend(const char *str,const char *style) { MGL_TO_WCS(str,AddLegend(wcs, style)); } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_dim2(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, bool less) { // if(!gr || !x || !y || !z) return true; // if data is absent then should be segfault!!! long n=z->GetNx(),m=z->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,name); return true; } if(a && z->GetNN()!=a->GetNN()) { gr->SetWarn(mglWarnDim,name); return true; } if(less) { if(x->GetNx()SetWarn(mglWarnDim,name); return true; } if(y->GetNx()GetNy()GetNx()GetNy()SetWarn(mglWarnDim,name); return true; } } else { if(x->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } if(y->GetNx()!=m && (x->GetNy()!=m || y->GetNx()!=n || y->GetNy()!=m)) { gr->SetWarn(mglWarnDim,name); return true; } } return false; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_dim0(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less) { // if(!gr || !x || !y) return true; // if data is absent then should be segfault!!! long n=y->GetNx(); if(less) { if(x->GetNx()SetWarn(mglWarnDim,name); return true; } if(z && z->GetNx()SetWarn(mglWarnDim,name); return true; } if(r && r->GetNx()SetWarn(mglWarnDim,name); return true; } } else { if(x->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } if(z && z->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } if(r && r->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } } return false; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_dim1(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less) { // if(!gr || !x || !y) return true; // if data is absent then should be segfault!!! long n=y->GetNx(); if(n<2) { gr->SetWarn(mglWarnLow,name); return true; } if(less) { if(x->GetNx()SetWarn(mglWarnDim,name); return true; } if(z && z->GetNx()SetWarn(mglWarnDim,name); return true; } if(r && r->GetNx()SetWarn(mglWarnDim,name); return true; } } else { if(x->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } if(z && z->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } if(r && r->GetNx()!=n) { gr->SetWarn(mglWarnDim,name); return true; } } return false; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_dim3(HMGL gr, bool both, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *name) { // if(!gr || !x || !y || !z || !a) return true; // if data is absent then should be segfault!!! long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); if(n<2 || m<2 || l<2) { gr->SetWarn(mglWarnLow,name); return true; } if(!both && (x->GetNx()!=n || y->GetNx()!=m || z->GetNx()!=l)) { gr->SetWarn(mglWarnDim,name); return true; } if(b && b->GetNN()!=n*m*l) { gr->SetWarn(mglWarnDim,name); return true; } return false; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_trig(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, int d) { // if(!gr || !x || !y || !z || !a || !nums) return true; // if data is absent then should be segfault!!! long n = x->GetNN(), m = nums->GetNy(); if(nums->GetNx()SetWarn(mglWarnLow,name); return true; } if(y->GetNN()!=n || z->GetNN()!=n) { gr->SetWarn(mglWarnDim,name); return true; } if(a->GetNN()!=m && a->GetNN()!=n) { gr->SetWarn(mglWarnDim,name); return true; } return false; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_isnboth(HCDT x, HCDT y, HCDT z, HCDT a) { long n=a->GetNN(); return x->GetNN()!=n || y->GetNN()!=n || z->GetNN()!=n; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_isboth(HCDT x, HCDT y, HCDT z, HCDT a) { long n=a->GetNN(); return x->GetNN()==n && y->GetNN()==n && z->GetNN()==n; } //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_vec3(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *name) { // if(!gr || !x || !y || !z || !ax || !ay || !az) return true; // if data is absent then should be segfault!!! long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(), nn=n*m*l; if(nn!=ay->GetNN() || nn!=az->GetNN()) { gr->SetWarn(mglWarnDim,name); return true; } if(n<2 || m<2 || l<2) { gr->SetWarn(mglWarnLow,name); return true; } bool both = x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn; if(!(both || (x->GetNx()==n && y->GetNx()==m && z->GetNx()==l))) { gr->SetWarn(mglWarnDim,name); return true; } return false; } //----------------------------------------------------------------------------- void mglBase::ClearUnused() { #if MGL_HAVE_PTHREAD pthread_mutex_lock(&mutexPnt); pthread_mutex_lock(&mutexPrm); #endif #pragma omp critical { size_t l=Prm.size(); // find points which are actually used long *used = new long[Pnt.size()]; memset(used,0,Pnt.size()*sizeof(long)); for(size_t i=0;i=0) used[p.n2] = 1; break; case 2: if(p.n2>=0 && p.n3>=0) used[p.n2] = used[p.n3] = 1; break; case 3: if(p.n2>=0 && p.n3>=0 && p.n4>=0) used[p.n2] = used[p.n3] = used[p.n4] = 1; break; } } // now add proper indexes l=Pnt.size(); mglStack pnt; pnt.reserve(l); for(size_t i=0;i=num) break; float t1=-100, t2=100; // XY angle boundary float rg1=-100, rg2=100; // RG angle boundary float gb1=-100, gb2=100; // GB angle boundary size_t k; for(k=i+1;k t+d || t2 < t-d) break; // too curved const mglColor c2(GetPntC(k0+(k-1)*step)-c1); dd = c2.NormS(); if(dd>0) // color are different { float rg = atan2(c2.r,c2.g), gb = atan2(c2.g,c2.b); d = atan(1e-4/dd); if(rg1 > rg+d || rg2 < rg-d || gb1 > gb+d || gb2 < gb-d) break; // too curved rg1 = rg1rg+d?rg+d:rg2; // new RG range gb1 = gb1gb+d?gb+d:gb2; // new GB range } t1 = t1t+d?t+d:t2; // new range } k--; line_plot(k0+i*step,k0+k*step); i = k-1; } } //----------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/src/cont.cpp���������������������������������������������������������������������������0000644�0001750�0001750�00000214670�13513030041�015415� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * cont.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ // NOTE: Borland before 2007 (i.e. < 0x0600) use , after 0x0630 it use . // I don't find information about 2009, 2010 versions (i.e. 0x0610 and 0x0620). // May be condition below can be rewritten as (__CODEGEARC__ >= 0x0600) #if !defined(__BORLANDC__) || (__CODEGEARC__ >= 0x0630) #include #else #include #endif #include #include "mgl2/surf.h" #include "mgl2/cont.h" #include "mgl2/data.h" #include "mgl2/eval.h" #include "mgl2/font.h" #include "mgl2/base.h" //----------------------------------------------------------------------------- // // Text printing along a curve // //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_string_curve(mglBase *gr,long f,long ,const long *ff,const long *nn,const wchar_t *text, const char *font, mreal size) { if(f<0 || nn[f]<0) return; // do nothing since there is no curve if(!font) font=""; int pos = strchr(font,'T') ? 1:-1, align; bool cc=mglGetStyle(font,0,&align); align = align&3; mreal h=gr->TextHeight(font,size)/2, g = 1.1*h; wchar_t L[2]=L"a"; if(align==1) // TODO divide curve by 2 {} std::vector qa, qb; // curves above and below original if(ff[f]<0) for(long i=nn[f];i>=0 && i!=f;i=nn[i]) // find first real point if(ff[i]>=0) { f=i; break; } if(ff[f]<0) return; mreal c=cc?gr->AddTexture(font) : gr->GetClrC(ff[f]); mglPoint p=gr->GetPntP(ff[f]), q=p, s; for(long i=nn[f];i>=0 && i!=f;i=nn[i]) // find second real point if(ff[i]>=0) { s=gr->GetPntP(ff[i]); break; } mglPoint l=!(s-q), t=l; qa.push_back(q+l*g); qb.push_back(q-l*h); for(long i=nn[f];i>=0 && i!=f;i=nn[i]) // construct curves { p=q; q=s; l=t; if(nn[i]>=0 && ff[nn[i]]>=0) { s=gr->GetPntP(ff[nn[i]]); t=!(s-q); } mreal tet = t.x*l.y-t.y*l.x; mreal tt = 1+fabs(t.x*l.x+t.y*l.y); if(tet>0) { qa.push_back(q+l*g); qa.push_back(q+t*g); qb.push_back(q-(l+t)*(h/tt)); } else if(tet<0) { qb.push_back(q-l*h); qb.push_back(q-t*h); qa.push_back(q+(l+t)*(g/tt)); } else { qa.push_back(q+l*g); qb.push_back(q-l*h); } } if(pos>0) qa=qb; // adjust text direction bool rev = align==2; const char *ffont=mglchr(font,':'); char *fnt = new char[strlen(font)+5]; if(ffont) strcpy(fnt,ffont); else *fnt=0; /* if(qa[0].x>qa[1].x) { if(align==0){ strcat(fnt,":R"); align=2; } else if(align==1) rev = true; else { strcat(fnt,":L"); align=0; } }*/ if(mglchr(font,'T')) strcat(fnt,":T"); if(rev) reverse(qa.begin(),qa.end()); long len = mgl_wcslen(text); mreal *wdt=new mreal[len+1]; for(long j=0;jTextWidth(L,font,size); } wdt[len]=0; // place glyphs points mglPoint *pt=new mglPoint[len+1]; pt[0] = qa[0]; long i=0, k, m = qa.size(); mreal t1,t2, tt=0; for(long j=0;jw) break; if(k>i+1 && ka*d should be here! if(b*b>1e3*a*d) { t1 = d/(b+w); t2 = d/(b-w); } // keep precision else { t1 = (b-w)/a; t2 = (b+w)/a; } if(t1<0 || t11)?1/MGL_FEPSILON/(len-1):0; for(long j=0;jtext_plot(gr->AddPnt(pt[j]+(pos*h)*l,c+dc*i,align!=2?s:-s,-1,-1),L,fnt,size,0.05,c+dc*j); } delete []wdt; delete []pt; delete []fnt; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z,const wchar_t *text, const char *font, const char *opt) { long n=y->GetNx(); if(mgl_check_dim1(gr,x,y,z,0,"Text")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TextC",cgid++); long kq = gr->AllocPnts(n); long *nn = new long[n], *ff = new long[n]; #pragma omp parallel for for(long i=0;iAddPntQ(kq+i,mglPoint(x->v(i),y->v(i),z->v(i)),-1); } nn[n-1]=-1; mgl_string_curve(gr,0,n,ff,nn,text,font,-1); delete []ff; delete []nn; gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textw_xy(HMGL gr, HCDT x, HCDT y, const wchar_t *text, const char *font, const char *opt) { gr->SaveState(opt); mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_textw_xyz(gr,x,y,&z,text,font,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_textw_y(HMGL gr, HCDT y, const wchar_t *text, const char *font, const char *opt) { gr->SaveState(opt); mglDataV x(y->GetNx()), z(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_textw_xyz(gr,&x,y,&z,text,font,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_text_xyz(HMGL gr, HCDT x, HCDT y, HCDT z,const char *text, const char *font, const char *opt) { MGL_TO_WCS(text,mgl_textw_xyz(gr,x,y,z, wcs, font, opt)); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_text_xy(HMGL gr, HCDT x, HCDT y, const char *text, const char *font, const char *opt) { mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin()); mgl_text_xyz(gr,x,y,&z,text,font,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_text_y(HMGL gr, HCDT y, const char *text, const char *font, const char *opt) { mglDataV x(y->GetNx()), z(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin()); mgl_text_xyz(gr,&x,y,&z,text,font,opt); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_text_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z,const char *text,const char *font, const char *opt,int l,int n,int lo) { char *s=new char[l+1]; memcpy(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,font,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_text_xyz(_GR_, _DA_(x),_DA_(y), _DA_(z), s, f, o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_text_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *text, const char *font, const char *opt, int l,int n,int lo) { char *s=new char[l+1]; memcpy(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,font,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_text_xy(_GR_, _DA_(x),_DA_(y),s,f,o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_text_y_(uintptr_t *gr, uintptr_t *y, const char *text, const char *font, const char *opt, int l,int n,int lo) { char *s=new char[l+1]; memcpy(s,text,l); s[l]=0; char *f=new char[n+1]; memcpy(f,font,n); f[n]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_text_y(_GR_, _DA_(y),s,f,o); delete []o; delete []s; delete []f; } //----------------------------------------------------------------------------- // // Cont series // //----------------------------------------------------------------------------- #include "cont.hpp" //----------------------------------------------------------------------------- std::vector MGL_EXPORT mgl_get_lines(mreal val, HCDT a, HCDT x, HCDT y, HCDT z, long ak) { long n=a->GetNx(), m=a->GetNy(); std::vector lines; // first add all possible lines for(long j=0;jv(i,j,ak),v2=a->v(i+1,j,ak),v3=a->v(i,j+1,ak),v4=a->v(i+1,j+1,ak); mreal dl=mgl_d(val,v1,v3),dr=mgl_d(val,v2,v4),dp=mgl_d(val,v1,v2),dn=mgl_d(val,v3,v4); bool added=false; if(v1>val || v4>val) { mglSegment line; if(line.set(0,dl,dn,1,i,j,ak,x,y,z)) { lines.push_back(line); added=true; } if(line.set(1,dr,dp,0,i,j,ak,x,y,z)) { lines.push_back(line); added=true; } } else { mglSegment line; if(line.set(0,dl,dp,0,i,j,ak,x,y,z)) { lines.push_back(line); added=true; } if(line.set(1,dr,dn,1,i,j,ak,x,y,z)) { lines.push_back(line); added=true; } } if(!added) // try to add any other variants { mglSegment line; if(line.set(0,dl,1,dr,i,j,ak,x,y,z)) lines.push_back(line); else if(line.set(dp,0,dn,1,i,j,ak,x,y,z)) lines.push_back(line); else if(line.set(0,dl,dn,1,i,j,ak,x,y,z)) lines.push_back(line); else if(line.set(1,dr,dp,0,i,j,ak,x,y,z)) lines.push_back(line); else if(line.set(0,dl,dp,0,i,j,ak,x,y,z)) lines.push_back(line); else if(line.set(1,dr,dn,1,i,j,ak,x,y,z)) lines.push_back(line); } } return lines; } //----------------------------------------------------------------------------- std::vector MGL_EXPORT mgl_get_curvs(const mglPoint &Min, const mglPoint &Max, std::vector lines) { long n = lines.size(), m = n; const long nsl=(n>0 && n*n>100)?sqrt(double(n)):10; mreal dxsl = nsl/((Max.x-Min.x)*MGL_FEPSILON), x0 = Min.x; mreal dysl = nsl/((Max.y-Min.y)*MGL_FEPSILON), y0 = Min.y; std::vector *xsl, *ysl; xsl = new std::vector[nsl+1]; ysl = new std::vector[nsl+1]; for(long i=0;insl) i1=nsl; if(i2<0) i2=0; if(i2>nsl) i2=nsl; if(i1==i2 && i1*(i1-nsl)<=0) xsl[i1].push_back(i); else { if(i1*(i1-nsl)<=0) xsl[i1].push_back(i); if(i2*(i2-nsl)<=0) xsl[i2].push_back(i); } i1 = (lines[i].p1.y-y0)*dysl; i2 = (lines[i].p2.y-y0)*dysl; if(i1<0) i1=0; if(i1>nsl) i1=nsl; if(i2<0) i2=0; if(i2>nsl) i2=nsl; if(i1==i2 && i1*(i1-nsl)<=0) ysl[i1].push_back(i); else { if(i1*(i1-nsl)<=0) ysl[i1].push_back(i); if(i2*(i2-nsl)<=0) ysl[i2].push_back(i); } } size_t xm=0,ym=0; for(long i=0;i<=nsl;i++) { if(xm curvs; char *used = new char[n]; memset(used,0,n); // create curves from lines while(m>0) // NOTE! This algorithm can be *very* slow!!! { mglSegment curv; bool added = false; for(long i=0;i0) { added = false; long i1, i2; if(xm<=ym) { i1 = (curv.p1.x-x0)*dxsl; i2 = (curv.p2.x-x0)*dxsl; } else { i1 = (curv.p1.y-y0)*dysl; i2 = (curv.p2.y-y0)*dysl; } if(i1<0) i1=0; if(i1>nsl) i1=nsl; if(i2<0) i2=0; if(i2>nsl) i2=nsl; const std::vector &isl1=(xm<=ym)?xsl[i1]:ysl[i1]; for(size_t i=0;i &isl2=(xm<=ym)?xsl[i2]:ysl[i2]; if(m>0) for(size_t i=0;i MGL_EXPORT mgl_get_curvs(HMGL gr, std::vector lines) { return mgl_get_curvs(gr->Min, gr->Max, lines); } //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_draw_curvs(HMGL gr, mreal val, mreal c, int text, const std::vector &curvs) { long pc=0; for(size_t i=0;iReserve(pc); // fill arguments for other functions long *ff = new long[pc], *nn = new long[pc], m=0; for(size_t i=0;i &pp=curvs[i].pp; for(std::list::const_iterator it=pp.begin(); it != pp.end(); ++it) { ff[m] = gr->AddPnt(*it, c); nn[m] = m+1; m++; } nn[m-1]=-1; } if(text && pc>1) { wchar_t wcs[64]; mglprintf(wcs,64,L"%4.3g",val); mreal del = 2*gr->TextWidth(wcs,"",-0.5); // find width and height of drawing area mreal ar=gr->GetRatio(), w=gr->GetWidth(), h = gr->GetHeight(); ar = (ar>1?1/ar:1)*gr->FontFactor(); if(delGetPntP(ff[k]); mreal tx = t.x+x0, ty = t.y+y0; // quasi-random shift long i = long(tx/del); tx -= i*del; long j = long(ty/del); ty -= j*del; if(i>=0 && i=0 && jtx) { rr[i]=tx; oo[i]=k; } } } for(long i=0;i=0) mgl_string_curve(gr,oo[i],pc,ff,nn,wcs,text==1?"t:C":"T:C",-0.5); delete []oo; delete []rr; } for(long i=0;i=0) gr->line_plot(ff[i], ff[nn[i]]); delete []nn; delete []ff; } //----------------------------------------------------------------------------- HMDT mgl_data_conts(mreal val, HCDT dat) { mglPoint Min(0,0,0), Max(1,1,1); mglDataV x(dat->GetNx(),dat->GetNy(),dat->GetNz(),0,1,'x'); mglDataV y(dat->GetNx(),dat->GetNy(),dat->GetNz(),0,1,'y'); mglDataV z(dat->GetNx(),dat->GetNy(),dat->GetNz(),0,1,'z'); std::vector curvs = mgl_get_curvs(Min,Max,mgl_get_lines(val,dat,&x,&y,&z,0)); long pc=curvs.size(), m=0; if(pc==0) return NULL; for(size_t i=0;i &pp=curvs[i].pp; for(std::list::const_iterator it=pp.begin(); it != pp.end(); ++it) { long i0 = 3*m; res->a[i0] = (*it).x; res->a[1+i0] = (*it).y; res->a[2+i0] = (*it).z; m++; } long i0 = 3*m; m++; res->a[i0] = res->a[1+i0] = res->a[2+i0] = NAN; } return res; } //----------------------------------------------------------------------------- // NOTE! All data MUST have the same size! Only first slice is used! void MGL_EXPORT mgl_cont_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak) { long n=a->GetNx(), m=a->GetNy(); if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m) { gr->SetWarn(mglWarnDim,"ContGen"); return; } mgl_draw_curvs(gr,val,c,text,mgl_get_curvs(gr,mgl_get_lines(val,a,x,y,z,ak))); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_gen(HMGL gr, double val, HCDT a, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,z,a,"ContGen")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("ContGen",cgid++); int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; gr->SetPenPal(sch); mgl_cont_gen(gr,val,a,x,y,z,gr->CDef,text,0); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"Cont")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Cont",cgid++); int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); mglData xx, yy; if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n) // make { xx.Create(n, m); yy.Create(n, m); for(long i=0;iv(i); for(long j=1;jv(j); for(long i=0;iGetNx();i++) for(long j=0;jGetNz();j++) { if(gr->NeedStop()) continue; mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0; if(z->GetNz()>1) z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1); mglDataV zz(n, m); zz.Fill(z0,z0); mgl_cont_gen(gr,v0,z,x,y,&zz,gr->GetC(s,v0),text,j); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt) { long n = z->GetNx(), m = z->GetNy(); if(m<2 || n<2) { gr->SetWarn(mglWarnLow,"Cont"); return; } gr->SaveState(opt); mglDataV x(n, m), y(n, m); x.Fill(gr->Min.x,gr->Max.x,'x'); y.Fill(gr->Min.y,gr->Max.y,'y'); mgl_cont_xy_val(gr,v,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- #define norm(x,y) ((x)*(x)+(y)*(y)) std::vector MGL_NO_EXPORT mgl_find_saddle_val(HCDT z) { long nx=z->GetNx(), ny=z->GetNy(); std::vector v; for(long i=1;ivthr(i), x1=z->vthr(i+1), x2=z->vthr(i-1), dp=z->vthr(i+nx); if(dd<=x1 && dd<=x2 && dd>=dp) v.push_back(z->vthr(i)); if(dd>=x1 && dd>=x2 && dd<=dp) v.push_back(z->vthr(i)); long i0 = i+nx*(ny-1); dd=z->vthr(i0); x1=z->vthr(i0+1); x2=z->vthr(i0-1); dp=z->vthr(i0-nx); if(dd<=x1 && dd<=x2 && dd>=dp) v.push_back(z->vthr(i0)); if(dd>=x1 && dd>=x2 && dd<=dp) v.push_back(z->vthr(i0)); } for(long j=1;jvthr(i0), dp=z->vthr(i0+1), y1=z->vthr(i0+nx), y2=z->vthr(i0-nx); if(dd<=dp && dd>=y1 && dd>=y2) v.push_back(z->vthr(i0)); if(dd>=dp && dd<=y1 && dd<=y2) v.push_back(z->vthr(i0)); i0 = nx*j+nx-1; dd=z->vthr(i0); dp=z->vthr(i0-1); y1=z->vthr(i0+nx); y2=z->vthr(i0-nx); if(dd<=dp && dd>=y1 && dd>=y2) v.push_back(z->vthr(i0)); if(dd>=dp && dd<=y1 && dd<=y2) v.push_back(z->vthr(i0)); } for(long j=1;jvthr(i0),x1=z->vthr(i0+1),x2=z->vthr(i0-1),y1=z->vthr(i0+nx),y2=z->vthr(i0-nx); if(dd<=x1 && dd<=x2 && dd>=y1 && dd>=y2) ok=true; if(dd>=x1 && dd>=x2 && dd<=y1 && dd<=y2) ok=true; x1=z->vthr(i0+1+nx); x2=z->vthr(i0-1-nx); y1=z->vthr(i0-1+nx); y2=z->vthr(i0+1-nx); if(dd<=x1 && dd<=x2 && dd>=y1 && dd>=y2) ok=true; if(dd>=x1 && dd>=x2 && dd<=y1 && dd<=y2) ok=true; if(ok) v.push_back(z->vthr(i0)); } return v; } void MGL_EXPORT mgl_cont_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); if(mglchr(sch,'.')) { mglDataS v; v.dat = mgl_find_saddle_val(z); if(v.dat.size()>0) { std::sort( v.dat.begin(), v.dat.end() ); v.dat.erase( std::unique( v.dat.begin(), v.dat.end() ), v.dat.end() ); mgl_cont_xy_val(gr,&v,x,y,z,sch,0); } else gr->SetWarn(mglWarnCnt,"Cont"); } else { long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont_xy_val(gr,&v,x,y,z,sch,0); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont(HMGL gr, HCDT z, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); if(mglchr(sch,'.')) { mglDataS v; v.dat = mgl_find_saddle_val(z); if(v.dat.size()>0) { std::sort( v.dat.begin(), v.dat.end() ); v.dat.erase( std::unique( v.dat.begin(), v.dat.end() ), v.dat.end() ); mgl_cont_val(gr,&v,z,sch,0); } else gr->SetWarn(mglWarnCnt,"Cont"); } else { long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont_val(gr,&v,z,sch,0); } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_xy_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_val(_GR_, _DA_(v), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContF series // //----------------------------------------------------------------------------- long static mgl_add_pnt(HMGL gr, mreal d, HCDT x, HCDT y, HCDT z, long i1, long j1, long i2, long j2, mreal c, bool edge) { long res=-1; if(edge || (d>0 && d<1)) { mglPoint p(x->v(i1,j1)*(1-d)+x->v(i2,j2)*d, y->v(i1,j1)*(1-d)+y->v(i2,j2)*d, z->v(i1,j1)*(1-d)+z->v(i2,j2)*d); mglPoint u(x->dvx(i1,j1)*(1-d)+x->dvx(i2,j2)*d, y->dvx(i1,j1)*(1-d)+y->dvx(i2,j2)*d, z->dvx(i1,j1)*(1-d)+z->dvx(i2,j2)*d); mglPoint v(x->dvy(i1,j1)*(1-d)+x->dvy(i2,j2)*d, y->dvy(i1,j1)*(1-d)+y->dvy(i2,j2)*d, z->dvy(i1,j1)*(1-d)+z->dvy(i2,j2)*d); res = gr->AddPnt(p,c,u^v); } return res; } //----------------------------------------------------------------------------- void static mgl_add_range(HMGL gr, HCDT a, HCDT x, HCDT y, HCDT z, long i1, long j1, long di, long dj, mreal c, long &u1, long &u2, long ak, mreal v1, mreal v2) { long i2=i1+di, j2=j1+dj; mreal f1 = a->v(i1,j1,ak), f2 = a->v(i2,j2,ak), d1, d2; d1 = mgl_d(v1,f1,f2); u1 = mgl_add_pnt(gr,d1,x,y,z,i1,j1,i2,j2,c,false); d2 = mgl_d(v2,f1,f2); u2 = mgl_add_pnt(gr,d2,x,y,z,i1,j1,i2,j2,c,false); if(d1>d2) { j2=u1; u1=u2; u2=j2; } if(u1<0) { u1=u2; u2=-1; } } //----------------------------------------------------------------------------- void static mgl_add_edges(HMGL gr, HCDT a, HCDT x, HCDT y, HCDT z, long i1, long j1, long di, long dj, mreal c, long &u1, long &u2, long ak, mreal v1, mreal v2) { long i2=i1+di, j2=j1+dj; u1 = u2 = -1; mreal f1 = a->v(i1,j1,ak), f2 = a->v(i2,j2,ak); if(f1<=v2 && f1>=v1) u1 = mgl_add_pnt(gr,0,x,y,z,i1,j1,i2,j2,c,true); if(f2<=v2 && f2>=v1) u2 = mgl_add_pnt(gr,1,x,y,z,i1,j1,i2,j2,c,true); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, long ak) { long n=a->GetNx(), m=a->GetNy(); if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m) { gr->SetWarn(mglWarnDim,"ContFGen"); return; } gr->Reserve(8*n*m); long *kk = new long[4*n], l1,l2, r1,r2, t1,t2, u1,u2, b1,b2, d1,d2, p[8],num; memset(kk,-1,2*n*sizeof(long)); for(long i=0;i=0) p[num++] = b1; if(t1>=0) p[num++] = t1; if(t2>=0) p[num++] = t2; if(b2>=0) p[num++] = b2; if(r1>=0) p[num++] = r1; if(r2>=0) p[num++] = r2; if(d2>=0) p[num++] = d2; if(u2>=0) p[num++] = u2; if(u1>=0) p[num++] = u1; if(d1>=0) p[num++] = d1; if(l2>=0) p[num++] = l2; if(l1>=0) p[num++] = l1; // d1 u1 u2 d2 // l2 r2 // l1 r1 // b1 t1 t2 b2 // draw it bool b1d2 = a->v(i+1,j,ak)>v2 && a->v(i,j-1,ak)>v2; bool b2d1 = a->v(i,j,ak)>v2 && a->v(i+1,j-1,ak)>v2; // mreal vv = a->linearD(i+0.5,j-0.5,ak,0,0,0); // vv = (vv-v1)*(vv-v2); if(num<3) continue; if(num==4) gr->quad_plot(p[0],p[1],p[3],p[2]); else if(num==3) gr->trig_plot(p[0],p[1],p[2]); else if(num==5) { gr->quad_plot(p[0],p[1],p[3],p[2]); gr->trig_plot(p[0],p[3],p[4]); } else if(num==6) { if(b1>=0 && b2>=0) { gr->quad_plot(b1,b2,l1,r1); gr->quad_plot(l1,r1,u1,u2); } else if(d1>=0 && d2>=0) { gr->quad_plot(d1,d2,l1,r1); gr->quad_plot(l1,r1,t1,t2); } else if(b1>=0 && d2>=0) { if(b2d1) { gr->trig_plot(b1,t1,l1); gr->trig_plot(r1,u1,d2); } else { gr->quad_plot(b1,t1,l1,r1); gr->quad_plot(l1,r1,u1,d2); } } else if(d1>=0 && b2>=0) { if(b1d2) { gr->trig_plot(t1,b2,r1); gr->trig_plot(l1,d1,u1); } else { gr->quad_plot(t1,b2,l1,r1); gr->quad_plot(l1,r1,d1,u1); } } else if(b1>=0 && d1>=0) { gr->quad_plot(b1,d1,t1,u1); gr->quad_plot(t1,u1,r1,r2); } else if(d2>=0 && b2>=0) { gr->quad_plot(d2,b2,u1,t1); gr->quad_plot(t1,u1,l1,l2); } } else if(num==7) { if(b1>=0) { gr->trig_plot(b1,l1,t1); gr->quad_plot(r1,r2,u1,u2); if(!b2d1) gr->quad_plot(l1,t1,u1,r1); } else if(b2>=0) { gr->trig_plot(b2,r1,t1); gr->quad_plot(l1,l2,u2,u1); if(!b1d2) gr->quad_plot(r1,t1,u2,l1); } else if(d2>=0) { gr->trig_plot(d2,r1,u1); gr->quad_plot(l1,l2,t1,t2); if(!b2d1) gr->quad_plot(r1,u1,t2,l2); } else if(d1>=0) { gr->trig_plot(d1,l1,u1); gr->quad_plot(r1,r2,t2,t1); if(!b1d2) gr->quad_plot(l1,u1,t1,r2); } } else if(num==8) { if(b2d1) { if(l2<0) { l2=l1; l1=b1; } if(r2<0) r2=d2; if(t2<0) { t2=t1; t1=b1; } if(u2<0) u2=d2; gr->quad_plot(r1,r2,u1,u2); gr->quad_plot(l1,l2,t1,t2); } else { if(l2<0) l2=d1; if(r2<0) { r2=r1; r1=b2; } if(t2<0) t2=b2; if(u2<0) { u2=u1; u1=d1; } gr->quad_plot(r1,r2,t2,t1); gr->quad_plot(l1,l2,u2,u1); } } } } delete []kk; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_gen(HMGL gr, double v1, mreal v2, HCDT a, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { if(mgl_check_dim2(gr,x,y,z,a,"ContFGen")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("ContFGen",cgid++); gr->SetPenPal(sch); mgl_contf_gen(gr,v1,v2,a,x,y,z,gr->CDef,0); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"ContF")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("ContF",cgid++); long s=gr->AddTexture(sch); bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); mglData xx, yy; if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n) // make { xx.Create(n, m); yy.Create(n, m); for(long i=0;iv(i); for(long j=1;jv(j); for(long i=0;iGetNx()-1;i++) for(long j=0;jGetNz();j++) { if(gr->NeedStop()) continue; mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0; if(z->GetNz()>1) z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1); mglDataV zz(n, m); zz.Fill(z0,z0); mgl_contf_gen(gr,v0,v->v(i+1),z,x,y,&zz,gr->GetC(s,v0),j); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt) { long n = z->GetNx(), m = z->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"Cont"); return; } gr->SaveState(opt); mglDataV x(n, m), y(n, m); x.Fill(gr->Min.x,gr->Max.x,'x'); y.Fill(gr->Min.y,gr->Max.y,'y'); mgl_contf_xy_val(gr,v,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglDataV v(Num+2); v.Fill(gr->Min.c, gr->Max.c); mgl_contf_xy_val(gr,&v,x,y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf(HMGL gr, HCDT z, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglDataV v(Num+2); v.Fill(gr->Min.c, gr->Max.c); mgl_contf_val(gr,&v,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_xy_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_val(_GR_, _DA_(v), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContP series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contp_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,a,"Cont")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Cont",cgid++); int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; bool fill = mglchr(sch,'f'); long s=gr->AddTexture(sch); gr->SetPenPal(sch); mglData xx, yy; if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n) // make { xx.Create(n, m); yy.Create(n, m); for(long i=0;iv(i); for(long j=1;jv(j); for(long i=0;iGetNx();i++) for(long j=0;jGetNz();j++) { if(gr->NeedStop()) continue; if(fill) mgl_contf_gen(gr,v->v(i),v->v(i+1),a,x,y,z,gr->GetC(s,v->v(i)),j); else mgl_cont_gen(gr,v->v(i),a,x,y,z,gr->GetC(s,v->v(i)),text,j); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contp(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_contp_val(gr,&v,x,y,z,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contp_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contp_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contp_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contp(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContD series // //----------------------------------------------------------------------------- int static mgl_get_ncol(const char *sch, char *res) { long j=0; if(sch) for(long i=0;sch[i]&&sch[i]!=':';i++) if(strchr(MGL_COLORS,sch[i])) { if(res) res[j]=sch[i]; j++; } return j?j:strlen(MGL_DEF_PAL); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long j=0,n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"ContD")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("ContD",cgid++); bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); if(sch) for(long i=0;sch[i];i++) if(strchr(MGL_COLORS,sch[i])) j++; if(j==0) sch = MGL_DEF_PAL; long s = gr->AddTexture(sch,1); int nc = gr->GetNumPal(s*256); mglData xx, yy; if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n) // make { xx.Create(n, m); yy.Create(n, m); for(long i=0;iv(i); for(long j=1;jv(j); for(long i=0;i1 ? 1/(MGL_FEPSILON*(nc-1)) : 0; #pragma omp parallel for collapse(2) for(long i=0;iGetNx()-1;i++) for(long j=0;jGetNz();j++) { if(gr->NeedStop()) continue; mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0; if(z->GetNz()>1) z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1); mglDataV zz(n, m); zz.Fill(z0,z0); mgl_contf_gen(gr,v0,v->v(i+1),z,x,y,&zz,s+(i%nc)*dc,j); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt) { long n = z->GetNx(), m = z->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContD"); return; } gr->SaveState(opt); mglDataV x(n, m), y(n, m); x.Fill(gr->Min.x,gr->Max.x,'x'); y.Fill(gr->Min.y,gr->Max.y,'y'); mgl_contd_xy_val(gr,v,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV v(mgl_get_ncol(sch,0)+1); v.Fill(gr->Min.c, gr->Max.c); mgl_contd_xy_val(gr,&v,x,y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd(HMGL gr, HCDT z, const char *sch, const char *opt) { gr->SaveState(opt); mglDataV v(mgl_get_ncol(sch,0)+1); v.Fill(gr->Min.c, gr->Max.c); mgl_contd_val(gr,&v,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contd_xy_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contd_val(_GR_, _DA_(v), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contd_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contd_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contd(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContV series // //----------------------------------------------------------------------------- // NOTE! All data MUST have the same size! Only first slice is used! void MGL_EXPORT mgl_contv_gen(HMGL gr, mreal val, mreal dval, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, long ak) { long n=a->GetNx(), m=a->GetNy(); if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m) { gr->SetWarn(mglWarnDim,"ContGen"); return; } const std::vector curvs = mgl_get_curvs(gr,mgl_get_lines(val,a,x,y,z,ak)); for(size_t i=0;i &pp=curvs[i].pp; long f2=-1,g2=-1; for(std::list::const_iterator it=pp.begin(); it != pp.end(); ++it) { mglPoint p=*it,q(p.y,-p.x); long f1 = f2; f2 = gr->AddPnt(p,c,q); p.z+=dval; long g1 = g2; g2 = gr->AddPnt(p,c,q); gr->quad_plot(f1,g1,f2,g2); } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"ContV")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("ContV",cgid++); bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); mglData xx, yy; if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n) // make { xx.Create(n, m); yy.Create(n, m); for(long i=0;iv(i); for(long j=1;jv(j); for(long i=0;iGetNx();i++) for(long j=0;jGetNz();j++) { if(gr->NeedStop()) continue; mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0; if(z->GetNz()>1) z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1); mglDataV zz(n, m); zz.Fill(z0,z0); mreal dv = (gr->Max.c-gr->Min.c)/8; if(i>0) dv = v->v(i-1)-v->v(i); else if(iGetNx()-1) dv = v->v(i)-v->v(i+1); if(fixed) dv=-dv; mgl_contv_gen(gr,v0,dv,z,x,y,&zz,gr->GetC(s,v0),j); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt) { long n = z->GetNx(), m = z->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"Cont"); return; } gr->SaveState(opt); mglDataV x(n, m), y(n, m); x.Fill(gr->Min.x,gr->Max.x,'x'); y.Fill(gr->Min.y,gr->Max.y,'y'); mgl_contv_xy_val(gr,v,&x,&y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_contv_xy_val(gr,&v,x,y,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv(HMGL gr, HCDT z, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_contv_val(gr,&v,z,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contv_xy_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contv_val(_GR_, _DA_(v), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contv_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contv_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contv(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Cont3 series // //----------------------------------------------------------------------------- struct _mgl_slice { mglData x,y,z,a; }; //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_get_slice(_mgl_slice &s, HCDT x, HCDT y, HCDT z, HCDT a, char dir, mreal d, bool both) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(), nx=1,ny=1,p; if(dir=='x') { nx = m; ny = l; if(d<0) d = n/2.; } if(dir=='y') { nx = n; ny = l; if(d<0) d = m/2.; } if(dir=='z') { nx = n; ny = m; if(d<0) d = l/2.; } s.x.Create(nx,ny); s.y.Create(nx,ny); s.z.Create(nx,ny); s.a.Create(nx,ny); p = long(d); d -= p; if(dir=='x' && p>=n-1) { d+=p-n+2; p=n-2; } if(dir=='y' && p>=m-1) { d+=p-m+2.; p=m-2; } if(dir=='z' && p>=l-1) { d+=p-l+2; p=l-2; } mreal v; if(both) { if(dir=='x') #pragma omp parallel for collapse(2) for(long j=0;jv(p,i,j)*(1-d) + x->v(p+1,i,j)*d; s.y.a[i0] = y->v(p,i,j)*(1-d) + y->v(p+1,i,j)*d; s.z.a[i0] = z->v(p,i,j)*(1-d) + z->v(p+1,i,j)*d; s.a.a[i0] = a->v(p,i,j)*(1-d) + a->v(p+1,i,j)*d; } if(dir=='y') #pragma omp parallel for collapse(2) for(long j=0;jv(i,p,j)*(1-d) + x->v(i,p+1,j)*d; s.y.a[i0] = y->v(i,p,j)*(1-d) + y->v(i,p+1,j)*d; s.z.a[i0] = z->v(i,p,j)*(1-d) + z->v(i,p+1,j)*d; s.a.a[i0] = a->v(i,p,j)*(1-d) + a->v(i,p+1,j)*d; } if(dir=='z') #pragma omp parallel for collapse(2) for(long j=0;jv(i,j,p)*(1-d) + x->v(i,j,p+1)*d; s.y.a[i0] = y->v(i,j,p)*(1-d) + y->v(i,j,p+1)*d; s.z.a[i0] = z->v(i,j,p)*(1-d) + z->v(i,j,p+1)*d; s.a.a[i0] = a->v(i,j,p)*(1-d) + a->v(i,j,p+1)*d; } } else // x, y, z -- vectors { if(dir=='x') { v = x->v(p)*(1-d)+x->v(p+1)*d; #pragma omp parallel for collapse(2) for(long j=0;jv(i); s.z.a[i0] = z->v(j); s.a.a[i0] = a->v(p,i,j)*(1-d) + a->v(p+1,i,j)*d; } } if(dir=='y') { v = y->v(p)*(1-d)+y->v(p+1)*d; #pragma omp parallel for collapse(2) for(long j=0;jv(i); s.z.a[i0] = z->v(j); s.a.a[i0] = a->v(i,p,j)*(1-d) + a->v(i,p+1,j)*d; } } if(dir=='z') { v = z->v(p)*(1-d)+z->v(p+1)*d; #pragma omp parallel for collapse(2) for(long j=0;jv(i); s.y.a[i0] = y->v(j); s.a.a[i0] = a->v(i,j,p)*(1-d) + a->v(i,j,p+1)*d; } } } } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt) { bool both = mgl_isboth(x,y,z,a); if(mgl_check_dim3(gr,both,x,y,z,a,0,"Cont3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Cont3",cgid++); char dir='y'; if(mglchr(sch,'x')) dir='x'; if(mglchr(sch,'z')) dir='z'; int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; long ss=gr->AddTexture(sch); gr->SetPenPal(sch); _mgl_slice s; mgl_get_slice(s,x,y,z,a,dir,sVal,both); #pragma omp parallel for for(long i=0;iGetNx();i++) { mreal v0 = v->v(i); mgl_cont_gen(gr,v0,&s.a,&s.x,&s.y,&s.z,gr->GetC(ss,v0),text,0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sVal, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_cont3_xyz_val(gr,v,&x,&y,&z,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont3"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont3_xyz_val(gr,&v,x,y,z,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Cont3"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont3_val(gr,&v,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_xyz_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont3_xyz_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont3_val(_GR_, _DA_(v), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_cont3(_GR_, _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Dens3 series // //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_surf_gen(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch); void MGL_EXPORT mgl_dens3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt) { bool both = mgl_isboth(x,y,z,a); if(mgl_check_dim3(gr,both,x,y,z,a,0,"Dens3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Dens3",cgid++); char dir='y'; if(mglchr(sch,'x')) dir='x'; if(mglchr(sch,'z')) dir='z'; _mgl_slice s; mgl_get_slice(s,x,y,z,a,dir,sVal,both); mgl_surf_gen(gr, &s.x,&s.y,&s.z,&s.a, 0, sch); // mgl_surfc_xy(gr,&s.x,&s.y,&s.z,&s.a,sch,0); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_dens3_xyz(gr,&x,&y,&z,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_dens3(_GR_, _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Grid3 series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt) { bool both = mgl_isboth(x,y,z,a); if(mgl_check_dim3(gr,both,x,y,z,a,0,"Grid3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Grid3",cgid++); char dir='y'; if(mglchr(sch,'x')) dir='x'; if(mglchr(sch,'z')) dir='z'; _mgl_slice s; mgl_get_slice(s,x,y,z,a,dir,sVal,both); mgl_mesh_xy(gr,&s.x,&s.y,&s.z,sch,0); gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_grid3_xyz(gr,&x,&y,&z,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grid3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_grid3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_grid3(_GR_, _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // ContF3 series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt) { bool both = mgl_isboth(x,y,z,a); if(mgl_check_dim3(gr,both,x,y,z,a,0,"ContF3")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("ContF3",cgid++); char dir='y'; if(mglchr(sch,'x')) dir='x'; if(mglchr(sch,'z')) dir='z'; long ss=gr->AddTexture(sch); _mgl_slice s; mgl_get_slice(s,x,y,z,a,dir,sVal,both); #pragma omp parallel for for(long i=0;iGetNx()-1;i++) { mreal v0 = v->v(i); mgl_contf_gen(gr,v0,v->v(i+1),&s.a,&s.x,&s.y,&s.z,gr->GetC(ss,v0),0); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sVal, const char *opt) { gr->SaveState(opt); mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz()); x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z); mgl_contf3_xyz_val(gr,v,&x,&y,&z,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"ContF3"); return; } mglDataV v(Num+2); v.Fill(gr->Min.c, gr->Max.c); mgl_contf3_xyz_val(gr,&v,x,y,z,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?7:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"ContF3"); return; } mglDataV v(Num+2); v.Fill(gr->Min.c, gr->Max.c); mgl_contf3_val(gr,&v,a,sch,sVal,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_xyz_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf3_xyz_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf3_val(_GR_, _DA_(v), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_contf3(_GR_, _DA_(a), s, *sVal, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Axial series // //----------------------------------------------------------------------------- long MGL_LOCAL_PURE mgl_find_prev(long i, long pc, long *nn) { for(long k=0;kReserve(pc*82); for(long i=0;iAllocPnts(41*2); #pragma omp parallel for for(long j=0;j<41;j++) { float co = mgl_cos[(j*18)%360], si = mgl_cos[(270+j*18)%360]; // fi = j*M_PI/20; si = sin(fi); co = cos(fi); mglPoint p1 = a*ff[i].y + b*(si*ff[i].x) + c*(co*ff[i].x); mglPoint p2 = a*ff[nn[i]].y + b*(si*ff[nn[i]].x) + c*(co*ff[nn[i]].x); if(wire) { gr->AddPntQ(kq+2*j,p1,cc); gr->AddPntQ(kq+2*j+1,p2,cc); } else { gr->AddPntQ(kq+2*j, p1,cc,(a*q1.y + b*(si*q1.x) + c*(co*q1.x))^(b*co-c*si)); gr->AddPntQ(kq+2*j+1,p2,cc,(a*q2.y + b*(si*q2.x) + c*(co*q2.x))^(b*co-c*si)); } } if(wire==1) { gr->line_plot(kq,kq+1); for(long j=1;j<41;j++) { gr->line_plot(kq+2*j,kq+2*j+1); gr->line_plot(kq+2*j,kq+2*j-2); gr->line_plot(kq+2*j-1,kq+2*j+1); gr->line_plot(kq+2*j-1,kq+2*j-2); } } else if(wire) for(long j=0;j<41;j++) { gr->mark_plot(kq+2*j,'.'); gr->mark_plot(kq+2*j+1,'.'); } else for(long j=1;j<41;j++) { long i0 = kq+2*j; gr->quad_plot(i0-2,i0-1,i0,i0+1); } } } //----------------------------------------------------------------------------- // NOTE! All data MUST have the same size! Only first slice is used! void MGL_EXPORT mgl_axial_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, mreal c, char dir,long ak,int wire) { long n=a->GetNx(), m=a->GetNy(); if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m) { gr->SetWarn(mglWarnDim,"ContGen"); return; } mglPoint *kk = new mglPoint[2*n*m],*pp = new mglPoint[2*n*m],p; long pc=0; // Usually number of points is much smaller. So, there is no reservation. // gr->Reserve(2*n*m); // add intersection point of isoline and X or Y axis const mglData *mx = dynamic_cast(x); const mglData *my = dynamic_cast(y); const mglData *ma = dynamic_cast(a); if(mx&&my&&ma) for(long j=0;ja[i0+n*m*ak],ma->a[i0+1+n*m*ak]):-1; if(d>=0 && d<1) { pp[pc].Set(mx->a[i0]*(1-d)+mx->a[i0+1]*d, my->a[i0]*(1-d)+my->a[i0+1]*d); kk[pc].Set(i+d,j); pc++; } d = (ja[i0+n*m*ak],ma->a[i0+n*m*ak+n]):-1; if(d>=0 && d<1) { pp[pc].Set(mx->a[i0]*(1-d)+mx->a[i0+n]*d, my->a[i0]*(1-d)+my->a[i0+n]*d); kk[pc].Set(i,j+d); pc++; } } else for(long j=0;jv(i,j,ak),vx=x->v(i,j),vy=y->v(i,j); mreal d = (iv(i+1,j,ak)):-1; if(d>=0 && d<1) { pp[pc].Set(vx*(1-d)+x->v(i+1,j)*d, vy*(1-d)+y->v(i+1,j)*d); kk[pc].Set(i+d,j); pc++; } d = (jv(i,j+1,ak)):-1; if(d>=0 && d<1) { pp[pc].Set(vx*(1-d)+x->v(i,j+1)*d, vy*(1-d)+y->v(i,j+1)*d); kk[pc].Set(i,j+d); pc++; } } // deallocate arrays and finish if no point if(pc==0) { delete []kk; delete []pp; return; } // allocate arrays for curve long *nn = new long[pc], *ff = new long[pc]; for(long i=0;i=0) { mreal kx = kk[j].x, ky = kk[j].y; long i = -1; long i11 = long(kx+1e-5), i12 = long(kx-1e-5); long j11 = long(ky+1e-5), j12 = long(ky-1e-5); for(long k=0;k=0); mgl_axial_plot(gr,pc,pp,nn,dir,c,wire); delete []kk; delete []nn; delete []ff; delete []pp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { long n=z->GetNx(),m=z->GetNy(); if(mgl_check_dim2(gr,x,y,z,0,"Axial")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("Axial",cgid++); long s=gr->AddTexture(sch); char dir='y'; if(mglchr(sch,'x')) dir = 'x'; if(mglchr(sch,'z')) dir = 'z'; mglData xx, yy; if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n) // make { xx.Create(n, m); yy.Create(n, m); for(long i=0;iv(i); for(long j=1;jv(j); for(long i=0;iGetNx();i++) for(long j=0;jGetNz();j++) { if(gr->NeedStop()) continue; mreal v0 = v->v(i); mgl_axial_gen(gr,v0,z,x,y,gr->GetC(s,v0),dir,j,wire); } gr->EndGroup(); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_val(HMGL gr, HCDT v, HCDT a, const char *sch, const char *opt) { long n=a->GetNx(), m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"Axial"); return; } gr->SaveState(opt); mglDataV x(n, m), y(n, m); if(gr->Max.x*gr->Min.x>=0) x.Fill(gr->Min.x,gr->Max.x,'x'); else x.Fill(0,gr->Max.x,'x'); y.Fill(gr->Min.y,gr->Max.y,'y'); mgl_axial_xy_val(gr,v,&x,&y,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_xy(HMGL gr, HCDT x, HCDT y, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?3:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Axial"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_axial_xy_val(gr,&v,x,y,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial(HMGL gr, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long Num = mgl_isnan(r)?3:long(r+0.5); if(Num<1) { gr->SetWarn(mglWarnCnt,"Axial"); return; } mglData v(Num); for(long i=0;iMin.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_axial_val(gr,&v,a,sch,0); } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_axial_xy_val(_GR_, _DA_(v), _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_axial_val(_GR_, _DA_(v), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_axial_xy(_GR_, _DA_(x), _DA_(y), _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_axial_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_axial(_GR_, _DA_(a), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- // // Torus series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_torus(HMGL gr, HCDT r, HCDT z, const char *sch, const char *opt) { long i,j,n=r->GetNx(); if(n*r->GetNy()!=z->GetNx()*z->GetNy()) { gr->SetWarn(mglWarnDim,"Torus"); return; } if(n<2) { gr->SetWarn(mglWarnLow,"Torus"); return; } gr->SaveState(opt); static int cgid=1; gr->StartGroup("Torus",cgid++); mglPoint *pp = new mglPoint[n]; long *nn = new long[n]; long ss=gr->AddTexture(sch); char dir='y'; if(mglchr(sch,'x')) dir = 'x'; if(mglchr(sch,'z')) dir = 'z'; mreal c = gr->GetC(ss,gr->Min.c); const mglData *mr = dynamic_cast(r); const mglData *mz = dynamic_cast(z); int wire = mglchr(sch,'#')?1:0; if(mglchr(sch,'.')) wire = 2; for(j=0;jGetNy();j++) { if(mr&&mz) for(i=0;ia[i+n*j], mz->a[i+n*j]); } else for(i=0;iv(i,j), z->v(i,j)); } mgl_axial_plot(gr,n,pp,nn,dir,c,wire); } gr->EndGroup(); delete []nn; delete []pp; } //----------------------------------------------------------------------------- void MGL_EXPORT mgl_torus_(uintptr_t *gr, uintptr_t *r, uintptr_t *z, const char *pen, const char *opt,int l,int lo) { char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0; char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0; mgl_torus(_GR_, _DA_(r), _DA_(z), s, o); delete []o; delete []s; } //----------------------------------------------------------------------------- ������������������������������������������������������������������������mathgl-2.4.4/include/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�13513030041�014570� 5����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�13513030041�015431� 5����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/abstract.h����������������������������������������������������������������0000644�0001750�0001750�00000053640�13513030041�017415� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * abstract.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_ABSTRACT_H_ #define _MGL_ABSTRACT_H_ #include "mgl2/define.h" //----------------------------------------------------------------------------- #ifdef __cplusplus #include "mgl2/type.h" #define MGL_TO_WCS(str,code) if(str && *str){size_t s=mbstowcs(0,str,0); wchar_t *wcs=new wchar_t[s+1]; mbstowcs(wcs,str,s); wcs[s]=0; code; delete []wcs;}else{const wchar_t *wcs=L""; code;} //----------------------------------------------------------------------------- class mglBase; class mglData; class mglDataA; class mglDataC; class mglParser; class mglFormula; class mglFormulaC; class mglFont; typedef mglBase* HMGL; typedef mglData* HMDT; typedef mglDataC* HADT; typedef mglParser* HMPR; typedef mglFormula* HMEX; typedef mglFormulaC* HAEX; typedef const mglDataA* HCDT; //----------------------------------------------------------------------------- std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns); std::string MGL_EXPORT mgl_datac_to_string(HCDT d, long ns); /// Get section separated by symbol ch. This is analog of QString::section(). std::string MGL_EXPORT mgl_str_arg(const std::string &str, char ch, int n1, int n2=-1); /// Get sections separated by symbol ch std::vector MGL_EXPORT mgl_str_args(const std::string &str, char ch); /// Get string from real number std::string MGL_EXPORT mgl_str_num(double val); /// Get string from complex number std::string MGL_EXPORT mgl_str_num(dual val); //----------------------------------------------------------------------------- extern "C" { #else #define mglDataA void #define mglNum void typedef void *HMGL; typedef void *HMDT; typedef void *HADT; typedef void *HMEX; typedef void *HAEX; typedef void *HMPR; typedef const void *HCDT; #endif /// Set buffer size for number of primitives as (1<0 ? (i0 ? (j0 ? (k1?GetNx()-1:1; dif.y*=GetNy()>1?GetNy()-1:1; dif.z*=GetNz()>1?GetNz()-1:1; return res; } /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] inline mreal Linear(mreal x,mreal y=0,mreal z=0) const { return mgl_data_linear_ext(this,x,y,z,0,0,0); } /// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1] inline mreal Linear1(mreal x,mreal y=0,mreal z=0) const { return mgl_data_linear_ext(this,x*(GetNx()-1),y*(GetNy()-1),z*(GetNz()-1),0,0,0); } /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] inline mreal Linear(mglPoint &dif, mreal x,mreal y=0,mreal z=0) const { return mgl_data_linear_ext(this,x,y,z, &(dif.x),&(dif.y), &(dif.z)); } /// Interpolate by line the data and return its derivatives at given point x,\a y,\a z which normalized in range [0, 1] inline mreal Linear1(mglPoint &dif, mreal x,mreal y=0,mreal z=0) const { mreal res=mgl_data_linear_ext(this,x*(GetNx()-1),y*(GetNy()-1),z*(GetNz()-1), &(dif.x),&(dif.y), &(dif.z)); dif.x*=GetNx()>1?GetNx()-1:1; dif.y*=GetNy()>1?GetNy()-1:1; dif.z*=GetNz()>1?GetNz()-1:1; return res; } }; //----------------------------------------------------------------------------- /// Structure for color ID struct MGL_EXPORT mglColorID { char id; mglColor col; }; MGL_EXPORT extern mglColorID mglColorIds[31]; MGL_EXPORT extern std::string mglGlobalMess; ///< Buffer for receiving global messages //----------------------------------------------------------------------------- #endif #ifdef MGL_SRC #define _Da_(d) (*((const mglDataA *)(d))) #define _DA_(a) ((const mglDataA *)*(a)) #define _GR_ ((mglBase *)(*gr)) //#define _D_(d) *((mglData *)*(d)) #define _DM_(a) ((mglData *)*(a)) #define _DT_ ((mglData *)*d) #endif #endif ������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/vect.h��������������������������������������������������������������������0000644�0001750�0001750�00000047036�13513030041�016555� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * vect.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_VECT_H_ #define _MGL_VECT_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------- /// Plot vectors at position {x,y} along {ax,ay} with length/color proportional to |a| /** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */ void MGL_EXPORT mgl_traj_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_traj_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int); /// Plot vectors at position {x,y,z} along {ax,ay,az} with length/color proportional to |a| /** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */ void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_traj_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int,int); /// Plot vector field {ax,ay} parametrically depended on coordinate {x,y} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ void MGL_EXPORT mgl_vect_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_vect_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int); /// Plot vector field {ax,ay} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ void MGL_EXPORT mgl_vect_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_vect_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int); /// Plot vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ void MGL_EXPORT mgl_vect_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_vect_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int,int); /// Plot vector field {ax,ay,az} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ void MGL_EXPORT mgl_vect_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_vect_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int,int); /// Plot flows for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘.’ for threads from vicinity of saddle point; * ‘v’ for drawing arrows on the threads. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_flow_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int); /// Plot flows for vector field {ax,ay} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘.’ for threads from vicinity of saddle point; * ‘v’ for drawing arrows on the threads. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_flow_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_flow_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int); /// Plot flows for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_flow_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int,int); /// Plot flows for vector field {ax,ay,az} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_flow_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_flow_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int,int); /// Plot flows from given plain for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘v’ for drawing arrows on the threads; * 't' for drawing tapes of normals in x-y and y-z planes. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_flow3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_flow3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, double *sVal, const char *opt,int,int); /// Plot flows from given plain for vector field {ax,ay,az} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘v’ for drawing arrows on the threads; * 't' for drawing tapes of normals in x-y and y-z planes. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_flow3(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_flow3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, double *sVal, const char *opt,int,int); /// Plot flow from point p for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘>’ for drawing in forward direction only; * ‘<’ for drawing in backward direction only; * ‘v’ for drawing arrows on the threads. */ void MGL_EXPORT mgl_flowp_xy(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_flowp_xy_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int, int); /// Plot flow from point p for vector field {ax,ay} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘>’ for drawing in forward direction only; * ‘<’ for drawing in backward direction only; * ‘v’ for drawing arrows on the threads. */ void MGL_EXPORT mgl_flowp_2d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_flowp_2d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int, int); /// Plot flow from point p for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘>’ for drawing in forward direction only; * ‘<’ for drawing in backward direction only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */ void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_flowp_xyz_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int, int); /// Plot flow from point p for vector field {ax,ay,az} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘>’ for drawing in forward direction only; * ‘<’ for drawing in backward direction only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */ void MGL_EXPORT mgl_flowp_3d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt); void MGL_EXPORT mgl_flowp_3d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int,int); /// Plot flow pipes for vector field {ax,ay} parametrically depended on coordinate {x,y} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt); void MGL_EXPORT mgl_pipe_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, mreal *r0, const char *opt,int,int); /// Plot flow pipes for vector field {ax,ay} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_pipe_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt); void MGL_EXPORT mgl_pipe_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, mreal *r0, const char *opt,int,int); /// Plot flow pipes for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt); void MGL_EXPORT mgl_pipe_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *r0, const char *opt,int,int); /// Plot flow pipes for vector field {ax,ay,az} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_pipe_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt); void MGL_EXPORT mgl_pipe_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *r0, const char *opt,int,int); /// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y,z} /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_grad_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ph, const char *sch, const char *opt); void MGL_EXPORT mgl_grad_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ph, const char *sch, const char *opt,int, int); /// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y} /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_grad_xy(HMGL gr, HCDT x, HCDT y, HCDT ph, const char *sch, const char *opt); void MGL_EXPORT mgl_grad_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ph, const char *sch, const char *opt,int,int); /// Plot flows for gradient of scalar field phi /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ void MGL_EXPORT mgl_grad(HMGL gr, HCDT ph, const char *sch, const char *opt); void MGL_EXPORT mgl_grad_(uintptr_t *gr, uintptr_t *ph, const char *sch, const char *opt,int,int); /// Draw vector plot along slice for 3d data specified parametrically /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows, * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */ void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_vect3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw vector plot along slice for 3d data /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows, * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */ void MGL_EXPORT mgl_vect3(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_vect3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *sVal, const char *opt,int,int); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/plot.h��������������������������������������������������������������������0000644�0001750�0001750�00000050053�13513030041�016563� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * plot.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_1D_H_ #define _MGL_1D_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Draw curve for formula with x in x-axis range /** Option "value" set initial number of points. */ void MGL_EXPORT mgl_fplot(HMGL gr, const char *eqY, const char *pen, const char *opt); void MGL_EXPORT mgl_fplot_(uintptr_t *gr, const char *fy, const char *stl, const char *opt, int ly, int ls, int lo); /// Draw curve for formulas parametrically depended on t in range [0,1] /** Option "value" set initial number of points. */ void MGL_EXPORT mgl_fplot_xyz(HMGL gr, const char *eqX, const char *eqY, const char *eqZ, const char *pen, const char *opt); void MGL_EXPORT mgl_fplot_xyz_(uintptr_t *gr, const char *fx, const char *fy, const char *fz, const char *stl, const char *opt, int lx, int ly, int lz, int ls, int lo); /// Draw radar chart (plot in curved coordinates) /** Option "value" set the additional shift of data (i.e. the data a+value is used instead of a).*/ void MGL_EXPORT mgl_radar(HMGL graph, HCDT a, const char *pen, const char *opt); void MGL_EXPORT mgl_radar_(uintptr_t *gr, uintptr_t *a, const char *pen, const char *opt, int l,int lo); /// Draw usual curve {x,y,z} void MGL_EXPORT mgl_plot_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_plot_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw usual curve {x,y} void MGL_EXPORT mgl_plot_xy(HMGL graph, HCDT x, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_plot_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw usual curve {x,y} with x in x-axis range void MGL_EXPORT mgl_plot(HMGL graph, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_plot_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw curve {x,y,z} which is colored by c (like tension plot) void MGL_EXPORT mgl_tens_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT c, const char *pen, const char *opt); void MGL_EXPORT mgl_tens_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *pen, const char *opt,int,int); /// Draw curve {x,y} which is colored by c (like tension plot) void MGL_EXPORT mgl_tens_xy(HMGL graph, HCDT x, HCDT y, HCDT c, const char *pen, const char *opt); void MGL_EXPORT mgl_tens_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *c, const char *pen, const char *opt,int,int); /// Draw curve {x,y} with x in x-axis range which is colored by c (like tension plot) void MGL_EXPORT mgl_tens(HMGL graph, HCDT y, HCDT c, const char *pen, const char *opt); void MGL_EXPORT mgl_tens_(uintptr_t *graph, uintptr_t *y, uintptr_t *c, const char *pen, const char *opt,int,int); /// Draw tapes which rotates as (bi-)normales of curve {x,y,z} /** The width of tape is proportional to barwidth and can be changed by option "value".*/ void MGL_EXPORT mgl_tape_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_tape_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw tapes which rotates as (bi-)normales of curve {x,y} /** The width of tape is proportional to barwidth and can be changed by option "value".*/ void MGL_EXPORT mgl_tape_xy(HMGL graph, HCDT x, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_tape_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw tapes which rotates as (bi-)normales of curve {x,y} with x in x-axis range /** The width of tape is proportional to barwidth and can be changed by option "value".*/ void MGL_EXPORT mgl_tape(HMGL graph, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_tape_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw box-plot (special 5-value plot used in statistic) for data specified parametrically /** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/ void MGL_EXPORT mgl_boxplot_xy(HMGL graph, HCDT x, HCDT a, const char *pen, const char *opt); void MGL_EXPORT mgl_boxplot_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw box-plot (special 5-value plot used in statistic) /** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/ void MGL_EXPORT mgl_boxplot(HMGL graph, HCDT a, const char *pen, const char *opt); void MGL_EXPORT mgl_boxplot_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Fill area between curve {x,y,z} and axis plane /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_area_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_area_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Fill area between curve {x,y} and axis plane /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_area_xy(HMGL graph, HCDT x, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_area_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Fill area between curve {x,y} with x in x-axis range and axis plane /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_area(HMGL graph, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_area_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Fill area (draw ribbon) between curves {x1,y1,z1} and {x2,y2,z2} /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_region_3d(HMGL graph, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT y2, HCDT z2, const char *pen, const char *opt); void MGL_EXPORT mgl_region_3d_(uintptr_t *graph, uintptr_t *x1, uintptr_t *y1, uintptr_t *z1, uintptr_t *x2, uintptr_t *y2, uintptr_t *z2, const char *pen, const char *opt,int,int); /// Fill area between curves {x,y1} and {x,y2} /** Style 'i' will fill area only if y1 < y2. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_region_xy(HMGL graph, HCDT x, HCDT y1, HCDT y2, const char *pen, const char *opt); void MGL_EXPORT mgl_region_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int, int); /// Fill area between curves {x,y1} and {x,y2} with x in x-axis range /** Style 'i' will fill area only if y1 < y2. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_region(HMGL graph, HCDT y1, HCDT y2, const char *pen, const char *opt); void MGL_EXPORT mgl_region_(uintptr_t *graph, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int, int); /// Draw vertical lines from points {x,y,z} to axis plane void MGL_EXPORT mgl_stem_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_stem_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw vertical lines from points {x,y} to axis plane void MGL_EXPORT mgl_stem_xy(HMGL graph, HCDT x, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_stem_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw vertical lines from points {x,y} with x in x-axis range to axis plane void MGL_EXPORT mgl_stem(HMGL graph, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_stem_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw stairs for points in arrays {x,y,z} void MGL_EXPORT mgl_step_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_step_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw stairs for points in arrays {x,y} void MGL_EXPORT mgl_step_xy(HMGL graph, HCDT x, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_step_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw stairs for points in arrays {x,y} with x in x-axis range void MGL_EXPORT mgl_step(HMGL graph, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_step_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw vertical bars from points {x,y,z} to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_bars_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_bars_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw vertical bars from points {x,y} to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_bars_xy(HMGL graph, HCDT x, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_bars_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw vertical bars from points {x,y} with x in x-axis range to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_bars(HMGL graph, HCDT y, const char *pen, const char *opt); void MGL_EXPORT mgl_bars_(uintptr_t *graph, uintptr_t *y, const char *pen, const char *opt,int,int); /// Draw horizontal bars from points {v,y} to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_barh_yx(HMGL graph, HCDT y, HCDT v, const char *pen, const char *opt); void MGL_EXPORT mgl_barh_yx_(uintptr_t *graph, uintptr_t *y, uintptr_t *v, const char *pen, const char *opt,int,int); /// Draw horizontal bars from points {v,y} with y in y-axis range to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_barh(HMGL graph, HCDT v, const char *pen, const char *opt); void MGL_EXPORT mgl_barh_(uintptr_t *graph, uintptr_t *v, const char *pen, const char *opt,int,int); /// Draw Open-High-Low-Close (OHLC) diagram /** Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */ void MGL_EXPORT mgl_ohlc_x(HMGL graph, HCDT x, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt); void MGL_EXPORT mgl_ohlc_x_(uintptr_t *graph, uintptr_t *x, uintptr_t *open, uintptr_t *high, uintptr_t *low, uintptr_t *close, const char *pen, const char *opt,int,int); /// Draw Open-High-Low-Close (OHLC) diagram with x in x-axis range /** Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */ void MGL_EXPORT mgl_ohlc(HMGL graph, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt); void MGL_EXPORT mgl_ohlc_(uintptr_t *graph, uintptr_t *open, uintptr_t *high, uintptr_t *low, uintptr_t *close, const char *pen, const char *opt,int,int); /// Draw chart for data a /** Space denote transparent color. Style '#' draw black borders. */ void MGL_EXPORT mgl_chart(HMGL graph, HCDT a, const char *col, const char *opt); void MGL_EXPORT mgl_chart_(uintptr_t *graph, uintptr_t *a, const char *col, const char *opt,int,int); /// Draw error boxes {ex,ey} at points {x,y} /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/ void MGL_EXPORT mgl_error_exy(HMGL graph, HCDT x, HCDT y, HCDT ex, HCDT ey, const char *pen, const char *opt); void MGL_EXPORT mgl_error_exy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *ex, uintptr_t *ey, const char *pen, const char *opt,int,int); /// Draw error boxes {ey} at points {x,y} /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/ void MGL_EXPORT mgl_error_xy(HMGL graph, HCDT x, HCDT y, HCDT ey, const char *pen, const char *opt); void MGL_EXPORT mgl_error_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int,int); /// Draw error boxes {ey} at points {x,y} with x in x-axis range /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/ void MGL_EXPORT mgl_error(HMGL graph, HCDT y, HCDT ey, const char *pen, const char *opt); void MGL_EXPORT mgl_error_(uintptr_t *graph, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int,int); /// Draw marks with size r at points {x,y,z} void MGL_EXPORT mgl_mark_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt); void MGL_EXPORT mgl_mark_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw marks with size r at points {x,y} void MGL_EXPORT mgl_mark_xy(HMGL graph, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt); void MGL_EXPORT mgl_mark_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw marks with size r at points {x,y} with x in x-axis range void MGL_EXPORT mgl_mark_y(HMGL graph, HCDT y, HCDT r, const char *pen, const char *opt); void MGL_EXPORT mgl_mark_y_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw Poincare map at condition s==0 for curve {x,y,z} void MGL_EXPORT mgl_pmap_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT s, const char *pen, const char *opt); void MGL_EXPORT mgl_pmap_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw Poincare map at condition s==0 for curve {x,y} void MGL_EXPORT mgl_pmap_xy(HMGL graph, HCDT x, HCDT y, HCDT s, const char *pen, const char *opt); void MGL_EXPORT mgl_pmap_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw Poincare map at condition s==0 for curve {x,y} with x in x-axis range void MGL_EXPORT mgl_pmap(HMGL graph, HCDT y, HCDT s, const char *pen, const char *opt); void MGL_EXPORT mgl_pmap_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw tube with variable radius r around curve {x,y,z} void MGL_EXPORT mgl_tube_xyzr(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt); void MGL_EXPORT mgl_tube_xyzr_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw tube with variable radius r around curve {x,y} void MGL_EXPORT mgl_tube_xyr(HMGL graph, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt); void MGL_EXPORT mgl_tube_xyr_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw tube with variable radius r around curve {x,y} with x in x-axis range void MGL_EXPORT mgl_tube_r(HMGL graph, HCDT y, HCDT r, const char *pen, const char *opt); void MGL_EXPORT mgl_tube_r_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int); /// Draw tube with constant radius r around curve {x,y,z} void MGL_EXPORT mgl_tube_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, double r, const char *pen, const char *opt); void MGL_EXPORT mgl_tube_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, mreal *r, const char *pen, const char *opt,int,int); /// Draw tube with constant radius r around curve {x,y} void MGL_EXPORT mgl_tube_xy(HMGL graph, HCDT x, HCDT y, double r, const char *penl, const char *opt); void MGL_EXPORT mgl_tube_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, mreal *r, const char *pen, const char *opt,int,int); /// Draw tube with constant radius r around curve {x,y} with x in x-axis range void MGL_EXPORT mgl_tube(HMGL graph, HCDT y, double r, const char *pen, const char *opt); void MGL_EXPORT mgl_tube_(uintptr_t *graph, uintptr_t *y, mreal *r, const char *pen, const char *opt,int,int); /// Draw candle plot for data specified parametrically /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt); void MGL_EXPORT mgl_candle_xyv_(uintptr_t *gr, uintptr_t *x, uintptr_t *v1, uintptr_t *v2, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int,int); /// Draw candle plot /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ void MGL_EXPORT mgl_candle_yv(HMGL gr, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt); void MGL_EXPORT mgl_candle_yv_(uintptr_t *gr, uintptr_t *v1, uintptr_t *v2, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int,int); /// Draw candle plot with v1=v[i], v2=v[i+1] /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ void MGL_EXPORT mgl_candle(HMGL gr, HCDT v, HCDT y1, HCDT y2, const char *pen, const char *opt); void MGL_EXPORT mgl_candle_(uintptr_t *gr, uintptr_t *y, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int,int); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/wnd.h���������������������������������������������������������������������0000644�0001750�0001750�00000020456�13513030041�016401� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * wnd.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_WND_H_ #define _MGL_WND_H_ #include "mgl2/mgl.h" #include "mgl2/wnd_cf.h" //----------------------------------------------------------------------------- MGL_EXPORT void *mgl_draw_calc(void *p); void MGL_EXPORT mgl_parse_comments(const char *text, double &a1, double &a2, double &da, std::vector &anim, std::string &dlg_ids, std::vector &dlg_par); void MGL_EXPORT mgl_parse_comments(const wchar_t *text, double &a1, double &a2, double &da, std::vector &anim, std::string &dlg_ids, std::vector &dlg_par); void MGL_EXPORT mgl_parse_animation(const char *text, std::vector &anim); void MGL_EXPORT mgl_parse_animation(const wchar_t *text, std::vector &anim); //----------------------------------------------------------------------------- /// Class for drawing in windows (like, mglCanvasFL, mglCanvasQT and so on) /// Make inherited class and redefine Draw() function if you don't want to use function pointers. class MGL_EXPORT mglDraw { public: virtual int Draw(mglGraph *)=0; ///< Function for drawing virtual void Reload(){} ///< Function for reloading data virtual void Param(char id, const char *val){} ///< Function for setting parameter virtual void Click() {} ///< Callback function on mouse click #if MGL_HAVE_PTHR_WIDGET mglDraw() { running=false; pthread_mutex_init(&mutex,NULL); thr=0; } virtual ~mglDraw() { pthread_mutex_destroy(&mutex); } virtual void Calc() {} ///< Function for calculations inline void Run() ///< Run/resume calculation in other thread { if(!running) { pthread_mutex_trylock(&mutex); pthread_mutex_unlock(&mutex); pthread_create(&thr,0,mgl_draw_calc,this); pthread_detach(thr); running = true; } } inline void Cancel() ///< Cancel thread with calculations { pthread_cancel(thr); running = false; } inline void Pause() ///< Pause calculation { pthread_mutex_lock(&mutex); } inline void Continue() ///< Continue calculation { pthread_mutex_trylock(&mutex); pthread_mutex_unlock(&mutex); } inline void Check() ///< Check if calculation can be continued (should be called inside Calc() ) { pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex); } //protected: pthread_t thr; bool running; pthread_mutex_t mutex; #else mglDraw() {} virtual ~mglDraw() {} #endif }; //----------------------------------------------------------------------------- extern "C" { int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p); // NOTE: MGL_EXPORT mgl_draw_class() and MGL_EXPORT mgl_draw_load() use mglWindow* only. Don't use it with inherited classes int MGL_EXPORT mgl_draw_class(HMGL gr, void *p); void MGL_EXPORT mgl_click_class(void *p); void MGL_EXPORT mgl_reload_class(void *p); void MGL_EXPORT mgl_prop_class(char id, const char *val, void *p); void MGL_EXPORT mgl_prop_func(char id, const char *val, void *p); extern MGL_EXPORT const char *mgl_hints[]; } //----------------------------------------------------------------------------- /// Abstract class for windows displaying graphics class MGL_EXPORT mglWnd : public mglGraph { mglWnd(const mglWnd &) {} // copying is not allowed const mglWnd &operator=(const mglWnd &t) { return t; } public: mglWnd() : mglGraph(-1) {} virtual ~mglWnd() { mgl_use_graph(gr,-255); } virtual int Run()=0; ///< Run main loop for event handling inline void *Window() ///< Return pointer to widget (Fl_Window* or QMainWindow*) used for plotting { return mgl_wnd_window(gr); } inline void *Widget() ///< Return pointer to widget (Fl_MGLView* or QMathGL*) used for plotting { return mgl_wnd_widget(gr); } inline void WndSize(int w, int h) ///< Resize window { mgl_wnd_size(gr,w,h); } inline void WndMove(int x, int y) ///< Move window { mgl_wnd_move(gr,x,y); } inline void ToggleAlpha() ///< Switch on/off transparency (do not overwrite user settings) { mgl_wnd_toggle_alpha(gr); } inline void ToggleLight() ///< Switch on/off lighting (do not overwrite user settings) { mgl_wnd_toggle_light(gr); } inline void ToggleZoom() ///< Switch on/off zooming by mouse { mgl_wnd_toggle_zoom(gr); } inline void ToggleRotate() ///< Switch on/off rotation by mouse { mgl_wnd_toggle_rotate(gr); } inline void ToggleNo() ///< Switch off all zooming and rotation { mgl_wnd_toggle_no(gr); } inline void Update() ///< Update picture by calling user drawing function { mgl_wnd_update(gr); } inline void ReLoad() ///< Reload user data and update picture { mgl_wnd_reload(gr); } inline void Adjust() ///< Adjust size of bitmap to window size { mgl_wnd_adjust(gr); } inline void NextFrame() ///< Show next frame (if one) { mgl_wnd_next_frame(gr); } inline void PrevFrame() ///< Show previous frame (if one) { mgl_wnd_prev_frame(gr); } inline void Animation() ///< Run slideshow (animation) of frames { mgl_wnd_animation(gr); } inline void SetClickFunc(void (*func)(void *p)) ///< Callback function for mouse click { mgl_set_click_func(gr,func); } /// Set callback function for properties setup void SetPropFunc(void (*prop)(char id, const char *val, void *p), void *par=NULL) { mgl_wnd_set_prop(gr,prop,par); } /// Make custom dialog for parameters ids of element properties defined by args inline void MakeDialog(const char *ids, char const * const *args, const char *title) { mgl_wnd_make_dialog(gr, ids, args, title); } inline void MakeDialog(const std::string &ids, const std::vector &args, const char *title="") { if(args.size()>0) { std::vector buf; buf.reserve(args.size()); for(size_t i=0;imutex)); #endif mgl_set_click_func(gr, mgl_click_class); } #if MGL_HAVE_PTHR_WIDGET /// Mutex for lock/unlock by widget inline void SetMutex(pthread_mutex_t *mutex) { mgl_wnd_set_mutex(gr, mutex); } #endif inline void SetDelay(double dt) ///< Set delay for animation in seconds { mgl_wnd_set_delay(gr, dt); } inline double GetDelay() ///< Get delay for animation in seconds { return mgl_wnd_get_delay(gr); } inline void Setup(bool clf_upd=true, bool showpos=false) { mgl_setup_window(gr, clf_upd, showpos); } inline mglPoint LastMousePos() ///< Last mouse position { mreal x,y,z; mgl_get_last_mouse_pos(gr,&x,&y,&z); return mglPoint(x,y,z); } }; //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/wx.h����������������������������������������������������������������������0000644�0001750�0001750�00000014744�13513030041�016252� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * wx.h.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MGL_WX_H #define MGL_WX_H //----------------------------------------------------------------------------- #include #include #include #include #include class mglCanvas; //----------------------------------------------------------------------------- /// Convert MathGL image to wxBitmap wxBitmap MGL_EXPORT ConvertFromGraph(HMGL gr); //----------------------------------------------------------------------------- /// Class is Wx widget which display MathGL graphics class MGL_EXPORT wxMathGL : public wxWindow { public: wxString appName; ///< Application name for message boxes bool AutoResize; ///< Allow auto resizing (default is false) wxMathGL(wxWindow *parent, wxWindowID id=-1, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=0, const wxString& name=wxPanelNameStr); virtual ~wxMathGL(); double GetRatio(); void SetPopup(wxMenu *p) { popup = p; }; ///< Set popup menu pointer void SetSize(int w, int h); ///< Set window/picture sizes void SetGraph(HMGL gr); ///< Set grapher object inline void SetGraph(mglGraph *GR) { SetGraph(GR->Self()); } inline HMGL GetGraph() { return (HMGL)gr; } /// Set drawing functions and its parameter inline void SetDraw(int (*func)(mglBase *gr, void *par), void *par=0) { draw_func = func; draw_par = par; } inline void SetDraw(mglDraw *dr) { draw_cl = dr; } inline void SetDraw(int (*draw)(mglGraph *gr)) { SetDraw(draw?mgl_draw_graph:0,(void*)draw); } inline void ZoomRegion(mreal xx1,mreal xx2,mreal yy1, mreal yy2) { x1=xx1; y1=yy1; x2=xx2; y2=yy2; } int GetPer() {return per;}; ///< Get perspective value int GetPhi() {return phi;}; ///< Get Phi-angle value int GetTet() {return tet;}; ///< Get Theta-angle value bool GetAlpha() {return alpha;}; ///< Get transparency state bool GetLight() {return light;}; ///< Get lightning state bool GetZoom() {return zoom;}; ///< Get mouse zooming state bool GetRotate() {return rotate;}; ///< Get mouse rotation state void Repaint(); void Update(); ///< Update picture void Copy(); ///< copy graphics to clipboard void Print(); ///< Print plot // void Stop(); ///< Stop execution void SetPer(int p); ///< Set perspective value void SetPhi(int p); ///< Set Phi-angle value void SetTet(int t); ///< Set Theta-angle value void SetAlpha(bool a); ///< Switch on/off transparency void SetLight(bool l); ///< Switch on/off lightning void SetZoom(bool z); ///< Switch on/off mouse zooming void SetRotate(bool r); ///< Switch on/off mouse rotation void ZoomIn(); ///< Zoom in graphics void ZoomOut(); ///< Zoom out graphics void Restore(); ///< Restore zoom and rotation to default values // void Reload(); ///< Reload data and execute script void ShiftLeft(); ///< Shift graphics to left direction void ShiftRight(); ///< Shift graphics to right direction void ShiftUp(); ///< Shift graphics to up direction void ShiftDown(); ///< Shift graphics to down direction void ExportPNG(wxString fname=L""); ///< export to PNG file void ExportPNGs(wxString fname=L""); ///< export to PNG file (no transparency) void ExportJPG(wxString fname=L""); ///< export to JPEG file void ExportBPS(wxString fname=L""); ///< export to bitmap EPS file void ExportEPS(wxString fname=L""); ///< export to vector EPS file void ExportSVG(wxString fname=L""); ///< export to SVG file void Adjust(); ///< Adjust plot size to fill entire window void NextSlide(); ///< Show next slide void PrevSlide(); ///< Show previous slide void Animation(bool st=true); ///< Start animation void About(); ///< Show about information protected: void OnPaint(wxPaintEvent& event); void OnSize(wxSizeEvent& event); void OnNextSlide(wxTimerEvent& evt); ///< Show next slide void OnMouseLeftDown(wxMouseEvent &ev); void OnMouseDown(wxMouseEvent &ev); void OnMouseLeftUp(wxMouseEvent &ev); void OnMouseRightUp(wxMouseEvent &ev); void OnMouseMove(wxMouseEvent &ev); // void MousePressEvent(QMouseEvent *); // void MouseReleaseEvent(QMouseEvent *); // void MouseMoveEvent(QMouseEvent *); mglCanvas *gr; ///< pointer to grapher void *draw_par; ///< Parameters for drawing function mglCanvasWnd::DrawFunc. /// Drawing function for window procedure. It should return the number of frames. int (*draw_func)(mglBase *gr, void *par); mglDraw *draw_cl; wxString MousePos; ///< Last mouse position wxBitmap pic; ///< Pixmap for drawing (changed by update) double tet, phi; ///< Rotation angles double per; ///< Value of perspective ( must be in [0,1) ) bool alpha; ///< Transparency state bool light; ///< Lightning state bool zoom; ///< Mouse zoom state bool rotate; ///< Mouse rotation state mreal x1,x2,y1,y2; ///< Zoom in region wxMenu *popup; ///< Pointer to pop-up menu wxTimer *timer; ///< Timer for animation DECLARE_EVENT_TABLE() private: int x0, y0, xe, ye; ///< Temporary variables for mouse }; //----------------------------------------------------------------------------- #endif ����������������������������mathgl-2.4.4/include/mgl2/mgl_cf.h������������������������������������������������������������������0000644�0001750�0001750�00000005025�13513030041�017033� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * mgl_cf.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_CF_H_ #define _MGL_CF_H_ //----------------------------------------------------------------------------- #ifdef __cplusplus #include #include #endif //----------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include //----------------------------------------------------------------------------- #if MGL_HAVE_OPENGL #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------- HMGL MGL_EXPORT mgl_create_graph_gl(); uintptr_t MGL_EXPORT mgl_create_graph_gl_(); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif #endif //----------------------------------------------------------------------------- #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/Fl_MathGL.h���������������������������������������������������������������0000644�0001750�0001750�00000025354�13513030041�017350� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Fl_MathGL.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_FL_MATHGL_H_ #define _MGL_FL_MATHGL_H_ #ifdef __MWERKS__ # define FL_DLL #endif #include #include #include #include #include #include #include #include class mglCanvas; //----------------------------------------------------------------------------- /// Class is FLTK widget which display MathGL graphics class MGL_EXPORT Fl_MathGL : public Fl_Widget { friend class Fl_MGLView; public: Fl_Valuator *tet_val; ///< pointer to external tet-angle validator Fl_Valuator *phi_val; ///< pointer to external phi-angle validator mglCanvas *gr; ///< Built-in mglCanvas instance (mglCanvasFLTK is used by default) std::string prim; ///< manual primitives bool use_pthr; ///< use pthread for update plot Fl_MathGL(int x, int y, int w, int h, const char *label=0); virtual ~Fl_MathGL(); /// Set drawing functions and its parameter inline void set_draw(int (*func)(mglBase *gr, void *par), void *par) { if(draw_cl) delete draw_cl; draw_cl=0; draw_func=func; draw_par=par; } /// Set drawing functions pointed on mglGraph inline void set_draw(int (*dr)(mglGraph *gr)) { set_draw(dr?mgl_draw_graph:0,(void*)dr); } /// Set drawing based on instance of mglDraw class inline void set_draw(mglDraw *dr) { if(draw_cl) delete draw_cl; draw_cl=dr; draw_func=0; } /// Set function for parameters inline void set_prop(void (*func)(char id, const char *val, void *par), void *par) { prop_func=func; prop_par=par; } /// Refresh image (without executing update) void refresh(); /// Update (redraw) plot virtual void update(); /// Set angles for additional plot rotation inline void set_angle(double t, double p){ tet = t; phi = p; } /// Set bitwise flags for general state (1-Alpha, 2-Light) inline void set_flag(int f) { flag = f; } /// Set flags for handling mouse void set_state(bool z, bool r, bool g=false) { zoom = z; rotate = r; grid = g; } /// Set zoom in/out region inline void set_zoom(double X1, double Y1, double X2, double Y2) { x1 = X1; x2 = X2; y1 = Y1; y2 = Y2; update(); } /// Get zoom region inline void get_zoom(double *X1, double *Y1, double *X2, double *Y2) { *X1 = x1; *X2 = x2; *Y1 = y1; *Y2 = y2; } /// Set popup menu pointer inline void set_popup(const Fl_Menu_Item *pmenu, Fl_Widget *wdg, void *v) { popup = pmenu; wpar = wdg; vpar = v; } /// Set grapher object instead of built-in one. /// NOTE: Fl_MathGL will automatically delete this object void set_graph(HMGL gr); /// Set grapher object instead of built-in one. /// NOTE: Fl_MathGL will automatically delete this object inline void set_graph(mglGraph *Gr) { set_graph(Gr->Self()); } /// Get pointer to grapher inline HMGL get_graph() { return (HMGL)gr; } /// Get mglDraw pointer or NULL inline mglDraw *get_class() { mglDraw *d=0; if(draw_func==mgl_draw_class) d = (mglDraw*)draw_par; if(draw_cl) d = draw_cl; return d; } inline void set_param(char id, const char *val) { mglDraw *d=get_class(); if(d) d->Param(id,val); else prop_func(id,val,prop_par); } /// Show window with warnings after script parsing inline void set_show_warn(bool s) { show_warn=s; } /// Ask to stop of script parsing void stop(bool stop=true); /// Enable/disable key handling as in mglview (default is false) inline void set_handle_key(bool val) { handle_keys=true; } /// Get id of last clicked object inline int get_last_id() { return last_id; } void draw_plot(); ///< Single thread drawing itself /// Check if script is parsing now or not inline bool running() { return run; } protected: void *draw_par; ///< Parameters for drawing function draw_func(). /// Drawing function for window procedure. It should return the number of frames. int (*draw_func)(mglBase *gr, void *par); void *prop_par; ///< Parameters for prop_func(). /// Function for setting properties. void (*prop_func)(char id, const char *val, void *par); mglDraw *draw_cl; int last_id; ///< last selected object id const Fl_Menu_Item *popup; ///< pointer to popup menu items Fl_Widget *wpar; ///< widget for popup menu void *vpar; ///< parameter for popup menu double tet,phi; ///< rotation angles bool rotate; ///< flag for handle mouse bool zoom; ///< flag for zoom by mouse bool grid; ///< flag to draw grid and edit prim bool show_warn; ///< show window with warnings bool handle_keys; double x1,x2,y1,y2; ///< zoom region int flag; ///< bitwise flag for general state (1-Alpha, 2-Light) int x0,y0,xe,ye; ///< mouse position char mouse_pos[128]; bool run; ///< flag that drawing in progress const unsigned char *img; ///< image for drawing #if (MGL_HAVE_PTHREAD|MGL_HAVE_PTHR_WIDGET) pthread_t thr; ///< main thread for drawing #endif virtual void draw(); ///< quick drawing function int handle(int code); ///< handle mouse events void resize(int x, int y, int w, int h); ///< resize control }; //----------------------------------------------------------------------------- class MGL_EXPORT Fl_MGLView : public Fl_Window { public: Fl_MathGL *FMGL; ///< Control which draw graphics Fl_Scroll *scroll; Fl_Menu_Bar *menu; void *par; ///< Parameter for handling animation void (*next)(void*); ///< Callback function for next frame void (*prev)(void*); ///< Callback function for prev frame mreal (*delay)(void*); ///< Callback function for delay void (*reload)(void*); ///< Callback function for reloading /// Toggle transparency (alpha) button void toggle_alpha() { toggle(alpha, alpha_bt, _("Graphics/Alpha")); } /// Toggle lighting button void toggle_light() { toggle(light, light_bt, _("Graphics/Light")); } /// Toggle slideshow button void toggle_sshow() { toggle(sshow, anim_bt, _("Graphics/Animation/Slideshow")); } /// Toggle grid drawing button void toggle_grid() { toggle(grid, grid_bt, _("Graphics/Grid")); } /// Toggle mouse zoom button void toggle_zoom() { toggle(zoom, zoom_bt); } /// Toggle mouse rotate button void toggle_rotate(){ toggle(rotate, rotate_bt); } /// Switch off zoom button void setoff_zoom() { setoff(zoom, zoom_bt); } /// Switch off rotate button void setoff_rotate(){ setoff(rotate, rotate_bt); } /// Check if slideshow running bool is_sshow() { return sshow; } /// Toggle pause calculation button void toggle_pause() { toggle(pauseC, pause_bt, _("Graphics/Pause calc")); exec_pause(); } /// Adjust image sizes to the current widget sizes void adjust() { mgl_set_size(FMGL->get_graph(),scroll->w(),scroll->h()); FMGL->size(scroll->w(),scroll->h()); update(); } /// Get current grapher HMGL get_graph() { return FMGL->get_graph(); } /// Update picture by calling user drawing function void update(); /// Create and show custom dialog void dialog(const char *ids, char const * const *args, const char *title="") { if(!ids || *ids==0) return; dlg_window(title); for(int i=0;ids[i];i++) add_widget(ids[i], args[i]); dlg_finish(); dlg_wnd->show(); } void dialog(const std::string &ids, const std::vector &args, const char *title="") { std::vector buf; buf.reserve(args.size()); for(size_t i=0;ishow(); } void dlg_window(const char *title=""); ///< Create/label dialog window void add_widget(char id, const char *args); ///< Add widget to dialog void dlg_show() { dlg_finish(); dlg_wnd->show(); } ///< Show window void dlg_hide() { dlg_wnd->hide(); } ///< Close window void get_values(); ///< Get all values from dialog window void set_progress(int value, int maximal); ///< Set progress Fl_MGLView(int x, int y, int w, int h, const char *label=0); virtual ~Fl_MGLView(); protected: Fl_Button *alpha_bt, *light_bt, *rotate_bt, *anim_bt, *zoom_bt, *grid_bt, *pause_bt; Fl_Progress *progress; int grid, alpha, light; ///< Current states of wire, alpha, light switches (toggle buttons) int sshow, rotate, zoom;///< Current states of slideshow, rotate, zoom switches (toggle buttons) int pauseC; ///< Current state of pause for calculations void toggle(int &val, Fl_Button *b, const char *txt=NULL); void setoff(int &val, Fl_Button *b, const char *txt=NULL); void exec_pause(); Fl_Double_Window *dlg_wnd; ///< Dialog window itself std::vector strs; ///< Strings for widget labels bool dlg_done; ///< Dialog is created int dlg_ind; ///< Current index of widget std::vector dlg_kind; ///< Kind of elements std::vector dlg_wdgt; ///< List of widgets std::vector dlg_ids; ///< Id of elements std::vector dlg_vals; ///< resulting strings void dlg_finish(); ///< Finish dialog window creation }; //----------------------------------------------------------------------------- void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w); MGL_EXPORT const char *mgl_file_chooser(const char *mess, const char *filter="", bool save=false); MGL_EXPORT const char *mgl_dir_chooser(const char *mess, const char *path); //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/eval.h��������������������������������������������������������������������0000644�0001750�0001750�00000007163�13513030041�016540� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * eval.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_EVAL_H_ #define _MGL_EVAL_H_ //----------------------------------------------------------------------------- #include "mgl2/abstract.h" /// types of errors #define MGL_ERR_LOG 1 #define MGL_ERR_ARC 2 #define MGL_ERR_SQRT 3 class mglData; //----------------------------------------------------------------------------- /// Class for evaluating formula specified by the string class MGL_EXPORT mglFormula { public: /// Evaluates the formula for 'x','r'=\a x, 'y','n'=\a y, 'z','t'=\a z, 'u'=\a u mreal Calc(mreal x,mreal y=0,mreal z=0,mreal u=0) const MGL_FUNC_PURE; /// Evaluates the formula for 'x, y, z, u, v, w' mreal Calc(mreal x,mreal y,mreal z,mreal u,mreal v,mreal w) const MGL_FUNC_PURE; /// Evaluates the formula for variables var mreal Calc(const mreal var[MGL_VS]) const MGL_FUNC_PURE; /// Evaluates the formula for 'x','r'=\a x, 'y','n'=\a y, 'z','t'=\a z, 'u'=\a u mreal CalcD(char diff, mreal x,mreal y=0,mreal z=0,mreal u=0) const MGL_FUNC_PURE; /// Evaluates the formula for 'x, y, z, u, v, w' mreal CalcD(char diff, mreal x,mreal y,mreal z,mreal u,mreal v,mreal w) const MGL_FUNC_PURE; /// Evaluates the derivates of the formula for variables var respect to variable diff mreal CalcD(const mreal var[MGL_VS], char diff) const MGL_FUNC_PURE; /// Return error code inline int GetError() const { return Error; } /// Parse the formula str and create formula-tree mglFormula(const char *str); /// Set data for the spline interpolation mglFormula(HCDT d, mreal x1=0, mreal x2=1, mreal y1=0, mreal y2=1, mreal z1=0, mreal z2=1) : dat(d),dx1(x1),dx2(x2),dy1(y1),dy2(y2),dz1(z1),dz2(z2),tmp(NULL) {}; /// Clean up formula-tree ~mglFormula(); protected: mreal CalcIn(const mreal *a1) const MGL_FUNC_PURE; mreal CalcDIn(int id, const mreal *a1) const MGL_FUNC_PURE; mglFormula *Left,*Right; // first and second argument of the function int Kod; // the function ID mreal Res; // the number or the variable ID HCDT dat; // data file for the interpolation mreal dx1,dx2,dy1,dy2,dz1,dz2; // ranges of data files static int Error; private: mglData *tmp; }; //----------------------------------------------------------------------------- #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/surf.h��������������������������������������������������������������������0000644�0001750�0001750�00000031364�13513030041�016570� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * surf.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_SURF_H_ #define _MGL_SURF_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Draw surface by formula with x,y in axis range /** Option "value" set initial number of points. */ void MGL_EXPORT mgl_fsurf(HMGL graph, const char *fz, const char *stl, const char *opt); void MGL_EXPORT mgl_fsurf_(uintptr_t *graph, const char *fz, const char *stl, const char *opt,int,int,int); /// Draw surface by formulas parametrically depended on u,v in range [0,1] /** Option "value" set initial number of points. */ void MGL_EXPORT mgl_fsurf_xyz(HMGL graph, const char *fx, const char *fy, const char *fz, const char *stl, const char *opt); void MGL_EXPORT mgl_fsurf_xyz_(uintptr_t *graph, const char *fx, const char *fy, const char *fz, const char *stl, const char *opt, int, int, int, int, int); /// Draw grid lines for density plot of 2d data specified parametrically void MGL_EXPORT mgl_grid_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *stl, const char *opt); void MGL_EXPORT mgl_grid_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *stl, const char *opt,int,int); /// Draw grid lines for density plot of 2d data void MGL_EXPORT mgl_grid(HMGL graph, HCDT a,const char *stl, const char *opt); void MGL_EXPORT mgl_grid_(uintptr_t *graph, uintptr_t *a,const char *stl, const char *opt,int,int); /// Draw mesh lines for 2d data specified parametrically void MGL_EXPORT mgl_mesh_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_mesh_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw mesh lines for 2d data void MGL_EXPORT mgl_mesh(HMGL graph, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_mesh_(uintptr_t *graph, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw waterfall plot for 2d data specified parametrically /** Style 'x' draw lines in x-direction. */ void MGL_EXPORT mgl_fall_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_fall_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw waterfall plot for 2d data /** Style 'x' draw lines in x-direction. */ void MGL_EXPORT mgl_fall(HMGL graph, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_fall_(uintptr_t *graph, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw belts for 2d data specified parametrically /** Style 'x' draw belts in x-direction. */ void MGL_EXPORT mgl_belt_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_belt_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw belts for 2d data /** Style 'x' draw belts in x-direction. */ void MGL_EXPORT mgl_belt(HMGL graph, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_belt_(uintptr_t *graph, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw belts for 2d data specified parametrically with color proportional to c /** Style 'x' draw belts in x-direction. */ void MGL_EXPORT mgl_beltc_xy(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_beltc_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw belts for 2d data with color proportional to c /** Style 'x' draw belts in x-direction. */ void MGL_EXPORT mgl_beltc(HMGL graph, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_beltc_(uintptr_t *graph, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw surface for 2d data specified parametrically with color proportional to z /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surf_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_surf_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw surface for 2d data with color proportional to z /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surf(HMGL graph, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_surf_(uintptr_t *graph, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw density plot for 2d data specified parametrically /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_dens_xy(HMGL graph, HCDT x, HCDT y, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_dens_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw density plot for 2d data /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_dens(HMGL graph, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_dens_(uintptr_t *graph, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw vertical boxes for 2d data specified parametrically /** Style ‘#’ draw filled boxes. */ void MGL_EXPORT mgl_boxs_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_boxs_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw vertical boxes for 2d data /** Style ‘#’ draw filled boxes. */ void MGL_EXPORT mgl_boxs(HMGL graph, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_boxs_(uintptr_t *graph, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw vertical tiles with manual colors c for 2d data specified parametrically void MGL_EXPORT mgl_tile_xyc(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_tile_xyc_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw vertical tiles for 2d data specified parametrically void MGL_EXPORT mgl_tile_xy(HMGL graph, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_tile_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw vertical tiles for 2d data void MGL_EXPORT mgl_tile(HMGL graph, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_tile_(uintptr_t *graph, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw vertical tiles with variable size r and manual colors c for 2d data specified parametrically void MGL_EXPORT mgl_tiles_xyc(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_tiles_xyc_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw vertical tiles with variable size r for 2d data specified parametrically void MGL_EXPORT mgl_tiles_xy(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *sch, const char *opt); void MGL_EXPORT mgl_tiles_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *sch, const char *opt,int,int); /// Draw vertical tiles with variable size r for 2d data void MGL_EXPORT mgl_tiles(HMGL graph, HCDT z, HCDT r, const char *sch, const char *opt); void MGL_EXPORT mgl_tiles_(uintptr_t *graph, uintptr_t *z, uintptr_t *r, const char *sch, const char *opt,int,int); /// Draw surface for 2d data specified parametrically with color proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surfc_xy(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_surfc_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw surface for 2d data with color proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surfc(HMGL graph, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_surfc_(uintptr_t *graph, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw surface for 2d data specified parametrically with alpha proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surfa_xy(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_surfa_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw surface for 2d data with alpha proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surfa(HMGL graph, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_surfa_(uintptr_t *graph, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw surface for 2d data specified parametrically with color proportional to c and alpha proportional to a /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surfca_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_surfca_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw surface for 2d data with color proportional to c and alpha proportional to a /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surfca(HMGL gr, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_surfca_(uintptr_t *graph, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw density plot for spectra-gramm specified parametrically /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_stfa_xy(HMGL graph, HCDT x, HCDT y, HCDT re, HCDT im, int dn, const char *sch, const char *opt); void MGL_EXPORT mgl_stfa_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *re, uintptr_t *im, int *dn, const char *sch, const char *opt,int, int); /// Draw density plot for spectra-gramm /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_stfa(HMGL graph, HCDT re, HCDT im, int dn, const char *sch, const char *opt); void MGL_EXPORT mgl_stfa_(uintptr_t *graph, uintptr_t *re, uintptr_t *im, int *dn, const char *sch, const char *opt,int, int); /// Color map of matrix a to matrix b, both matrix can parametrically depend on coordinates /** Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_map_xy(HMGL graph, HCDT x, HCDT y, HCDT a, HCDT b, const char *sch, const char *opt); void MGL_EXPORT mgl_map_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int,int); /// Color map of matrix a to matrix b /** Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_map(HMGL graph, HCDT a, HCDT b, const char *sch, const char *opt); void MGL_EXPORT mgl_map_(uintptr_t *graph, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int,int); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/canvas.h������������������������������������������������������������������0000644�0001750�0001750�00000066121�13513030041�017063� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * canvas.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MGL_CANVAS_H #define MGL_CANVAS_H #include "mgl2/base.h" //----------------------------------------------------------------------------- struct GifFileType; //----------------------------------------------------------------------------- /// Structure for drawing axis and ticks struct MGL_EXPORT mglAxis { mglAxis() : dv(0),ds(0),d(0),ns(0), v0(0),v1(0),v2(0),o(NAN), f(0), ch(0), pos('t'),sh(0),inv(false),angl(NAN) {} mglAxis(const mglAxis &aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns), t(aa.t),fact(aa.fact),stl(aa.stl), dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt), ch(aa.ch), pos(aa.pos),sh(aa.sh),inv(aa.inv),angl(aa.angl) {} #if MGL_HAVE_RVAL mglAxis(mglAxis &&aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns), t(aa.t),fact(aa.fact),stl(aa.stl), dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt), ch(aa.ch), pos(aa.pos),sh(aa.sh),inv(aa.inv),angl(aa.angl) {} #endif const mglAxis &operator=(const mglAxis &aa) { dv=aa.dv; ds=aa.ds; d=aa.d; ns=aa.ns; t=aa.t; fact=aa.fact; stl=aa.stl; dir=aa.dir; a=aa.a; b=aa.b; org=aa.org; v0=aa.v0; v1=aa.v1; v2=aa.v2; o=aa.o; f=aa.f; txt=aa.txt; ch=aa.ch; pos=aa.pos; sh=aa.sh; inv=aa.inv; return aa; } inline void AddLabel(const std::wstring &lbl, mreal v) { if(mgl_isfin(v)) txt.push_back(mglText(L' '+lbl+L' ',v)); } inline void Clear() { dv=ds=d=v0=v1=v2=sh=0; o=NAN; ns=f=0; pos = 't'; inv=false; fact.clear(); stl.clear(); t.clear(); txt.clear(); } mreal dv,ds; ///< Actual step for ticks and subticks. mreal d; ///< Step for axis ticks (if positive) or its number (if negative). int ns; ///< Number of axis subticks. std::wstring t; ///< Tick template (set "" to use default one ("%.2g" in simplest case)) std::wstring fact; ///< Factor which should be placed after number (like L"\pi") std::string stl; ///< Tick styles (default is ""=>"3m") mglPoint dir; ///< Axis direction mglPoint a,b; ///< Directions of over axis mglPoint org; mreal v0; ///< Center of axis cross section mreal v1; ///< Minimal axis range. mreal v2; ///< Maximal axis range. mreal o; ///< Point of starting ticks numbering (if NAN then Org is used). int f; ///< Flag 0x1 - time, 0x2 - manual, 0x4 - fixed dv std::vector txt; ///< Axis labels char ch; ///< Character of axis (like 'x','y','z','c') char pos; ///< Text position ('t' by default, or 'T' for opposite) mreal sh; ///< Extra shift of ticks and axis labels bool inv; ///< Inverse automatic origin position mreal angl; ///< Manual for ticks rotation (if not NAN) }; //----------------------------------------------------------------------------- class mglCanvas; /// Structure for drawing region struct MGL_EXPORT mglDrawReg { mglDrawReg() { memset(this,0,sizeof(mglDrawReg)); } mglDrawReg(const mglDrawReg &aa) : PDef(aa.PDef),angle(aa.angle),ObjId(aa.ObjId),PenWidth(aa.PenWidth),pPos(aa.pPos) ,x1(aa.x1),x2(aa.x2),y1(aa.y1),y2(aa.y2) {} #if MGL_HAVE_RVAL mglDrawReg(mglDrawReg &&aa) : PDef(aa.PDef),angle(aa.angle),ObjId(aa.ObjId),PenWidth(aa.PenWidth),pPos(aa.pPos) ,x1(aa.x1),x2(aa.x2),y1(aa.y1),y2(aa.y2) {} #endif inline void copy(const mglPrim &p) { PDef = p.n3; pPos = p.s; ObjId = p.id; PenWidth=p.w; angle = p.angl; if(p.type==2 || p.type==3) PDef = p.m; } inline const mglDrawReg &operator=(const mglDrawReg &aa) { PDef=aa.PDef; angle=aa.angle; ObjId=aa.ObjId; PenWidth=aa.PenWidth; pPos=aa.pPos; x1=aa.x1; x2=aa.x2; y1=aa.y1; y2=aa.y2; return aa; } union { uint64_t PDef; unsigned char m[8]; }; int angle; ///< mask rotation values in degrees int ObjId; mreal PenWidth, pPos; int x1,x2,y1,y2; void set(mglCanvas *gr, int nx, int ny, int m); }; //----------------------------------------------------------------------------- /// Structure contains everything for drawing struct MGL_EXPORT mglDrawDat { mglDrawDat() {} mglDrawDat(const mglDrawDat &aa) : Pnt(aa.Pnt),Prm(aa.Prm),Sub(aa.Sub),Ptx(aa.Ptx),Glf(aa.Glf),Txt(aa.Txt) {} #if MGL_HAVE_RVAL mglDrawDat(mglDrawDat &&aa) : Pnt(aa.Pnt),Prm(aa.Prm),Sub(aa.Sub),Ptx(aa.Ptx),Glf(aa.Glf),Txt(aa.Txt) {} #endif inline const mglDrawDat&operator=(const mglDrawDat &aa) { Pnt=aa.Pnt; Prm=aa.Prm; Ptx=aa.Ptx; Glf=aa.Glf; Txt=aa.Txt; Sub=aa.Sub; return aa; } mglStack Pnt; ///< Internal points mglStack Prm; ///< Primitives (lines, triangles and so on) -- need for export std::vector Sub; ///< InPlot regions std::vector Ptx; ///< Text labels for mglPrim std::vector Glf; ///< Glyphs data std::vector Txt; ///< Pointer to textures }; #if defined(_MSC_VER) MGL_EXTERN template class MGL_EXPORT std::vector; #endif //----------------------------------------------------------------------------- union mglRGBA { uint32_t c; unsigned char r[4]; }; //----------------------------------------------------------------------------- /// Class contains all functionality for creating different mathematical plots class MGL_EXPORT mglCanvas : public mglBase { friend struct mglPrim; friend struct mglDrawReg; public: using mglBase::Light; mglCanvas(int w=800, int h=600); virtual ~mglCanvas(); /// Set default parameter for plotting void DefaultPlotParam(); /// Set angle of view indepently from mglCanvas::Rotate() virtual void View(mreal tetx,mreal tetz,mreal tety=0); /// Zoom in or zoom out (if Zoom(0, 0, 1, 1)) a part of picture virtual void Zoom(mreal x1, mreal y1, mreal x2, mreal y2); /// Restore image after View() and Zoom() inline void Restore() { Zoom(0,0,1,1); } /// Clear transformation matrix. inline void Identity(bool rel=false) { InPlot(0,1,0,1,rel); } inline void Identity(mglMatrix &M, bool rel=false) { InPlot(M,0,1,0,1,rel); } /// Push transformation matrix into stack void Push(); /// Set PlotFactor inline void SetPlotFactor(mreal val) { if(val<=0) {B.pf=1.55; set(MGL_AUTO_FACTOR);} else {B.pf=val; clr(MGL_AUTO_FACTOR);} } /// Get PlotFactor inline mreal GetPlotFactor() { return B.pf; } /// Pop transformation matrix from stack void Pop(); /// Clear up the frame virtual void Clf(mglColor back=NC); virtual void Clf(const char *col); /// Put further plotting in cell of stick rotated on angles tet, phi void StickPlot(int num, int i, mreal tet, mreal phi); /// Put further plotting in cell of stick sheared on sx, sy void ShearPlot(int num, int i, mreal sx, mreal sy, mreal xd, mreal yd); /// Put further plotting in some region of whole frame surface. inline void InPlot(mreal x1,mreal x2,mreal y1,mreal y2,bool rel=true) { InPlot(B,x1,x2,y1,y2,rel); } void InPlot(mreal x1,mreal x2,mreal y1,mreal y2, const char *style); void InPlot(mglMatrix &M,mreal x1,mreal x2,mreal y1,mreal y2,bool rel=true); /// Add title for current subplot/inplot void Title(const char *title,const char *stl="#",mreal size=-2); void Title(const wchar_t *title,const char *stl="#",mreal size=-2); /// Set aspect ratio for further plotting. void Aspect(mreal Ax,mreal Ay,mreal Az); /// Shear a further plotting. void Shear(mreal Sx,mreal Sy); /// Rotate a further plotting. void Rotate(mreal TetX,mreal TetZ,mreal TetY=0); /// Rotate a further plotting around vector {x,y,z}. void RotateN(mreal Tet,mreal x,mreal y,mreal z); /// Set perspective (in range [0,1)) for plot. Set to zero for switching off. Return the current perspective. void Perspective(mreal a, bool req=true) { if(req) persp = Bp.pf = a; else Bp.pf = persp?persp:fabs(a); } /// Save parameters of current inplot inline void SaveInPlot() { sB=B; sW=inW, sH=inH, sZ=ZMin, sX=inX, sY=inY, sFF=font_factor; } /// Use saved parameters as current inplot inline void LoadInPlot() { B=sB; inW=sW, inH=sH, ZMin=sZ, inX=sX, inY=sY, font_factor=sFF; } /// Set size of frame in pixels. Normally this function is called internaly. virtual void SetSize(int w,int h,bool clf=true); /// Get ratio (mreal width)/(mreal height). mreal GetRatio() const MGL_FUNC_PURE; /// Get bitmap data prepared for saving to file virtual unsigned char **GetRGBLines(long &w, long &h, unsigned char *&f, bool alpha=false); /// Get RGB bitmap of current state image. virtual const unsigned char *GetBits(); /// Get RGBA bitmap of background image. const unsigned char *GetBackground() { return GB; }; /// Get RGBA bitmap of current state image. const unsigned char *GetRGBA() { Finish(); return G4; } /// Get width of the image int GetWidth() const { return Width; } /// Get height of the image int GetHeight() const { return Height; } /// Combine plots from 2 canvases. Result will be saved into this. void Combine(const mglCanvas *gr); /// Set boundary box for export graphics into 2D file formats void SetBBox(int x1=0, int y1=0, int x2=-1, int y2=-1) { BBoxX1=x1; BBoxY1=y1; BBoxX2=x2; BBoxY2=y2; } /// Rasterize current plot and set it as background image void Rasterize(); /// Load image for background from file void LoadBackground(const char *fname, double alpha=1); /// Fill background image by specified color void FillBackground(const mglColor &cc); inline mreal GetDelay() const { return Delay; } inline void SetDelay(mreal d) { Delay=d; } /// Calculate 3D coordinate {x,y,z} for screen point {xs,ys} mglPoint CalcXYZ(int xs, int ys, bool real=false) const MGL_FUNC_PURE; /// Calculate screen point {xs,ys} for 3D coordinate {x,y,z} void CalcScr(mglPoint p, int *xs, int *ys) const; mglPoint CalcScr(mglPoint p) const; /// Set object/subplot id inline void SetObjId(long id) { ObjId = id; } /// Get object id inline int GetObjId(long xs,long ys) const { long i=xs+Width*ys; return (i>=0 && i &leg, int where=3, const char *font="#", const char *opt="") { Legend(leg,(where&1)?1:0,(where&2)?1:0,font,opt); } /// Draw legend strings text at position (x, y) by font with size void Legend(const std::vector &leg, mreal x, mreal y, const char *font="#", const char *opt=""); /// Number of marks in legend sample inline void SetLegendMarks(int num=1) { LegendMarks = num>0?num:1; } /// Draw table for values val along given direction with row labels text at given position void Table(mreal x, mreal y, HCDT val, const wchar_t *text, const char *fnt, const char *opt); void StartAutoGroup (const char *); void EndGroup(); /// Set extra shift for tick and axis labels inline void SetTickShift(mglPoint p) { ax.sh = p.x; ay.sh = p.y; az.sh = p.z; ac.sh = p.c; } /// Get rotation angle for glyph float GetGlyphPhi(const mglPnt &q, float phi); // Following arrays are open for advanced users only. It is not recommended to change them directly float *Z; ///< Height for given level in Z-direction (size 3*width*height) unsigned char *C; ///< Picture for given level in Z-direction (size 3*4*width*height) int *OI; ///< ObjId arrays (size width*height) /// Plot point p with color c void pnt_plot(long x,long y,mreal z,const unsigned char c[4], int obj_id); void pnt_fast(long x,long y,mreal z,const unsigned char c[4], int obj_id); /// preparing primitives for 2d export or bitmap drawing (0 default, 1 for 2d vector, 2 for 3d vector) void PreparePrim(int fast); inline uint32_t GetPntCol(long i) const { return pnt_col[i]; } inline uint32_t GetPrmCol(long i, bool sort=true) const { return GetColor(GetPrm(i, sort)); } /// Set the size of semi-transparent area around lines, marks, ... inline void SetPenDelta(float d) { pen_delta = 1.5*fabs(d); } protected: mreal Delay; ///< Delay for animation in seconds // NOTE: Z should be float for reducing space and for compatibility reasons unsigned char *G4; ///< Final picture in RGBA format. Prepared in Finish(). unsigned char *G; ///< Final picture in RGB format. Prepared in Finish(). unsigned char *GB; ///< Background picture in RGBA format. std::vector DrwDat; ///< Set of ALL drawing data for each frames int LegendMarks; ///< Number of marks in the Legend unsigned char BDef[4]; ///< Background color mglAxis ax,ay,az,ac;///< Axis parameters int TuneTicks; ///< Draw tuned ticks with extracted common component mreal FactorPos; ///< Position of axis ticks factor (0 at Min, 1 at Max, 1.1 is default) mreal TickLen; ///< Length of tiks (subticks length is sqrt(1+st_t)=1.41... times smaller) char AxisStl[32]; ///< Axis line style. Default is "k" char TickStl[32]; ///< Tick line style. Default is "k" char SubTStl[32]; ///< Subtick line style. Default is "k" mreal st_t; ///< Subtick-to-tick ratio (ls=lt/sqrt(1+st_t)). Default is 1. int CurFrameId; ///< Number of automaticle created frames int Width; ///< Width of the image int Height; ///< Height of the image int Depth; ///< Depth of the image mreal inW, inH; ///< Width and height of last InPlot mreal inX, inY; ///< Coordinates of last InPlot mglLight light[10]; ///< Light sources mreal FogDist; ///< Inverse fog distance (fog ~ exp(-FogDist*Z)) mreal FogDz; ///< Relative shift of fog inline mglAxis &GetAxis(unsigned ch) { mglAxis *aa[3]={&ax,&ay,&az}; ch-='x'; return ch<3?*(aa[ch]):ac; } inline HMEX GetFormula(unsigned ch) { HMEX aa[3]={fx,fy,fz}; ch-='x'; return ch<3?aa[ch]:fa; } /// Auto adjust ticks void AdjustTicks(mglAxis &aa, bool ff); /// Prepare labels for ticks void LabelTicks(mglAxis &aa); /// Draw axis void DrawAxis(mglAxis &aa, int text=1, char arr=0,const char *stl="",mreal angl=NAN); /// Draw axis grid lines void DrawGrid(mglAxis &aa, bool at_tick=false); /// Update axis ranges inline void UpdateAxis() { ax.v0=Org.x; ay.v0=Org.y; az.v0=Org.z; ac.v0=Org.c; ax.v1=Min.x; ay.v1=Min.y; az.v1=Min.z; ac.v1=Min.c; ax.v2=Max.x; ay.v2=Max.y; az.v2=Max.z; ac.v2=Max.c; } /// Clear ZBuffer only void ClfZB(bool force=false); /// Scale coordinates and cut off some points bool ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan=true) const; void LightScale(const mglMatrix *M); ///< Additionally scale positions of light sources void LightScale(const mglMatrix *M, mglLight &l); ///< Additionally scale positions of light /// Push drawing data (for frames only). NOTE: can be VERY large long PushDrwDat(); /// Retur color for primitive depending lighting uint32_t GetColor(const mglPrim &p) const MGL_FUNC_PURE; mreal GetOrgX(char dir, bool inv=false) const MGL_FUNC_PURE; ///< Get Org.x (parse NAN value) mreal GetOrgY(char dir, bool inv=false) const MGL_FUNC_PURE; ///< Get Org.y (parse NAN value) mreal GetOrgZ(char dir, bool inv=false) const MGL_FUNC_PURE; ///< Get Org.z (parse NAN value) void mark_plot(long p, char type, mreal size=1); void arrow_plot(long p1, long p2, char st); void line_plot(long p1, long p2); void trig_plot(long p1, long p2, long p3); void quad_plot(long p1, long p2, long p3, long p4); void Glyph(mreal x, mreal y, mreal f, int style, long icode, mreal col); void smbl_plot(long p1, char id, double size); mreal text_plot(long p,const wchar_t *text,const char *fnt,mreal size=-1,mreal sh=0,mreal col=-('k'), bool rot=true); void add_prim(mglPrim &a); ///< add primitive to list void arrow_draw(const mglPnt &p1, const mglPnt &p2, char st, mreal size, const mglDrawReg *d); virtual void mark_draw(const mglPnt &p, char type, mreal size, mglDrawReg *d); virtual void line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d); virtual void trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d); virtual void quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d); virtual void pnt_draw(const mglPnt &p, const mglDrawReg *d); void arrow_draw(long n1, long n2, char st, float ll); void arrow_plot_3d(long n1, long n2, char st, float ll); void glyph_draw(const mglPrim &P, mglDrawReg *d); void glyph_draw_new(const mglPrim &P, mglDrawReg *d); bool IsSame(const mglPrim &pr,mreal wp,mglColor cp,int st); // check if visible bool trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const; bool quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const; // functions for glyph drawing virtual void glyph_fill(mreal phi, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d); void glyph_wire(mreal phi, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d); void glyph_line(mreal phi, const mglPnt &p, mreal f, bool solid, const mglDrawReg *d); // restore normalized coordinates from screen ones mglPoint RestorePnt(mglPoint ps, bool norm=false) const MGL_FUNC_PURE; // functions for multi-threading void pxl_pntcol(long id, long n, const void *); void pxl_combine(long id, long n, const void *); void pxl_memcpy(long id, long n, const void *); void pxl_backgr(long id, long n, const void *); void pxl_primdr(long id, long n, const void *); void pxl_dotsdr(long id, long n, const void *); void pxl_primpx(long id, long n, const void *); void pxl_transform(long id, long n, const void *); void pxl_setz(long id, long n, const void *); void pxl_setz_adv(long id, long n, const void *); void pxl_other(long id, long n, const void *p); /// Put drawing from other mglCanvas (for multithreading, like subplots) void PutDrawReg(mglDrawReg *d, const mglCanvas *gr); private: mglCanvas(const mglCanvas &){} // copying is not allowed const mglCanvas &operator=(const mglCanvas &t){return t;} // copying is not allowed mglMatrix sB; // parameters of saved inplot mreal sW, sH, sZ, sX, sY, sFF; uint32_t *pnt_col; // mreal _tetx,_tety,_tetz; // extra angles std::vector stack; ///< stack for transformation matrices GifFileType *gif; mreal fscl,ftet; ///< last scale and rotation for glyphs long forg; ///< original point (for directions) size_t grp_counter; ///< Counter for StartGroup(); EndGroup(); mglMatrix Bt; ///< temporary matrix for text float pen_delta; ///< delta pen width (dpw) -- the size of semi-transparent region for lines, marks, ... /// Draw generic colorbar void colorbar(HCDT v, const mreal *s, int where, mreal x, mreal y, mreal w, mreal h, bool text); /// Draw labels for ticks void DrawLabels(mglAxis &aa, bool inv=false, const mglMatrix *M=0); /// Get label style char GetLabelPos(mreal c, long kk, mglAxis &aa); /// Draw tick void tick_draw(mglPoint o, mglPoint d1, mglPoint d2, int f); mreal FindOptOrg(char dir, int ind) const MGL_FUNC_PURE; /// Transform mreal color and alpha to bits format void col2int(const mglPnt &p, unsigned char *r, int obj_id) const; /// Combine colors in 2 plane. void combine(unsigned char *c1, const unsigned char *c2) const; /// Fast drawing of line between 2 points void fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d); /// Additionally scale points p for positioning in image void PostScale(const mglMatrix *M, mglPoint &p) const; /// Scale points p for projection to the face number nface in image long ProjScale(int nface, long p, bool text=false); /// Set coordinate and add the point, return its id long setPp(mglPnt &q, const mglPoint &p); // fill pixel for given primitive void mark_pix(long i,long j,const mglPnt &p, char type, mreal size, mglDrawReg *d); void arrow_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, char st, mreal size, const mglDrawReg *d); void line_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d); void trig_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d); void quad_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d); void glyph_pix(long i,long j,const mglPrim &P, mglDrawReg *d); void pnt_pix(long i,long j,const mglPnt &p, const mglDrawReg *d); void glyph_fpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d); void glyph_wpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d); void glyph_lpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, bool solid, const mglDrawReg *d); }; //----------------------------------------------------------------------------- struct mglThreadG { mglCanvas *gr; // grapher void (mglCanvas::*f)(long i, long n, const void *); unsigned id; // thread id long n; // total number of iteration const void *p; // external parameter }; /// Start several thread for the task void mglStartThread(void (mglCanvas::*func)(long i, long n), mglCanvas *gr, long n); //----------------------------------------------------------------------------- inline mreal get_persp(float pf, float z, float Depth) //{ return (1-pf)/(1-pf*z/Depth); } { return (1-pf/1.37)/(1-pf*z/Depth); } inline mreal get_pfact(float pf, float Depth) //{ return pf/(1-pf)/Depth; } { return pf/(1-pf/1.37)/Depth; } //----------------------------------------------------------------------------- #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/evalc.h�������������������������������������������������������������������0000644�0001750�0001750�00000006146�13513030041�016703� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * evalc.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_EVALC_H_ #define _MGL_EVALC_H_ //----------------------------------------------------------------------------- #include "mgl2/eval.h" class mglDataC; //----------------------------------------------------------------------------- /// Class for evaluating formula specified by the string class MGL_EXPORT mglFormulaC // ������ ��� ����� � ���������� ������ { public: /// Evaluates the formula for 'x','r'=\a x, 'y','n'=\a y, 'z','t'=\a z, 'u'=\a u dual Calc(dual x,dual y=0,dual z=0,dual u=0) const MGL_FUNC_PURE; /// Evaluates the formula for 'x, y, z, u, v, w' dual Calc(dual x,dual y,dual z,dual u,dual v,dual w) const MGL_FUNC_PURE; /// Evaluates the formula for variables var dual Calc(const dual var[MGL_VS]) const MGL_FUNC_PURE; /// Return error code inline int GetError() const { return Error; } /// Parse the formula str and create formula-tree mglFormulaC(const char *str); /// Set data for the spline interpolation mglFormulaC(HCDT d, mreal x1=0, mreal x2=1, mreal y1=0, mreal y2=1, mreal z1=0, mreal z2=1) : dat(d),dx1(x1),dx2(x2),dy1(y1),dy2(y2),dz1(z1),dz2(z2),tmp(NULL) {}; /// Clean up formula-tree virtual ~mglFormulaC(); protected: dual CalcIn(const dual *a1) const MGL_FUNC_PURE; mglFormulaC *Left,*Right; // first and second argument of the function int Kod; // the function ID dual Res; // the number or the variable ID HCDT dat; // data file for the interpolation mreal dx1,dx2,dy1,dy2,dz1,dz2; // ranges of data files static int Error; private: mglDataC *tmp; }; //----------------------------------------------------------------------------- #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/mglplot.fs����������������������������������������������������������������0000644�0001750�0001750�00000037734�13513030041�017457� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\ Mathgl library wrapper Thu Feb 21 12:33:02 MST 2008 \ Copyright (C) 2008, Sergey Plis \ \ This program is free software; you can redistribute it and/or modify \ it under the terms of the GNU General Public License as published by \ the Free Software Foundation; either version 2 of the License, or \ (at your option) any later version. \ \ This program is distributed in the hope that it will be useful, \ but WITHOUT ANY WARRANTY; without even the implied warranty of \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \ GNU General Public License for more details. \needs gsl include gsl.fs \needs mathgl include mathgl.fs \needs vectors include vectors.fs \needs $! include string.fs Module mglplot also minos also vectors also gsl also mathgl also float \ ------------------------------------------------------------------------ \ structures \ ------------------------------------------------------------------------ struct{ cell transp? cell transp_type cell alpha? cell light cell box cell grid double ambient cell axis? cell axis_str cell rotation[ cell aspect[ cell colorbar double linewidth double fontsize cell labelx$ cell labely$ cell labelz$ cell textrotate } mgl-params struct{ cell next \ next plot in the list of current figure cell prev cell xrange \ cell yrange \ cell zrange \ cell hmdtlist \ vector of all data objects used in the plot cell params \ vector of parameters to the plotting function cell ops \ vector of xt's of operations to place params \ list on the stack so the plotting function can \ be executed cell plotfunc \ the plotting function } a_plot struct{ cell next \ next figure in the figure structure cell # cell active? \ True/False cell figure \ plot object } a_figure : dispose-hmdtlist ( v( -- ) dup )size 0 do dup i )@ mgl_delete_data loop drop ; : dispose-a-plot ( *a_plot -- ) dup a_plot hmdtlist @ dispose-hmdtlist dup a_plot params @ )free dup a_plot ops @ )free dup a_plot xrange @ ]free dup a_plot yrange @ ]free dup a_plot zrange @ ]free free throw ; : dispose-all-plots ( *a_plot -- ) dup begin while dup a_plot next @ swap dispose-a-plot dup repeat drop ; \ simple aux words | : ]@s ( x[ -- f: x[0] .. x[n] ) dup ]size 0 do dup i ]@ loop drop ; | : ]!s ( x[ f: x[0] .. x[n] -- ) dup ]size 0 do dup i ]! loop drop ; | create axis-param 0 c, 0 c, 0 c, 0 c, 0 c, | create mglstrbuff $FF allot : default-rotation ( -- r[ ) 3 :] dup 0e 0e 0e ]!s ; : clear-axis-param axis-param dup 'x swap c! 1+ dup 'y swap c! 1+ 'z swap c! ; : NAN ( -- f: NAN) $7FC00000 sp@ sf@ drop ; \ ------------------------------------------------------------------------ \ GUI \ ------------------------------------------------------------------------ component class mathplot private: method fill-pixmap method mgl_settings_reset cell var mhold public: early open early dialog early open-app method generate-plot method addplot method clear-pixmap method #plots method clf method mgl-rotation! method mgl-colorbar method mgl-hold method mgl-holdoff method mgl-holdon method hold@ method hold! method mgl-grid method fontsize method mgl-xlabel method mgl-ylabel method mgl-zlabel canvas ptr mCanvas ( [varstart] ) \ memory-pixmap ptr pxmap \ the pixmap on the canvas cell var pxmap cell var graph \ the graph to display cell var plotlist \ list of plots to display cell var parameters \ parameter structure ( [varend] ) how: : params DF[ 0 ]DF s" figure" ; : hold@ mhold @ ; : hold! mhold ! ; : mgl-hold mhold @ not mhold ! ; : mgl-holdoff mhold off ; : mgl-holdon mhold on ; : open self DF[ 0 ]DF s" bigforth Plot" open-component ; : dialog new DF[ 0 ]DF s" bigforth Plot" open-dialog ; : open-app new DF[ 0 ]DF s" bigforth Plot" open-application ; : clear-pixmap pxmap @ if pxmap @ >o dispose o> 0 pxmap ! then ; : #plots ( -- ) 0 plotlist @ begin dup while swap 1+ swap a_plot next @ repeat drop ; : assign &600 &400 mgl_create_graph_zb graph ! sizeof mgl-params allocate throw parameters ! parameters @ sizeof mgl-params erase mgl_settings_reset \ 0 0 parameters @ mgl-params labelx$ dup @ if $off else drop then \ 0 0 parameters @ mgl-params labely$ dup @ if $off else drop then \ 0 0 parameters @ mgl-params labelz$ dup @ if $off else drop then 0 pxmap ! 0 plotlist ! mhold off ; : fontsize ( f: size -- ) parameters @ mgl-params fontsize sf! ; : mgl-set-params ( -- ) graph @ dup parameters @ mgl-params rotation[ @ ]@s mgl_rotate dup parameters @ mgl-params ambient sf@ mgl_set_ambbr dup parameters @ mgl-params fontsize sf@ mgl_set_font_size dup parameters @ mgl-params linewidth sf@ mgl_set_base_line_width dup parameters @ mgl-params aspect[ @ ]@s mgl_aspect dup parameters @ mgl-params transp? @ mgl_set_transp dup parameters @ mgl-params transp_type @ mgl_set_transp_type dup parameters @ mgl-params alpha? @ mgl_set_alpha dup parameters @ mgl-params light @ mgl_set_light dup parameters @ mgl-params textrotate @ mgl_set_rotated_text dup parameters @ mgl-params box @ mgl_box parameters @ mgl-params grid @ if dup 0" xyz" 0 mgl_axis_grid then drop ; : mgl-post-params ( -- ) graph @ 1 mgl_set_rotated_text parameters @ mgl-params labelx$ @ if parameters @ mgl-params labelx$ $@ mglstrbuff 0place parameters @ mgl-params fontsize sf@ 0e0 graph @ 'x mglstrbuff 0 mgl_label_ext then parameters @ mgl-params labely$ @ if parameters @ mgl-params labely$ $@ mglstrbuff 0place parameters @ mgl-params fontsize sf@ 0e0 graph @ 'y mglstrbuff 0 mgl_label_ext then parameters @ mgl-params labelz$ @ drop 0 if parameters @ mgl-params labelz$ $@ mglstrbuff 0place parameters @ mgl-params fontsize sf@ 0e0 graph @ 'z mglstrbuff 0 mgl_label_ext then parameters @ mgl-params colorbar @ drop 0 if dup 0 0 mgl_colorbar then ; : mgl_settings_reset 1 parameters @ mgl-params transp? ! 1 parameters @ mgl-params transp_type ! 0 parameters @ mgl-params alpha? ! 0 parameters @ mgl-params box ! 0 parameters @ mgl-params colorbar ! 0 parameters @ mgl-params light ! 1 parameters @ mgl-params axis? ! axis-param parameters @ mgl-params axis_str ! clear-axis-param parameters @ mgl-params labelx$ dup @ if $off else drop then parameters @ mgl-params labely$ dup @ if $off else drop then parameters @ mgl-params labelz$ dup @ if $off else drop then \ parameters @ mgl-params textrotate off !0.9 parameters @ mgl-params ambient sf! !2.5 parameters @ mgl-params fontsize sf! !1.2 parameters @ mgl-params linewidth sf! parameters @ mgl-params rotation[ @ dup if ]free else drop then default-rotation parameters @ mgl-params rotation[ ! parameters @ mgl-params aspect[ @ dup if ]free else drop then 3 :] parameters @ mgl-params aspect[ ! ; : mgl_settings_free parameters @ mgl-params labelx$ dup @ if $off else drop then parameters @ mgl-params labely$ dup @ if $off else drop then parameters @ mgl-params labelz$ dup @ if $off else drop then parameters @ mgl-params rotation[ @ dup if ]free else drop then parameters @ mgl-params aspect[ @ dup if ]free else drop then ; : addplot ( *a_plot -- ) mhold @ if >r plotlist @ r@ a_plot next ! r> plotlist @ if dup plotlist @ a_plot prev ! then else plotlist @ dispose-all-plots then plotlist ! generate-plot mcanvas draw ; : display_a_plot ( *a_plot -- ) >r graph @ r@ a_plot ops @ r@ a_plot params @ dup )size 0 do i -rot 2>r 2r@ rot dup >r *) swap r> )@ F execute 2r> loop 2drop r> a_plot plotfunc @ F execute ; : xmin ( -- f: xmin ) 1e20 plotlist @ begin dup while dup a_plot xrange @ ]min fmin a_plot next @ repeat drop ; : xmax ( -- f: xmax ) -1e20 plotlist @ begin dup while dup a_plot xrange @ ]max fmax a_plot next @ repeat drop ; : ymin ( -- f: ymin ) 1e20 plotlist @ begin dup while dup a_plot yrange @ ]min fmin a_plot next @ repeat drop ; : ymax ( -- f: ymax ) -1e20 plotlist @ begin dup while dup a_plot yrange @ ]max fmax a_plot next @ repeat drop ; : zmin ( -- f: zmin ) 1e20 plotlist @ begin dup while dup a_plot zrange @ ]min fmin a_plot next @ repeat drop ; : zmax ( -- f: ymax ) -1e20 plotlist @ begin dup while dup a_plot zrange @ ]max fmax a_plot next @ repeat drop ; : display_plots ( -- ) 0 plotlist @ begin dup while nip dup a_plot next @ repeat drop begin dup while dup display_a_plot a_plot prev @ repeat drop ; : create-figure ( -- ) graph @ mgl_identity graph @ mgl_clf graph @ mCanvas with w @ h @ endwith mgl_set_size \ parameters @ mgl-params rotation[ @ ]null? if \ graph @ \ [ 1e 3e fsqrt f/ 1e fswap f- 2e f/ 0.7e f* ] fliteral \ fdup \ fdup fdup 1e fswap f- fswap 1e fswap f- \ mgl_set_zoom \ else graph @ 0e 0e 0e 0e mgl_set_zoom \ parameters @ mgl-params fontsize sf@ \ 1.2e f* parameters @ mgl-params fontsize sf! \ then graph @ xmin ymin zmin xmax ymax zmax mgl_set_axis_3d \ graph @ xmin ymin zmin mgl_set_origin graph @ NAN NAN NAN mgl_set_origin mgl-set-params mgl-post-params display_plots ; : fill-pixmap clear-pixmap graph @ mgl_get_rgb mCanvas with w @ h @ endwith * 4 * dup allocate throw dup >r swap 4 / 3 * move r@ mCanvas with w @ h @ endwith memory-pixmap new pxmap ! r> free throw ; : generate-plot ( -- ) create-figure fill-pixmap ; : freeplots plotlist @ dispose-all-plots 0 plotlist ! ; : clf freeplots clear-pixmap draw ; : mgl-rotation! ( f: x y z ) fswap frot parameters @ mgl-params rotation[ @ ]!s generate-plot mcanvas draw ; : mgl-rotation@ ( -- f: x y z ) parameters @ mgl-params rotation[ @ ]@s ; : mgl-colorbar ( -- ) parameters @ mgl-params colorbar @ not parameters @ mgl-params colorbar ! generate-plot mcanvas draw ; : mgl-grid parameters @ mgl-params grid dup @ not swap ! generate-plot mcanvas draw ; : mgl-xlabel ( addr u -- ) parameters @ mgl-params labelx$ dup @ if dup $off $! else $! then generate-plot mcanvas draw ; : mgl-ylabel ( addr u -- ) parameters @ mgl-params labely$ dup @ if dup $off $! else $! then generate-plot mcanvas draw ; : mgl-zlabel ( addr u -- ) parameters @ mgl-params labelz$ dup @ if dup $off $! else $! then generate-plot mcanvas draw ; : dispose clear-pixmap plotlist @ dispose-all-plots graph @ mgl_delete_graph mgl_settings_free parameters @ sizeof mgl-params erase parameters @ free throw super dispose ; : widget CV[ outer with pxmap @ endwith 0<> if outer with pxmap @ endwith icon then ]CV ^^ CK[ 2drop 2drop ]CK $258 $1 *hfil $190 $1 *vfil canvas new ^^bind mCanvas $10 $1 *hfill *hglue new ^^ S[ s" not done" mCanvas text ]S X" Save " button new ^^ S[ close ]S X" Close " button new &3 habox new vfixbox panel &2 vabox new ; class; sizeof a_figure allocate throw constant current-figure current-figure sizeof a_figure erase actor class clear-pointer how: : dispose current-figure a_figure active? off current-figure sizeof a_figure erase super dispose ; class; : init-plot current-figure a_figure active? @ not if screen self mathplot new current-figure a_figure figure ! current-figure a_figure active? on clear-pointer new current-figure a_figure figure @ mathplot with >callback open endwith then ; : s>range[] ( fmin fmax -- :] ) 2 :] dup 1 ]! dup 0 ]! ; : []plot ( x[ str0 xt -- *a_plot ) >r >r dup >r mgl_create_data dup rot mgl_data_set_vector sizeof a_plot allocate throw dup r@ dup ]min ]max s>range[] swap a_plot yrange ! dup r> ]size 0e s>f s>range[] swap a_plot xrange ! dup 0e 0e s>range[] swap a_plot zrange ! dup 0 swap a_plot next ! dup 0 swap a_plot prev ! over 1 ivector* over a_plot hmdtlist ! over r> 2 ivector* over a_plot params ! ['] @ ['] @ 2 ivector* over a_plot ops ! nip r> over a_plot plotfunc ! ; : addplot ( *a_plot -- ) init-plot current-figure a_figure figure @ mathplot with addplot endwith ; : ]plot ( *gsl_vector 0"" -- ) ['] mgl_plot []plot addplot ; : ]stem ( *gsl_vector 0"" -- ) ['] mgl_stem []plot addplot ; : ]bars ( *gsl_vector 0"" -- ) ['] mgl_bars []plot addplot ; : ]step ( *gsl_vector 0"" -- ) ['] mgl_step []plot addplot ; : ]area ( *gsl_vector 0"" -- ) ['] mgl_area []plot addplot ; : [[]]plot ( x[[ str0 xt -- *a_plot ) >r >r dup >r mgl_create_data dup rot mgl_data_set_matrix sizeof a_plot allocate throw dup r@ dup ]]min ]]max s>range[] swap a_plot zrange ! dup r@ ]]size1 0e s>f s>range[] swap a_plot xrange ! dup r> ]]size2 0e s>f s>range[] swap a_plot yrange ! dup 0 swap a_plot next ! dup 0 swap a_plot prev ! over 1 ivector* over a_plot hmdtlist ! over r> 2 ivector* over a_plot params ! ['] @ ['] @ 2 ivector* over a_plot ops ! nip r> over a_plot plotfunc ! ; : ]]surf ( *gsl_matrix 0"" -- ) ['] mgl_surf [[]]plot addplot ; : ]]tile ( *gsl_matrix 0"" -- ) ['] mgl_tile [[]]plot addplot ; : ]]belt ( *gsl_matrix 0"" -- ) ['] mgl_belt [[]]plot addplot ; : ]]fall ( *gsl_matrix 0"" -- ) ['] mgl_fall [[]]plot addplot ; : ]]mesh ( *gsl_matrix 0"" -- ) ['] mgl_mesh [[]]plot addplot ; : ]]msurf ( *gsl_matrix 0"" -- ) init-plot 2dup ]]surf current-figure a_figure figure @ mathplot with hold@ mgl-holdon endwith >r ]]mesh r> current-figure a_figure figure @ mathplot with hold! endwith ; : [[]]plotf ( f:v x[[ str0 xt -- *a_plot ) >r >r dup >r mgl_create_data dup rot mgl_data_set_matrix sizeof a_plot allocate throw dup r@ dup ]]min ]]max s>range[] swap a_plot zrange ! dup r@ ]]size1 0e s>f s>range[] swap a_plot xrange ! dup r> ]]size2 0e s>f s>range[] swap a_plot yrange ! dup 0 swap a_plot next ! dup 0 swap a_plot prev ! over 1 ivector* over a_plot hmdtlist ! over r> f>fs 3 ivector* over a_plot params ! ['] @ ['] @ ['] sf@ 3 ivector* over a_plot ops ! nip r> over a_plot plotfunc ! ; : ]]boxs ( f:v *gsl_matrix 0"" -- ) ['] mgl_boxs [[]]plotf addplot ; : clf current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot clf o> then ; : fontsize! ( f:size -- ) current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot fontsize o> then ; : rotation ( F: x y z -- ) current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-rotation! o> else fdrop fdrop fdrop then ; : colorbar current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-colorbar o> then ; : mglhold current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-hold o> then ; : mglholdon current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-holdon o> then ; : mglholdoff current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-holdoff o> then ; : mglgrid current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-grid o> then ; : xlabel ( addr u -- ) current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-xlabel o> then ; : ylabel ( addr u -- ) current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-ylabel o> then ; : zlabel ( addr u -- ) current-figure a_figure active? @ if current-figure a_figure figure @ >o mathplot mgl-zlabel o> then ; clear previous previous previous previous previous Module; \\\ also mglplot also minos also gsl 100 fvector x[ x[ ]randomize x[ 0 ]plot ������������������������������������mathgl-2.4.4/include/mgl2/prim.h��������������������������������������������������������������������0000644�0001750�0001750�00000051621�13513030041�016556� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * prim.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_PRIM_H_ #define _MGL_PRIM_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Draws the mark at position {x,y,z} void MGL_EXPORT mgl_mark(HMGL gr, double x,double y,double z,const char *mark); void MGL_EXPORT mgl_mark_(uintptr_t *gr, mreal *x, mreal *y, mreal *z,const char *mark,int); /// Draws red point (ball) at position {x,y,z} void MGL_EXPORT mgl_ball(HMGL gr, double x,double y,double z); void MGL_EXPORT mgl_ball_(uintptr_t *gr, mreal *x, mreal *y, mreal *z); /// Draws the line between 2 points by specified pen /** Large \a n (for example, n=100) should be used for geodesic line in curvilinear coordinates */ void MGL_EXPORT mgl_line(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, const char *pen,int n); void MGL_EXPORT mgl_line_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, const char *pen,int *n,int); /// Draws the spline curve between 2 points by specified pen void MGL_EXPORT mgl_curve(HMGL gr, double x1, double y1, double z1, double dx1, double dy1, double dz1, double x2, double y2, double z2, double dx2, double dy2, double dz2, const char *pen,int n); void MGL_EXPORT mgl_curve_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *dx1, mreal *dy1, mreal *dz1, mreal *x2, mreal *y2, mreal *z2, mreal *dx2, mreal *dy2, mreal *dz2, const char *pen,int *n, int l); /// Draws the 3d error box {ex,ey,ez} for point {x,y,z} void MGL_EXPORT mgl_error_box(HMGL gr, double x, double y, double z, double ex, double ey, double ez, const char *pen); void MGL_EXPORT mgl_error_box_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, mreal *ex, mreal *ey, mreal *ez, const char *pen, int); /// Draws the face between points with color stl (include interpolation up to 4 colors). void MGL_EXPORT mgl_face(HMGL gr, double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, const char *stl); void MGL_EXPORT mgl_face_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *x3, mreal *y3, mreal *z3, const char *stl, int); /// Draws the face in y-z plane at point p with color stl (include interpolation up to 4 colors). void MGL_EXPORT mgl_facex(HMGL gr, double x0, double y0, double z0, double wy, double wz, const char *stl, double dx, double dy); void MGL_EXPORT mgl_facex_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *wy, mreal *wz, const char *stl, mreal *dx, mreal *dy, int l); /// Draws the face in x-z plane at point p with color stl (include interpolation up to 4 colors). void MGL_EXPORT mgl_facey(HMGL gr, double x0, double y0, double z0, double wx, double wz, const char *stl, double dx, double dy); void MGL_EXPORT mgl_facey_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *wx, mreal *wz, const char *stl, mreal *dx, mreal *dy, int l); /// Draws the face in x-y plane at point p with color stl (include interpolation up to 4 colors). void MGL_EXPORT mgl_facez(HMGL gr, double x0, double y0, double z0, double wx, double wy, const char *stl, double dx, double dy); void MGL_EXPORT mgl_facez_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *wx, mreal *wy, const char *stl, mreal *dx, mreal *dy, int l); /// Draws the sphere at point {x,y,z} with color stl and radius r void MGL_EXPORT mgl_sphere(HMGL gr, double x, double y, double z, double r, const char *stl); void MGL_EXPORT mgl_sphere_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, mreal *r, const char *stl, int); /// Draws the drop at point {x,y,z} in direction {dx,dy,dz} with color stl and radius r /** Parameter \a shift set the degree of drop oblongness: ‘0’ is sphere, ‘1’ is maximally oblongness drop. Parameter \a ap set relative width of the drop (this is analogue of “ellipticity” for the sphere).*/ void MGL_EXPORT mgl_drop(HMGL gr, double x, double y, double z, double dx, double dy, double dz, double r, const char *stl, double shift, double ap); void MGL_EXPORT mgl_drop_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl, mreal *shift, mreal *ap, int); /// Draws the cone between points p1,p2 with radius r1,r2 and with style stl /** Parameter \a stl can contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinder instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones.*/ void MGL_EXPORT mgl_cone(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r1, double r2, const char *stl); void MGL_EXPORT mgl_cone_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r1, mreal *r2, const char *stl, int); /// Draws the ellipse between points p1,p2 with color stl and width r /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ void MGL_EXPORT mgl_ellipse(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl); void MGL_EXPORT mgl_ellipse_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl, int); /// Draws the rhomb between points p1,p2 with color stl and width r /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ void MGL_EXPORT mgl_rhomb(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl); void MGL_EXPORT mgl_rhomb_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl, int); /// Draws the polygon based on points p1,p2 with color stl /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ void MGL_EXPORT mgl_polygon(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, int n, const char *stl); void MGL_EXPORT mgl_polygon_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, int *n, const char *stl, int); /// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees) void MGL_EXPORT mgl_arc_ext(HMGL gr, double x0, double y0, double z0, double xr, double yr, double zr, double x1, double y1, double z1, double a, const char *stl); void MGL_EXPORT mgl_arc_ext_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *xr, mreal *yr, mreal *zr, mreal *x1, mreal *y1, mreal *z1, mreal *a, const char *stl, int); /// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees) void MGL_EXPORT mgl_arc(HMGL gr, double x0, double y0, double x1, double y1, double a, const char *stl); void MGL_EXPORT mgl_arc_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *x1, mreal *y1, mreal *a, const char *stl,int l); /// Draw cones from points {x,y,z} to axis plane /** String \a pen may contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinders instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones; * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_cones_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_cones_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw cones from points {x,z} to axis plane /** String \a pen may contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinders instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones; * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_cones_xz(HMGL graph, HCDT x, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_cones_xz_(uintptr_t *graph, uintptr_t *x, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw cones from points {x,z} with x in x-axis range to axis plane /** String \a pen may contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinders instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones; * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ void MGL_EXPORT mgl_cones(HMGL graph, HCDT z, const char *pen, const char *opt); void MGL_EXPORT mgl_cones_(uintptr_t *graph, uintptr_t *z, const char *pen, const char *opt,int,int); /// Plot dew drops for vector field {ax,ay} parametrically depended on coordinate {x,y} void MGL_EXPORT mgl_dew_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt); void MGL_EXPORT mgl_dew_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int); /// Plot dew drops for vector field {ax,ay} void MGL_EXPORT mgl_dew_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *optl); void MGL_EXPORT mgl_dew_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int,int l); /// Print text in position {x,y,z} with specified font /* NOTE: Function don't have options because it can be part of group.*/ void MGL_EXPORT mgl_puts(HMGL graph, double x, double y, double z,const char *text, const char *font, double size); void MGL_EXPORT mgl_puts_(uintptr_t *graph, mreal *x, mreal *y, mreal *z,const char *text, const char *font, mreal *size, int, int); void MGL_EXPORT mgl_putsw(HMGL graph, double x, double y, double z,const wchar_t *text, const char *font, double size); /// Print text in position {x,y,z} along direction {dx,dy,dz} with specified font /* NOTE: Function don't have options because it can be part of group.*/ void MGL_EXPORT mgl_puts_dir(HMGL graph, double x, double y, double z, double dx, double dy, double dz, const char *text, const char *font, double size); void MGL_EXPORT mgl_puts_dir_(uintptr_t *graph, mreal *x, mreal *y, mreal *z, mreal *dx, mreal *dy, mreal *dz, const char *text, const char *font, mreal *size, int, int); void MGL_EXPORT mgl_putsw_dir(HMGL graph, double x, double y, double z, double dx, double dy, double dz, const wchar_t *text, const char *font, double size); /// Draw user-defined symbol in position p void MGL_EXPORT mgl_symbol(HMGL gr, double x, double y, double z, char id, const char *how, double size); void MGL_EXPORT mgl_symbol_(uintptr_t *gr, double *x, double *y, double *z, char *id, const char *how, double *size,int,int); /// Draw user-defined symbol in position p along direction d void MGL_EXPORT mgl_symbol_dir(HMGL gr, double x, double y, double z, double dx, double dy, double dz, char id, const char *how, double size); void MGL_EXPORT mgl_symbol_dir_(uintptr_t *gr, double *x, double *y, double *z, double *dx, double *dy, double *dz, char *id, const char *how, double *size,int,int); /// Draw textual marks with size r at points {x,y,z} void MGL_EXPORT mgl_textmark_xyzr(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_textmark_xyzr_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *text, const char *fnt, const char *opt,int,int,int); void MGL_EXPORT mgl_textmarkw_xyzr(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const wchar_t *text, const char *fnt, const char *opt); /// Draw textual marks with size r at points {x,y} void MGL_EXPORT mgl_textmark_xyr(HMGL graph, HCDT x, HCDT y, HCDT r, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_textmark_xyr_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *text, const char *fnt, const char *opt,int,int,int); void MGL_EXPORT mgl_textmarkw_xyr(HMGL graph, HCDT x, HCDT y, HCDT r, const wchar_t *text, const char *fnt, const char *opt); /// Draw textual marks with size r at points {x,y} with x in x-axis range void MGL_EXPORT mgl_textmark_yr(HMGL graph, HCDT y, HCDT r, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_textmark_yr_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *text, const char *fnt, const char *opt,int,int,int); void MGL_EXPORT mgl_textmarkw_yr(HMGL graph, HCDT y, HCDT r, const wchar_t *text, const char *fnt, const char *opt); /// Draw textual marks with size r=1 at points {x,y} with x in x-axis range void MGL_EXPORT mgl_textmark(HMGL graph, HCDT y, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_textmarkw(HMGL graph, HCDT y, const wchar_t *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_textmark_(uintptr_t *graph, uintptr_t *y, const char *text, const char *fnt, const char *opt,int,int,int); /// Draw labels for points coordinate(s) at points {x,y,z} /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ void MGL_EXPORT mgl_label_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_label_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *text, const char *fnt, const char *opt,int,int,int); void MGL_EXPORT mgl_labelw_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const wchar_t *text, const char *fnt, const char *opt); /// Draw labels for points coordinate(s) at points {x,y} /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ void MGL_EXPORT mgl_label_xy(HMGL graph, HCDT x, HCDT y, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_label_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, const char *text, const char *fnt, const char *opt,int,int,int); void MGL_EXPORT mgl_labelw_xy(HMGL graph, HCDT x, HCDT y, const wchar_t *text, const char *fnt, const char *opt); /// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ void MGL_EXPORT mgl_label_y(HMGL graph, HCDT y, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_labelw_y(HMGL graph, HCDT y, const wchar_t *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_label_y_(uintptr_t *graph, uintptr_t *y, const char *text, const char *fnt, const char *opt,int,int,int); /// Draw table for values val along given direction with row labels text at position {x,y} /** String \a fnt may contain: * ‘#’ for drawing cell borders; * ‘|’ for limiting table width by subplot one (equal to option ‘value 1’); * ‘=’ for equal width of all cells; * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers. * Option value set the width of the table (default is 1).*/ void MGL_EXPORT mgl_table(HMGL gr, double x, double y, HCDT val, const char *text, const char *fnt, const char *opt); void MGL_EXPORT mgl_table_(uintptr_t *gr, mreal *x, mreal *y, uintptr_t *val, const char *text, const char *fnt, const char *opt,int,int,int); void MGL_EXPORT mgl_tablew(HMGL gr, double x, double y, HCDT val, const wchar_t *text, const char *fnt, const char *opt); /// Draws bitmap (logo) which is stretched along whole axis range void MGL_EXPORT mgl_logo(HMGL gr, long w, long h, const unsigned char *rgba, int smooth, const char *opt); void MGL_EXPORT mgl_logo_file(HMGL gr, const char *fname, int smooth, const char *opt); void MGL_EXPORT mgl_logo_file_(uintptr_t *gr, const char *fname, int *smooth, const char *opt,int l,int n); /// Draws Lamerey diagram for mapping x_new = f(x_old) /** String \a stl may contain: ‘v’ for drawing arrows; ‘~’ for disable 1st segment. * Option value set the number of segments (default is 20).*/ void MGL_EXPORT mgl_lamerey(HMGL gr, double x0, double (*f)(double,void *), void *par, const char *stl, const char *opt); void MGL_EXPORT mgl_lamerey_dat(HMGL gr, double x0, HCDT f, const char *stl, const char *opt); void MGL_EXPORT mgl_lamerey_str(HMGL gr, double x0, const char *f, const char *stl, const char *opt); void MGL_EXPORT mgl_lamerey_dat_(uintptr_t *gr, double *x0, uintptr_t *f, const char *stl, const char *opt, int,int); void MGL_EXPORT mgl_lamerey_str_(uintptr_t *gr, double *x0, const char *f, const char *stl, const char *opt, int,int,int); /// Draws Bifurcation diagram for mapping x_new = f(x_old) in x-axis range /** Option value set the number of stationary points (default is 1024).*/ void MGL_EXPORT mgl_bifurcation(HMGL gr, double dx, double (*f)(double,double,void *), void *par, const char *stl, const char *opt); void MGL_EXPORT mgl_bifurcation_dat(HMGL gr, double dx, HCDT f, const char *stl, const char *opt); void MGL_EXPORT mgl_bifurcation_str(HMGL gr, double dx, const char *f, const char *stl, const char *opt); void MGL_EXPORT mgl_bifurcation_dat_(uintptr_t *gr, double *dx, uintptr_t *f, const char *stl, const char *opt, int,int); void MGL_EXPORT mgl_bifurcation_str_(uintptr_t *gr, double *dx, const char *f, const char *stl, const char *opt, int,int,int); /// Draws Iris plots for determining cross-dependences of data arrays /** NOTE: using the same ranges and empty ids will not draw axis. This will add data to existing Iris plot. * Option value set the size of data labels ids, separated by ';'.*/ void MGL_EXPORT mgl_iris(HMGL gr, HCDT dats, HCDT ranges, const char *ids, const char *stl, const char *opt); void MGL_EXPORT mgl_iris_1(HMGL gr, HCDT dats, const char *ids, const char *stl, const char *opt); void MGL_EXPORT mgl_irisw(HMGL gr, HCDT dats, HCDT ranges, const wchar_t *ids, const char *stl, const char *opt); void MGL_EXPORT mgl_irisw_1(HMGL gr, HCDT dats, const wchar_t *ids, const char *stl, const char *opt); void MGL_EXPORT mgl_iris_(uintptr_t *gr, uintptr_t *dats, uintptr_t *ranges, const char *ids, const char *stl, const char *opt,int l,int m,int n); void MGL_EXPORT mgl_iris_1_(uintptr_t *gr, uintptr_t *dats, const char *ids, const char *stl, const char *opt,int,int,int); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ���������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/vectors.fs����������������������������������������������������������������0000644�0001750�0001750�00000011767�13513030041�017464� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\ Integer vectors library Thu Feb 21 12:46:01 MST 2008 \ Copyright (C) 2008, Sergey Plis \ \ This program is free software; you can redistribute it and/or modify \ it under the terms of the GNU General Public License as published by \ the Free Software Foundation; either version 2 of the License, or \ (at your option) any later version. \ \ This program is distributed in the hope that it will be useful, \ but WITHOUT ANY WARRANTY; without even the implied warranty of \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \ GNU General Public License for more details. \needs float import float \ vector variables better have names ending with "(" for readability Module vectors also float \ fetches | create fetch_operations ' c@ , ' w@ , ' @ , 0 , ' 2@ , ' f@ , \ stores | create store_operations ' c! , ' w! , ' ! , 0 , ' 2! , ' f! , | : type-idx ( cell_size -- idx ) 4 >> ; macro | : f-op ( cell-size -- cfa ) type-idx cells fetch_operations + @ ; | : s-op ( cell-size -- cfa ) type-idx cells store_operations + @ ; : ^)! ( *vector -- addr ) [ 3 cells ] literal - @ ; : ^)@ ( *vector -- addr ) [ 4 cells ] literal - @ ; \ number of elements : )size ( *vector -- size ) [ 1 cells ] literal - @ ; \ set number of elements - useful for temporal size adjustments in \ datastructures such as heaps : )size! ( sz *vector -- ) [ 1 cells ] literal - ! ; \ size of an element in bytes : )type ( *vector -- size ) [ 2 cells ] literal - @ ; : )free ( *vector -- ) [ 4 cells ] literal - free throw ; \ header | fetch_cfa | store_cfa | el_size | #els | \ cell-size in bits \ unnamed vector : _vector ( n cell-size -- addr ) 2dup * [ 4 cells ] literal + allocate throw dup >r over f-op swap ! r@ cell+ over s-op swap ! r@ [ 2 cells ] literal + ! \ cell size store r@ [ 3 cells ] literal + ! \ #els store r> [ 4 cells ] literal + ; \ named vector : vector ( n cell-size -- ) create 2dup * [ 4 cells ] literal + allocate throw dup , dup >r over f-op swap ! r@ cell+ over s-op swap ! r@ [ 2 cells ] literal + ! \ cell size store r@ [ 3 cells ] literal + ! \ #els store r> dup \ erasing the content [ 2 cells ] literal + @ over [ 3 cells ] literal + @ * swap [ 4 cells ] literal + swap erase does> @ [ 4 cells ] literal + ; \ vector of pointers : vector* ( # -- *vector ) cell 8 * _vector ; | : ?idx-in-range ( *vector idx -- 1/0 ) dup rot )size < swap 0>= and ; | : check-range ( *vector idx -- *vector idx | fail ) 2dup ?idx-in-range not abort" Index is out of range! " ; \ addr of ith element of the vector : *) ( *vector i -- addr ) over )type 3 >> * + ; : )@ ( *vector index -- ) [IFDEF] отладка check-range [THEN] over dup ^)@ >r )type 3 >> * + r> execute ; : )! ( value *vector index -- ) [IFDEF] отладка check-range [THEN] over dup ^)! >r )type 3 >> * + r> execute ; \ : test! cell * + ! ; | create print-funcs ' . , ' . , ' . , 0 , ' d. , ' f. , : )print ( *v -- cfa ) )type type-idx cells print-funcs + @ execute ; : )map ( *v xt -- ) swap dup )size 0 do 2dup i )@ swap execute loop 2drop ; : map ( *v -- ) ( word-to-map ) ' swap dup )size 0 do 2dup i )@ swap execute loop 2drop ; : )initperm ( v( -- ) dup )size 0 do dup i swap over )! loop drop ; : ). ( *vector -- ) dup )size 0 do dup i )@ over )print loop drop ; \ does arbitrary vector contain this element ? : )in? ( *v value -- 1/0 ) swap dup )size 0 do 2dup i )@ = if 2drop True unloop exit then loop 2drop False ; : )find ( *v value -- i True/False ) swap dup )size 0 do 2dup i )@ = if 2drop i True unloop exit then loop 2drop False ; : vector->stack ( *v -- n1 n2 .. n# # ) dup )size 0 do dup i )@ swap loop )size ; \ initialized cell vector \ preserve order : ivector* ( n1 n2 .. n# # -- *vector ) dup vector* swap 1- 0 swap do swap over i )! -1 +loop ; \ reversed order : irvector* ( n1 n2 .. n# # -- *vector ) dup vector* swap 0 do swap over i )! loop ; \ does not take care of duplicate elements | : overlap ( v1( v2( -- n1 .. n2 # / 0 ) depth 2- >r dup )size 0 do 2dup i )@ )in? if dup i )@ -rot then loop 2drop depth r> - ; | : notoverlap ( v1( v2( -- n1 .. n2 # ) depth 2- >r dup )size 0 do 2dup i )@ )in? not if dup i )@ -rot then loop 2drop depth r> - ; : )union ( *v1( *v2( -- *v3( ) over >r notoverlap r> swap >r vector->stack r> + dup 0= abort" empty union!" ivector* ; : )intersection ( *v1( *v2( -- *v3(/0 ) overlap dup 0<> if ivector* then ; \ elementwise comparison of two vectors : )= ( *v1( *v2( -- 1/0 ) dup )size >r over )size r> <> if 2drop 0 exit then dup )size 0 do 2dup i )@ swap i )@ <> if 2drop unloop 0 exit then loop 2drop -1 ; : subset? ( *v( *s( -- 1/0 ) 2dup )intersection dup 0= if -rot 2drop exit then dup >r )= swap drop r> )free ; : )clone ( *v -- *cv ) vector->stack ivector* ; : )erase ( *v -- ) dup )size over )type 3 >> * erase ; : _last ( *v -- *v idx-of-last-element ) dup )size 1- ; clear previous Module;���������mathgl-2.4.4/include/mgl2/cont.h��������������������������������������������������������������������0000644�0001750�0001750�00000045330�13513030041�016552� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * cont.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_CONT_H_ #define _MGL_CONT_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Print text along the curve in parametric form {x,y,z} void MGL_EXPORT mgl_text_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *text, const char *font, const char *opt); void MGL_EXPORT mgl_text_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z,const char *text,const char *font, const char *opt,int,int l,int n); void MGL_EXPORT mgl_textw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const wchar_t *text, const char *font, const char *opt); /// Print text along the curve in parametric form {x,y} void MGL_EXPORT mgl_text_xy(HMGL gr, HCDT x, HCDT y, const char *text, const char *font, const char *opt); void MGL_EXPORT mgl_text_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *text, const char *font, const char *opt,int, int l,int n); void MGL_EXPORT mgl_textw_xy(HMGL gr, HCDT x, HCDT y, const wchar_t *text, const char *font, const char *opt); /// Print text along the curve void MGL_EXPORT mgl_text_y(HMGL gr, HCDT y, const char *text, const char *font, const char *opt); void MGL_EXPORT mgl_text_y_(uintptr_t *gr, uintptr_t *y, const char *text, const char *font, const char *opt,int, int l,int n); void MGL_EXPORT mgl_textw_y(HMGL gr, HCDT y, const wchar_t *text, const char *font, const char *opt); void MGL_EXPORT mgl_cont_gen(HMGL gr, double val, HCDT a, HCDT x, HCDT y, HCDT z, const char *stl, const char *opt); void MGL_EXPORT mgl_contf_gen(HMGL gr, double v1, double v2, HCDT a, HCDT x, HCDT y, HCDT z, const char *stl, const char *opt); //void MGL_EXPORT mgl_contv_gen(HMGL gr, double v1, double v2, HCDT a, HCDT x, HCDT y, HCDT z, const char *stl); //void MGL_EXPORT mgl_axial_gen(HMGL gr, double v1, double v2, HCDT a, HCDT x, HCDT y, HCDT z, const char *stl); /// Draw contour lines at manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_cont_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour lines at manual levels for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_cont_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour lines for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_cont_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour lines for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont(HMGL gr, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_cont_(uintptr_t *gr, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours at manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. */ void MGL_EXPORT mgl_contf_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contf_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours at manual levels for 2d data /** Style ‘_’ to draw contours at bottom of axis box. */ void MGL_EXPORT mgl_contf_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contf_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contf_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf(HMGL gr, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contf_(uintptr_t *gr, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours at manual levels for 2d data specified parametrically with specified colors /** Style ‘_’ to draw contours at bottom of axis box. */ void MGL_EXPORT mgl_contd_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contd_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours at manual levels for 2d data with specified colors /** Style ‘_’ to draw contours at bottom of axis box. */ void MGL_EXPORT mgl_contd_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contd_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours for 2d data specified parametrically with specified colors /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contd_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contd_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw solid contours for 2d data with specified colors /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contd(HMGL gr, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contd_(uintptr_t *gr, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour tubes between manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. */ void MGL_EXPORT mgl_contv_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contv_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour tubes between manual levels for 2d data /** Style ‘_’ to draw contours at bottom of axis box. */ void MGL_EXPORT mgl_contv_val(HMGL gr, HCDT v, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contv_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour tubes for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contv_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contv_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour tubes for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contv(HMGL gr, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_contv_(uintptr_t *gr, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour lines on parametric surface at manual levels for 2d data specified parametrically /** Style ‘f’ to draw solid contours. * Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_contp_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_contp_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw contour lines on parametric surface for 2d data specified parametrically /** Style ‘f’ to draw solid contours. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contp(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_contp_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw axial-symmetric isosurfaces at manual levels for 2d data specified parametrically /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */ void MGL_EXPORT mgl_axial_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_axial_xy_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw axial-symmetric isosurfaces at manual levels for 2d data /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */ void MGL_EXPORT mgl_axial_val(HMGL gr, HCDT v, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_axial_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw axial-symmetric isosurfaces for 2d data specified parametrically /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_axial_xy(HMGL gr, HCDT x, HCDT y, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_axial_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw axial-symmetric isosurfaces for 2d data /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_axial(HMGL gr, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_axial_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw surface of curve {r,z} rotation around axis /** Style ‘#’ produce wire plot. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_torus(HMGL gr, HCDT r, HCDT z, const char *col, const char *opt); void MGL_EXPORT mgl_torus_(uintptr_t *gr, uintptr_t *r, uintptr_t *z, const char *pen, const char *opt,int,int); /// Draw grid lines for density plot at slice for 3d data specified parametrically /** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ void MGL_EXPORT mgl_grid3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_grid3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw grid lines for density plot at slice for 3d data /** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ void MGL_EXPORT mgl_grid3(HMGL gr, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_grid3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw density plot at slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ void MGL_EXPORT mgl_dens3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_dens3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw density plot at slice for 3d data /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ void MGL_EXPORT mgl_dens3(HMGL gr, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_dens3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw contour lines at manual levels along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_cont3_xyz_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw contour lines at manual levels along slice for 3d data /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont3_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_cont3_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw contour lines along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_cont3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw contour lines along slice for 3d data /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_cont3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw solid contours at manual levels along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */ void MGL_EXPORT mgl_contf3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_contf3_xyz_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw solid contours at manual levels along slice for 3d data /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */ void MGL_EXPORT mgl_contf3_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_contf3_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw solid contours along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_contf3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); /// Draw solid contours along slice for 3d data /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt); void MGL_EXPORT mgl_contf3_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sVal, const char *opt,int,int); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/base_cf.h�����������������������������������������������������������������0000644�0001750�0001750�00000032070�13513030041�017166� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * base_cf.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_BASE_CF_H_ #define _MGL_BASE_CF_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Check if MathGL version is valid (return 0) or not (return 1) int MGL_EXPORT mgl_check_version(const char *ver); int MGL_EXPORT mgl_check_version_(const char *ver, int); /// Suppress printing warnings to stderr void MGL_EXPORT mgl_suppress_warn(int on); void MGL_EXPORT mgl_suppress_warn_(int *on); /// Get last warning code int MGL_EXPORT_PURE mgl_get_warn(HMGL gr); int MGL_EXPORT_PURE mgl_get_warn_(uintptr_t *gr); /// Set warning code ant fill message void MGL_EXPORT mgl_set_warn(HMGL gr, int code, const char *text); void MGL_EXPORT mgl_set_warn_(uintptr_t *gr, int *code, const char *text,int); /// Get text of warning message(s) MGL_EXPORT_PURE const char *mgl_get_mess(HMGL gr); int MGL_EXPORT mgl_get_mess_(uintptr_t *gr, char *out, int len); /// Set name of plot for saving filename void MGL_EXPORT mgl_set_plotid(HMGL gr, const char *id); void MGL_EXPORT mgl_set_plotid_(uintptr_t *gr, const char *id,int); /// Get name of plot for saving filename MGL_EXPORT_PURE const char *mgl_get_plotid(HMGL gr); int MGL_EXPORT mgl_get_plotid_(uintptr_t *gr, char *out, int len); /// Ask to stop drawing void MGL_EXPORT mgl_ask_stop(HMGL gr, int stop); void MGL_EXPORT mgl_ask_stop_(uintptr_t *gr, int *stop); /// Check if plot termination is asked int MGL_EXPORT mgl_need_stop(HMGL gr); int MGL_EXPORT mgl_need_stop_(uintptr_t *gr); /// Set callback function for event processing void MGL_EXPORT mgl_set_event_func(HMGL gr, void (*func)(void *), void *par); /// Get plot quality int MGL_EXPORT_PURE mgl_get_quality(HMGL gr); int MGL_EXPORT_PURE mgl_get_quality_(uintptr_t *gr); /// Set plot quality /** qual=0 -- no face drawing (fastest), * qual=1 -- no color interpolation (fast), * qual=2 -- high quality (normal), * qual|4 -- direct bitmap drawing (low memory usage); * qual|8 for dots drawing instead of primitives (extremely fast). */ void MGL_EXPORT mgl_set_quality(HMGL gr, int qual); void MGL_EXPORT mgl_set_quality_(uintptr_t *gr, int *qual); /// Set drawing region for Quality&4 void MGL_EXPORT mgl_set_draw_reg(HMGL gr, long nx, long ny, long m); void MGL_EXPORT mgl_set_draw_reg_(uintptr_t *gr, int *nx, int *ny, int *m); /// Check if support of frames is enabled (i.e. MGL_VECT_FRAME is set and Quality&MGL_DRAW_LMEM==0) int MGL_EXPORT_PURE mgl_is_frames(HMGL gr); /// Get bit-value flag of HMGL state (for advanced users only) int MGL_EXPORT_PURE mgl_get_flag(HMGL gr, uint32_t flag); int MGL_EXPORT_PURE mgl_get_flag_(uintptr_t *gr, unsigned long *flag); /// Set bit-value flag of HMGL state (for advanced users only) void MGL_EXPORT mgl_set_flag(HMGL gr, int val, uint32_t flag); void MGL_EXPORT mgl_set_flag_(uintptr_t *gr, int *val, unsigned long *flag); /// Change counter of HMGL uses (for advanced users only). Non-zero counter prevent automatic object removing. long MGL_EXPORT mgl_use_graph(HMGL gr, int inc); long MGL_EXPORT mgl_use_graph_(uintptr_t *gr, int *inc); void MGL_EXPORT mgl_set_rdc_acc(HMGL gr, int reduce); void MGL_EXPORT mgl_set_rdc_acc_(uintptr_t *gr, int *reduce); /// Start group of objects void MGL_EXPORT mgl_start_group(HMGL gr, const char *name); void MGL_EXPORT mgl_start_group_(uintptr_t *gr, const char *name,int); /// End group of objects void MGL_EXPORT mgl_end_group(HMGL gr); void MGL_EXPORT mgl_end_group_(uintptr_t *gr); /// Highlight objects with given id void MGL_EXPORT mgl_highlight(HMGL gr, int id); void MGL_EXPORT mgl_highlight_(uintptr_t *gr, int *id); /// Set default palette void MGL_EXPORT mgl_set_palette(HMGL gr, const char *colors); void MGL_EXPORT mgl_set_palette_(uintptr_t *gr, const char *colors, int); void MGL_EXPORT mgl_set_pal_color_(uintptr_t *gr, int *n, mreal *r, mreal *g, mreal *b); void MGL_EXPORT mgl_set_pal_num_(uintptr_t *gr, int *num); /// Sets RGB values for color with given id void MGL_EXPORT mgl_set_color(char id, double r, double g, double b); void MGL_EXPORT mgl_set_color_(char *id, mreal *r, mreal *g, mreal *b, int); /// Set default color scheme void MGL_EXPORT mgl_set_def_sch(HMGL gr, const char *sch); void MGL_EXPORT mgl_set_def_sch_(uintptr_t *gr, const char *sch,int); /// Set mask for face coloring as array of type 'unsigned char[8]' void MGL_EXPORT mgl_set_mask(char id, const char *mask); void MGL_EXPORT mgl_set_mask_(const char *id, const char *mask,int,int); /// Set mask for face coloring as unsigned long number void MGL_EXPORT mgl_set_mask_val(char id, uint64_t mask); void MGL_EXPORT mgl_set_mask_val_(const char *id, uint64_t *mask,int); /// Set default mask rotation angle void MGL_EXPORT mgl_set_mask_angle(HMGL gr, int angle); void MGL_EXPORT mgl_set_mask_angle_(uintptr_t *gr, int *angle); /// Set default value of alpha-channel void MGL_EXPORT mgl_set_alpha_default(HMGL gr, double alpha); void MGL_EXPORT mgl_set_alpha_default_(uintptr_t *gr, mreal *alpha); /// Set relative width of rectangles in Bars, Barh, BoxPlot, Candle, OHLC (default is 0.7) void MGL_EXPORT mgl_set_bar_width(HMGL gr, double width); void MGL_EXPORT mgl_set_bar_width_(uintptr_t *gr, mreal *width); /// Set number of mesh lines (use 0 to draw all of them) void MGL_EXPORT mgl_set_meshnum(HMGL gr, int num); void MGL_EXPORT mgl_set_meshnum_(uintptr_t *gr, int *num); /// Set number of visible faces (use 0 to draw all of them) void MGL_EXPORT mgl_set_facenum(HMGL gr, int num); void MGL_EXPORT mgl_set_facenum_(uintptr_t *gr, int *num); /// Clear unused points and primitives. Useful only in combination with mgl_set_facenum(). void MGL_EXPORT mgl_clear_unused(HMGL gr); void MGL_EXPORT mgl_clear_unused_(uintptr_t *gr); /// Set ambient light brightness void MGL_EXPORT mgl_set_ambbr(HMGL gr, double i); void MGL_EXPORT mgl_set_ambbr_(uintptr_t *gr, mreal *i); /// Set diffusive light brightness void MGL_EXPORT mgl_set_difbr(HMGL gr, double i); void MGL_EXPORT mgl_set_difbr_(uintptr_t *gr, mreal *i); /// Use diffusive light (only for local light sources) -- OBSOLETE void MGL_EXPORT mgl_set_light_dif(HMGL gr, int enable); void MGL_EXPORT mgl_set_light_dif_(uintptr_t *gr, int *enable); /// Set cutting for points outside of bounding box void MGL_EXPORT mgl_set_cut(HMGL gr, int cut); void MGL_EXPORT mgl_set_cut_(uintptr_t *gr, int *cut); /// Set additional cutting box void MGL_EXPORT mgl_set_cut_box(HMGL gr, double x1,double y1,double z1,double x2,double y2,double z2); void MGL_EXPORT mgl_set_cut_box_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2); /// Set the cutting off condition (formula) void MGL_EXPORT mgl_set_cutoff(HMGL gr, const char *EqC); void MGL_EXPORT mgl_set_cutoff_(uintptr_t *gr, const char *EqC, int); /// Set values of axis range void MGL_EXPORT mgl_set_ranges(HMGL gr, double x1, double x2, double y1, double y2, double z1, double z2); void MGL_EXPORT mgl_set_ranges_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2); /// Set range in direction dir as [v1, v2] void MGL_EXPORT mgl_set_range_val(HMGL gr, char dir, double v1,double v2); void MGL_EXPORT mgl_set_range_val_(uintptr_t *gr, const char *dir, mreal *v1, mreal *v2,int); /// Add [v1, v2] to the current range in direction dir void MGL_EXPORT mgl_add_range_val(HMGL gr, char dir, double v1,double v2); void MGL_EXPORT mgl_add_range_val_(uintptr_t *gr, const char *dir, mreal *v1, mreal *v2,int); /// Set range in direction dir as minimal and maximal values of data a void MGL_EXPORT mgl_set_range_dat(HMGL gr, char dir, HCDT a, int add); void MGL_EXPORT mgl_set_range_dat_(uintptr_t *gr, const char *dir, uintptr_t *a, int *add,int); /// Set ranges for automatic variables void MGL_EXPORT mgl_set_auto_ranges(HMGL gr, double x1, double x2, double y1, double y2, double z1, double z2, double c1, double c2); void MGL_EXPORT mgl_set_auto_ranges_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2, mreal *c1, mreal *c2); /// Set axis range scaling -- simplified way to shift/zoom axis range -- need to redraw whole image! void MGL_EXPORT mgl_zoom_axis(HMGL gr, double x1,double y1,double z1,double c1,double x2,double y2,double z2,double c2); void MGL_EXPORT mgl_zoom_axis_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *z1, mreal *c1, mreal *x2, mreal *y2, mreal *z2, mreal *c2); /// Set axis origin void MGL_EXPORT mgl_set_origin(HMGL gr, double x0, double y0, double z0); void MGL_EXPORT mgl_set_origin_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0); /// Set the transformation formulas for coordinate. Use "" or NULL for built-in ones void MGL_EXPORT mgl_set_func(HMGL gr, const char *EqX,const char *EqY,const char *EqZ,const char *EqA); void MGL_EXPORT mgl_set_func_(uintptr_t *gr, const char *EqX, const char *EqY, const char *EqZ, const char *EqA, int, int, int, int); /// Set one of predefined transformation rule void MGL_EXPORT mgl_set_coor(HMGL gr, int how); void MGL_EXPORT mgl_set_coor_(uintptr_t *gr, int *how); /// Set to draw Ternary axis (triangle like axis, grid and so on) /** val=1 for Ternary axis (a+b+c=1, z=z), * val=2 for Quaternary axis (a+b+c+d=1), * val|4 for projections. */ void MGL_EXPORT mgl_set_ternary(HMGL gr, int kind); void MGL_EXPORT mgl_set_ternary_(uintptr_t *gr, int *kind); /// Set to use or not tick labels rotation void MGL_EXPORT mgl_set_tick_rotate(HMGL gr, int enable); void MGL_EXPORT mgl_set_tick_rotate_(uintptr_t *gr, int *enable); /// Set to use or not tick labels skipping void MGL_EXPORT mgl_set_tick_skip(HMGL gr, int enable); void MGL_EXPORT mgl_set_tick_skip_(uintptr_t *gr, int *enable); /// Set default font for all new HMGL objects void MGL_EXPORT mgl_def_font(const char *name, const char *path); void MGL_EXPORT mgl_def_font_(const char *name, const char *path,int,int); /// Set default size of marks (locally you can use "size" option) void MGL_EXPORT mgl_set_mark_size(HMGL gr, double size); void MGL_EXPORT mgl_set_mark_size_(uintptr_t *gr, mreal *size); /// Set default size of arrows (locally you can use "size" option) void MGL_EXPORT mgl_set_arrow_size(HMGL gr, double size); void MGL_EXPORT mgl_set_arrow_size_(uintptr_t *gr, mreal *size); /// Set default font size void MGL_EXPORT mgl_set_font_size(HMGL gr, double size); void MGL_EXPORT mgl_set_font_size_(uintptr_t *gr, mreal *size); /// Set default font style and color void MGL_EXPORT mgl_set_font_def(HMGL gr, const char *fnt); void MGL_EXPORT mgl_set_font_def_(uintptr_t *gr, const char *fnt, int); /// Set to use or not text rotation void MGL_EXPORT mgl_set_rotated_text(HMGL gr, int enable); void MGL_EXPORT mgl_set_rotated_text_(uintptr_t *gr, int *enable); /// Set to scale text in relative subplots too void MGL_EXPORT mgl_set_scale_text(HMGL gr, int enable); void MGL_EXPORT mgl_set_scale_text_(uintptr_t *gr, int *enable); /// Load font from file void MGL_EXPORT mgl_load_font(HMGL gr, const char *name, const char *path); void MGL_EXPORT mgl_load_font_(uintptr_t *gr, char *name, char *path, int l, int n); /// Copy font from another mglGraph instance void MGL_EXPORT mgl_copy_font(HMGL gr, HMGL gr_from); void MGL_EXPORT mgl_copy_font_(uintptr_t *gr, uintptr_t *gr_from); /// Restore font (load default font for new HMGL objects) void MGL_EXPORT mgl_restore_font(HMGL gr); void MGL_EXPORT mgl_restore_font_(uintptr_t *gr); /// Add user-defined glyph for symbol and set its optional id void MGL_EXPORT mgl_define_symbol(HMGL gr, char id, HCDT x, HCDT y); void MGL_EXPORT mgl_define_symbol_(uintptr_t *gr, char *id, uintptr_t *x, uintptr_t *y,int); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/fit.h���������������������������������������������������������������������0000644�0001750�0001750�00000016611�13513030041�016371� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * fit.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_FIT_H_ #define _MGL_FIT_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------- extern int mglFitPnts; ///< Number of output points in fitting extern char mglFitRes[1024]; ///< Last fitted formula /// Fit data along x-direction for each data row. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_1(HMGL gr, HCDT y, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_1_(uintptr_t* gr, uintptr_t* y, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data along x-, y-directions for each data slice. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_2(HMGL gr, HCDT z, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_2_(uintptr_t* gr, uintptr_t* z, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data along along all directions. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_3(HMGL gr, HCDT a, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_3_(uintptr_t* gr, uintptr_t* a, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data along x-direction for each data row. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_xy(HMGL gr, HCDT x, HCDT y, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_xy_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data along x-, y-directions for each data slice. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_xyz_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data along along all directions. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_xyza(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_xyza_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* a, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_ys(HMGL gr, HCDT y, HCDT s, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_ys_(uintptr_t* gr, uintptr_t* y, uintptr_t* ss, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); HMDT MGL_EXPORT mgl_fit_xys(HMGL gr, HCDT x, HCDT y, HCDT s, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_xys_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* ss, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Fit data with dispersion s along x-, y-directions for each data slice. Return array with values for found formula. HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT s, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_xyzs_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* ss, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT s, const char *eq, const char *vars, HMDT ini, const char *opt); uintptr_t MGL_EXPORT mgl_fit_xyzas_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* a, uintptr_t* ss, const char *eq, const char *vars, uintptr_t *ini, const char *opt,int, int l, int n); /// Get last fitted formula MGL_EXPORT_CONST const char *mgl_get_fit(HMGL gr); int MGL_EXPORT mgl_get_fit_(uintptr_t *gr, char *out, int len); /// Make histogram (distribution) of data. This function do not plot data. /** Option "value" sets the size of output array (default is mglFitPnts=100). */ HMDT MGL_EXPORT mgl_hist_x(HMGL gr, HCDT x, HCDT a, const char *opt); uintptr_t MGL_EXPORT mgl_hist_x_(uintptr_t* gr, uintptr_t* x, uintptr_t* a, const char *opt,int); /// Make histogram (distribution) of data. This function do not plot data. /** Option "value" sets the size of output array (default is mglFitPnts=100). */ HMDT MGL_EXPORT mgl_hist_xy(HMGL gr, HCDT x, HCDT y, HCDT a, const char *opt); uintptr_t MGL_EXPORT mgl_hist_xy_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* a, const char *opt,int); /// Make histogram (distribution) of data. This function do not plot data. /** Option "value" sets the size of output array (default is mglFitPnts=100). */ HMDT MGL_EXPORT mgl_hist_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *opt); uintptr_t MGL_EXPORT mgl_hist_xyz_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, uintptr_t* z, uintptr_t* a, const char *opt,int); /// Print fitted last formula (with coefficients) void MGL_EXPORT mgl_puts_fit(HMGL gr, double x, double y, double z, const char *prefix, const char *font, double size); void MGL_EXPORT mgl_puts_fit_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, const char *prefix, const char *font, mreal *size, int l, int n); /// Get chi for last fitted formula mreal MGL_EXPORT_PURE mgl_get_fit_chi(); mreal MGL_EXPORT_PURE mgl_get_fit_chi_(); /// Get covariance matrix for last fitted formula HCDT MGL_EXPORT_CONST mgl_get_fit_covar(); uintptr_t MGL_EXPORT_CONST mgl_get_fit_covar_(); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif �����������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/wnd_cf.h������������������������������������������������������������������0000644�0001750�0001750�00000012412�13513030041�017042� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * wnd_cf.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MGL_WND_CF_H #define MGL_WND_CF_H #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------- /// Callback function for mouse click void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p)); #if MGL_HAVE_PTHR_WIDGET /// Mutex for lock/unlock by widget void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex); #endif /// Make custom dialog for parameters ids of element properties defined by args void MGL_EXPORT mgl_wnd_make_dialog(HMGL gr, const char *ids, char const * const *args, const char *title); /// Set callback functions for drawing and data reloading void MGL_EXPORT mgl_wnd_set_func(HMGL gr, int (*draw)(HMGL gr, void *p), void *par, void (*reload)(void *p)); /// Set callback functions for setting properties void MGL_EXPORT mgl_wnd_set_prop(HMGL gr, void (*prop)(char id, const char *val, void *p), void *par); /// Set delay for animation in seconds void MGL_EXPORT mgl_wnd_set_delay(HMGL gr, double dt); void MGL_EXPORT mgl_wnd_set_delay_(uintptr_t *gr, mreal *dt); /// Get delay for animation in seconds double MGL_EXPORT_PURE mgl_wnd_get_delay(HMGL gr); double MGL_EXPORT_PURE mgl_wnd_get_delay_(uintptr_t *gr); /// Set window properties void MGL_EXPORT mgl_setup_window(HMGL gr, int clf_upd, int showpos); void MGL_EXPORT mgl_setup_window_(uintptr_t *gr, int *clf_upd, int *showpos); /// Switch on/off transparency (do not overwrite user settings) void MGL_EXPORT mgl_wnd_toggle_alpha(HMGL gr); void MGL_EXPORT mgl_wnd_toggle_alpha_(uintptr_t *gr); /// Switch on/off lighting (do not overwrite user settings) void MGL_EXPORT mgl_wnd_toggle_light(HMGL gr); void MGL_EXPORT mgl_wnd_toggle_light_(uintptr_t *gr); /// Switch on/off zooming by mouse void MGL_EXPORT mgl_wnd_toggle_zoom(HMGL gr); void MGL_EXPORT mgl_wnd_toggle_zoom_(uintptr_t *gr); /// Switch on/off rotation by mouse void MGL_EXPORT mgl_wnd_toggle_rotate(HMGL gr); void MGL_EXPORT mgl_wnd_toggle_rotate_(uintptr_t *gr); /// Switch off all zooming and rotation void MGL_EXPORT mgl_wnd_toggle_no(HMGL gr); void MGL_EXPORT mgl_wnd_toggle_no_(uintptr_t *gr); /// Update picture by calling user drawing function void MGL_EXPORT mgl_wnd_update(HMGL gr); void MGL_EXPORT mgl_wnd_update_(uintptr_t *gr); /// Reload user data and update picture void MGL_EXPORT mgl_wnd_reload(HMGL gr); void MGL_EXPORT mgl_wnd_reload_(uintptr_t *gr); /// Adjust size of bitmap to window size void MGL_EXPORT mgl_wnd_adjust(HMGL gr); void MGL_EXPORT mgl_wnd_adjust_(uintptr_t *gr); /// Show next frame (if one) void MGL_EXPORT mgl_wnd_next_frame(HMGL gr); void MGL_EXPORT mgl_wnd_next_frame_(uintptr_t *gr); /// Show previous frame (if one) void MGL_EXPORT mgl_wnd_prev_frame(HMGL gr); void MGL_EXPORT mgl_wnd_prev_frame_(uintptr_t *gr); /// Run slideshow (animation) of frames void MGL_EXPORT mgl_wnd_animation(HMGL gr); void MGL_EXPORT mgl_wnd_animation_(uintptr_t *gr); /// Get last mouse position void MGL_EXPORT mgl_get_last_mouse_pos(HMGL gr, mreal *x, mreal *y, mreal *z); void MGL_EXPORT mgl_get_last_mouse_pos_(uintptr_t *gr, mreal *x, mreal *y, mreal *z); /// Return pointer to widget (Fl_Window* or QMainWindow*) used for plotting MGL_EXPORT void *mgl_wnd_window(HMGL gr); /// Return pointer to widget (Fl_MGLView* or QMathGL*) used for plotting MGL_EXPORT void *mgl_wnd_widget(HMGL gr); /// Move window to given position void MGL_EXPORT mgl_wnd_move(HMGL gr, int x, int y); void MGL_EXPORT mgl_wnd_move_(uintptr_t *gr, int *x, int *y); /// Change window sizes void MGL_EXPORT mgl_wnd_size(HMGL gr, int w, int h); void MGL_EXPORT mgl_wnd_size_(uintptr_t *gr, int *w, int *h); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/mgl_pas.pas���������������������������������������������������������������0000644�0001750�0001750�00000364520�13513030041�017572� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//************************************************************************** // mgl_pas.pas is part of Math Graphic Library * // Copyright (C) 2008-2013 Mikhail Barg, Alexey Balakin * // * // This program is free software; you can redistribute it and/or modify * // it under the terms of the GNU Library General Public License as * // published by the Free Software Foundation; either version 2 of the * // License, or (at your option) any later version. * // * // This program is distributed in the hope that it will be useful, * // but WITHOUT ANY WARRANTY; without even the implied warranty of * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * // GNU General Public License for more details. * // * // You should have received a copy of the GNU Library General Public * // License along with this program; if not, write to the * // Free Software Foundation, Inc., * // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * //************************************************************************** unit mgl_pas; {$IFDEF FPC} {$MODE DELPHI } {$PACKENUM 4} (* use 4-byte enums *) {$PACKRECORDS C} (* C/C++-compatible record packing *) {$ELSE} {$MINENUMSIZE 4} (* use 4-byte enums *) {$ENDIF} {$IFDEF DARWIN} {$linklib libmgl} {$ENDIF} interface uses {$IFDEF MSWINDOWS} Windows, Graphics, {$ENDIF} Math; const MGL_VER2 = 2.2; //* This define enables double precision in MathGL */ MGL_USE_DOUBLE = 1; const {$IFDEF MSWINDOWS} //win - .dll libmgl = 'libmgl.dll'; libmglglut = 'libmgl-glut.dll'; libmglfltk = 'libmgl-fltk.dll'; libmglqt = 'libmgl-qt.dll'; {$ELSE} {$IFDEF LINUX} //linux - .so libmgl = 'libmgl.so'; libmglglut = 'libmgl-glut.so'; libmglfltk = 'libmgl-fltk.so'; libmglqt = 'libmgl-qt.so'; {$ELSE} {$IFDEF DARWIN} //darwin - .dylib libmgl = 'libmgl.dylib'; libmglglut = 'libmgl-glut.dylib'; libmglfltk = 'libmgl-fltk.dylib'; libmglqt = 'libmgl-qt.dylib'; {$ELSE} // other platforms? {$ENDIF} {$ENDIF} {$ENDIF} {$IF (MGL_USE_DOUBLE = 0)} type mreal = double; {$ELSE} type mreal = real; {$IFEND} {$IFDEF FPC} {$ELSE} type QWord = Int64; {$ENDIF} Pmreal = ^mreal; type TNGLDraw = record end; type TMGLGraph = record end; type TMGLData = record end; type TMGLParse = record end; type TMGLFormula = record end; type TMGLFormulaC = record end; type TMGLDataC = record end; type HMDR = ^TNGLDraw; type HMGL = ^TMGLGraph; type HMDT = ^TMGLData; type HMPR = ^TMGLParse; type PPChar = ^PChar; type HMEX = ^TMGLFormula; type HAEX = ^TMGLFormulaC; type HADT = ^TMGLDataC; type Preal = ^single; type Pdouble = ^double; type Pint = ^integer; type dual = record re, im: mreal; end; type Pdual = ^dual; type TGSLVector = record end; type TGSLMatrix = record end; type PGSLVector = ^TGSLVector; type PGSLMatrix = ^TGSLMatrix; type TMglDrawFunction = function (gr: HMGL; p: pointer): integer; cdecl; function mgl_create_graph_gl(): HMGL; cdecl; external libmgl; function mgl_create_graph_glut(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglglut; function mgl_create_graph_fltk(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglfltk; procedure mgl_fltk_run(); cdecl; external libmglfltk; function mgl_create_graph_qt(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglqt; procedure mgl_qt_run(); cdecl; external libmglqt; {== ../../include/mgl2/abstract.h ==} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /// Set seed for random numbers procedure mgl_srnd(seed: integer); cdecl; external libmgl; /// Get random number function mgl_rnd(): double; cdecl; external libmgl; /// Set name for data variable (can be used in mgl_formula_calc() or in MGL scripts) procedure mgl_data_set_name(dat: HMDT;const name: PChar); cdecl; external libmgl; procedure mgl_data_set_name_w(dat: HMDT;const name: PWideChar); cdecl; external libmgl; /// Set callback function which is called at deleting variable /// Save whole data array (for ns=-1) or only ns-th slice to text file procedure mgl_data_save(const dat: HMDT;const fname: PChar;ns: integer); cdecl; external libmgl; /// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme procedure mgl_data_export(const dat: HMDT;const fname: PChar;const scheme: PChar;v1: mreal;v2: mreal;ns: integer); cdecl; external libmgl; /// Save data to HDF file procedure mgl_data_save_hdf(const d: HMDT;const fname: PChar;const data: PChar;rewrite: integer); cdecl; external libmgl; /// Get information about the data (sizes and momentum) to string function mgl_data_info(const dat: HMDT): PChar; cdecl; external libmgl; /// Put HDF data names into buf as '\t' separated. function mgl_datas_hdf(const fname: PChar;buf: PChar;size: integer): integer; cdecl; external libmgl; /// Get maximal value of the data function mgl_data_max(const dat: HMDT): mreal; cdecl; external libmgl; /// Get maximal value of the data which is less than 0 function mgl_data_neg_max(const dat: HMDT): mreal; cdecl; external libmgl; /// Get minimal value of the data function mgl_data_min(const dat: HMDT): mreal; cdecl; external libmgl; /// Get minimal value of the data which is larger than 0 function mgl_data_pos_min(const dat: HMDT): mreal; cdecl; external libmgl; /// Find position (after specified in i,j,k) of first nonzero value of formula function mgl_data_first(const dat: HMDT;const cond: PChar;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl; /// Find position (before specified in i,j,k) of last nonzero value of formula function mgl_data_last(const dat: HMDT;const cond: PChar;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl; /// Find position of first in direction 'dir' nonzero value of formula function mgl_data_find(const dat: HMDT;const cond: PChar;dir: char;i: integer;j: integer;k: integer): integer; cdecl; external libmgl; /// Find if any nonzero value of formula function mgl_data_find_any(const dat: HMDT;const cond: PChar): integer; cdecl; external libmgl; /// Get maximal value of the data and its position function mgl_data_max_int(const dat: HMDT;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl; /// Get maximal value of the data and its approximated position function mgl_data_max_real(const dat: HMDT;x: Pmreal;y: Pmreal;z: Pmreal): mreal; cdecl; external libmgl; /// Get minimal value of the data and its position function mgl_data_min_int(const dat: HMDT;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl; /// Get minimal value of the data and its approximated position function mgl_data_min_real(const dat: HMDT;x: Pmreal;y: Pmreal;z: Pmreal): mreal; cdecl; external libmgl; /// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis function mgl_data_momentum_val(const d: HMDT;dir: char;m: Pmreal;w: Pmreal;s: Pmreal;k: Pmreal): mreal; cdecl; external libmgl; //----------------------------------------------------------------------------- /// Callback function for asking user a question. Result shouldn't exceed 1024. //----------------------------------------------------------------------------- /// Abstract class for data array // { return i>0 ? (i0 ? (j0 ? (k= IF BEGIN .w SI ) DX mov 2 # SI add CX dec DX AX *2 I) AX lea 0< UNTIL THEN & Hashbits A#) CX mov AX DX mov AX shr DX AX add & Hashlen A#) CX mov CX dec CX AX and DX pop ret | Code Hash ( string -- key ) R: SI push AX SI mov (hash rel) call SI pop Next end-code also dos also complex also float also atlas also vectors s" libptcblas.so" getlib 0<> [IF] library libblas libptcblas.so depends libatlas [ELSE] library libblas libcblas.so depends libatlas [THEN] library libgsl libgsl.so.0 depends libblas legacy off \ some functions libgsl gsl_log1p df (fp) gsl_log1p ( df -- df ) libgsl gsl_acosh df (fp) gsl_acosh ( df -- df ) \ error handling Wed Sep 21 23:04:06 MDT 2005 libgsl gsl_set_error_handler ptr (int) gsl_set_error_handler ( function -- function ) libgsl gsl_strerror int (ptr) gsl_strerror callback 4:0 (void) int int int int callback; : cstr-fstr ( addr -- addr len ) 0 begin 2dup + c@ 0 = not while 1+ repeat ; | : .bold-red ." " ; | : .red ." " ; | : .reset ." " ; | : cb-test cr \ .bold-red ." GSL ERROR: " cr \ .reset cr 10 spaces gsl_strerror cstr-fstr type cr drop \ ." at line: " . cr drop \ ." of file: " cstr-fstr type cr 10 spaces cstr-fstr type cr \ .red -1 abort" failed at" ; ' cb-test 4:0 c_plus \ 1 2 c_plus 2:1call . | variable old_handler c_plus gsl_set_error_handler old_handler ! 0 Constant GSL_SUCCESS \ random number generation Mon Sep 12 22:06:01 MDT 2005 libgsl gsl_rng_types_setup (ptr) gsl_rng_types_setup ( -- *gsl_rng_type) libgsl gsl_rng_env_setup (ptr) gsl_rng_env_setup ( -- *gsl_rng) libgsl gsl_rng_alloc int (int) gsl_rng_alloc ( *gsl_rng_type -- *gsl_rng ) libgsl gsl_rng_name int (int) gsl_rng_name ( *gsl_rng -- string ) libgsl gsl_rng_set int int (void) gsl_rng_set ( *gsl_rng int -- ) libgsl gsl_rng_uniform int (fp) gsl_rng_uniform ( *gsl_rng -- df ) libgsl gsl_rng_uniform_pos int (fp) gsl_rng_uniform_pos ( *gsl_rng -- df ) libgsl gsl_rng_uniform_int int int (int) gsl_rng_uniform_int ( *gsl_rng n --n ) libgsl gsl_rng_get int (int) gsl_rng_get ( *gsl_rng -- int ) libgsl gsl_rng_max int (int) gsl_rng_max ( *gsl_rng -- int ) libgsl gsl_rng_min int (int) gsl_rng_min ( *gsl_rng -- int ) libgsl gsl_rng_clone int (int) gsl_rng_clone ( *gsl_rng -- *gsl_rng ) libgsl gsl_rng_free int (int) gsl_rng_free ( *gsl_rng -- ) \ random number distributions Tue Sep 13 00:44:35 MDT 2005 \ Gaussian libgsl gsl_ran_gaussian df int (fp) gsl_ran_gaussian ( *gsl_rng df -- df ) libgsl gsl_ran_gaussian_ratio_method df int (fp) gsl_ran_gaussian_ratio_method ( *gsl_rng df -- df ) libgsl gsl_ran_gaussian_pdf df df (fp) gsl_ran_gaussian_pdf ( df df -- df ) \ sigma = 1 libgsl gsl_ran_ugaussian int (fp) gsl_ran_ugaussian ( *gsl_rng -- df ) libgsl gsl_ran_ugaussian_ratio_method int (fp) gsl_ran_ugaussian_ratio_method ( *gsl_rng -- df ) libgsl gsl_ran_ugaussian_pdf df (fp) gsl_ran_ugaussian_pdf ( df df -- df ) libgsl gsl_ran_discrete_preproc int int (int) gsl_ran_discrete_preproc ( int int -- int ) libgsl gsl_ran_discrete int int (int) gsl_ran_discrete libgsl gsl_ran_discrete_free int (void) gsl_ran_discrete_free libgsl gsl_ran_shuffle int int ptr ptr (void) gsl_ran_shuffle \ cdf P(x) = \int_{-\infty}^{x} p(x)dx Q(x) = \int_{x}^{\infty} p(x)dx libgsl gsl_cdf_gaussian_P df df (fp) gsl_cdf_gaussian_P ( df df -- df ) libgsl gsl_cdf_gaussian_Q df df (fp) gsl_cdf_gaussian_Q ( df df -- df ) libgsl gsl_cdf_gaussian_Pinv df df (fp) gsl_cdf_gaussian_Pinv ( df df -- df ) libgsl gsl_cdf_gaussian_Qinv df df (fp) gsl_cdf_gaussian_Qinv ( df df -- df ) \ sigma = 1 cdf libgsl gsl_cdf_ugaussian_P df (fp) gsl_cdf_ugaussian_P ( df -- df ) libgsl gsl_cdf_ugaussian_Q df (fp) gsl_cdf_ugaussian_Q ( df -- df ) libgsl gsl_cdf_ugaussian_Pinv df (fp) gsl_cdf_ugaussian_Pinv ( df -- df ) libgsl gsl_cdf_ugaussian_Qinv df (fp) gsl_cdf_ugaussian_Qinv ( df -- df ) \ statistics Tue Sep 13 01:17:35 MDT 2005 libgsl gsl_stats_mean int int int (fp) gsl_stats_mean ( array{ step size -- df ) libgsl gsl_stats_variance int int int (fp) gsl_stats_variance ( array{ step size -- df ) libgsl gsl_stats_variance_m df int int int (fp) gsl_stats_variance_m ( df array{ step size -- df ) libgsl gsl_stats_sd int int int (fp) gsl_stats_sd ( array{ step size -- df ) libgsl gsl_stats_sd_m df int int int (fp) gsl_stats_sd_m ( df array{ step size -- df ) libgsl gsl_stats_skew int int int (fp) gsl_stats_skew ( array{ step size -- df ) libgsl gsl_stats_kurtosis int int int (fp) gsl_stats_kurtosis ( array{ step size -- df ) libgsl gsl_stats_lag1_autocorrelation int int int (fp) gsl_stats_lag1_autocorrelation ( array{ step size -- df ) libgsl gsl_stats_max int int int (fp) gsl_stats_max ( array{ step size -- df ) libgsl gsl_stats_min int int int (fp) gsl_stats_min ( array{ step size -- df ) libgsl gsl_stats_max_index int int int (int) gsl_stats_max_index ( array{ step size -- n ) libgsl gsl_stats_min_index int int int (int) gsl_stats_min_index ( array{ step size -- n ) \ vectors and matrices Wed Sep 14 00:15:36 MDT 2005 \ Vectors libgsl gsl_block_alloc int (int) gsl_block_alloc ( n -- addr ) libgsl gsl_block_calloc int (int) gsl_block_calloc ( n -- addr ) libgsl gsl_block_free int (int) gsl_block_free ( n -- addr ) libgsl gsl_vector_alloc int (int) gsl_vector_alloc ( n -- addr ) libgsl gsl_vector_calloc int (int) gsl_vector_calloc ( n -- addr ) libgsl gsl_vector_alloc_from_vector int int int ptr (int) gsl_vector_alloc_from_vector libgsl gsl_vector_free int (void) gsl_vector_free ( addr -- ) libgsl gsl_vector_get int int (fp) gsl_vector_get ( addr i -- df ) libgsl gsl_vector_set df int int (void/fp) gsl_vector_set ( df addr i -- ) libgsl gsl_vector_set_all df int (void) gsl_vector_set_all ( df addr -- ) libgsl gsl_vector_set_zero int (void) gsl_vector_set_zero ( addr -- ) libgsl gsl_vector_memcpy int int (int) gsl_vector_memcpy ( dest_addr src_addr -- n ) libgsl gsl_vector_add int int (int) gsl_vector_add ( addr addr -- n ) libgsl gsl_vector_sub int int (int) gsl_vector_sub ( addr addr -- n ) libgsl gsl_vector_mul int int (int) gsl_vector_mul ( addr addr -- n ) libgsl gsl_vector_div int int (int) gsl_vector_div ( addr addr -- n ) libgsl gsl_vector_scale df int (int) gsl_vector_scale ( df addr -- n ) libgsl gsl_vector_add_constant df int (int) gsl_vector_add_constant ( df addr -- n ) libgsl gsl_vector_max int (fp) gsl_vector_max ( addr -- df ) libgsl gsl_vector_min int (fp) gsl_vector_min ( addr -- df ) libgsl gsl_vector_max_index int (fp) gsl_vector_max_index ( addr -- df ) libgsl gsl_vector_min_index int (fp) gsl_vector_min_index ( addr -- df ) libgsl gsl_vector_subvector int int int (int) gsl_vector_subvector \ Vector properties libgsl gsl_vector_isnull ptr (int) gsl_vector_isnull libgsl gsl_vector_ispos ptr (int) gsl_vector_ispos libgsl gsl_vector_isneg ptr (int) gsl_vector_isneg \ permutations libgsl gsl_permutation_alloc int (int) gsl_permutation_alloc ( n -- *gsl_prm) libgsl gsl_permutation_calloc int (int) gsl_permutation_calloc ( n -- *gsl_prm) libgsl gsl_permutation_init int (void) gsl_permutation_init ( *gsl_prm -- ) libgsl gsl_permutation_free int (void) gsl_permutation_free ( *gsl_prm -- ) libgsl gsl_permutation_get int int (int) gsl_permutation_get ( *gsl_prm i -- n) \ Matrices \ Allocation libgsl gsl_matrix_alloc int int (int) gsl_matrix_alloc libgsl gsl_matrix_calloc int int (int) gsl_matrix_calloc libgsl gsl_matrix_alloc_from_block [ 5 ] ints (int) gsl_matrix_alloc_from_block libgsl gsl_matrix_alloc_from_matrix [ 5 ] ints (int) gsl_matrix_alloc_from_matrix libgsl gsl_matrix_free ( *gsl_matrix -- ) int (void) gsl_matrix_free \ Accessing matrix elements libgsl gsl_matrix_get int int int (fp) gsl_matrix_get ( *m i j -- df ) libgsl gsl_matrix_set df int int int (void) gsl_matrix_set ( df *m i j -- ) libgsl gsl_matrix_ptr int int int (int) gsl_matrix_ptr ( *m i j -- *[i,j] ) \ Initializing matrix elements libgsl gsl_matrix_set_all df int (void) gsl_matrix_set_all ( *m df -- n ) libgsl gsl_matrix_set_zero df int (void) gsl_matrix_set_zero ( *m df -- n ) libgsl gsl_matrix_set_identity df int (void) gsl_matrix_set_identity ( *m df -- n ) \ Reading and writing matrices libgsl gsl_matrix_fwrite ptr ptr (int) gsl_matrix_fwrite libgsl gsl_matrix_fread ptr ptr (int) gsl_matrix_fread libgsl gsl_matrix_fprintf ptr ptr ptr (int) gsl_matrix_fprintf libgsl gsl_matrix_fscanf ptr ptr (int) gsl_matrix_fscanf \ Copying matrices libgsl gsl_matrix_memcpy int int (int) gsl_matrix_memcpy ( *m *m -- n ) libgsl gsl_matrix_swap int int (int) gsl_matrix_swap ( *m *m -- n ) \ Copying Rows and columns libgsl gsl_matrix_get_row int int int (int) gsl_matrix_get_row libgsl gsl_matrix_set_row int int int (int) gsl_matrix_set_row libgsl gsl_matrix_get_col int int int (int) gsl_matrix_get_col libgsl gsl_matrix_set_col int int int (int) gsl_matrix_set_col \ Exchanging rows and columns libgsl gsl_matrix_swap_rows int int ptr (int) gsl_matrix_swap_rows libgsl gsl_matrix_swap_columns int int ptr (int) gsl_matrix_swap_columns libgsl gsl_matrix_swap_rowcol int int ptr (int) gsl_matrix_swap_rowcol libgsl gsl_matrix_transpose_memcpy int int (int) gsl_matrix_transpose_memcpy libgsl gsl_matrix_transpose int (int) gsl_matrix_transpose \ Matrix operations libgsl gsl_matrix_add int int (int) gsl_matrix_add libgsl gsl_matrix_sub int int (int) gsl_matrix_sub libgsl gsl_matrix_mul_elements int int (int) gsl_matrix_mul_elements libgsl gsl_matrix_div_elements int int (int) gsl_matrix_div_elements libgsl gsl_matrix_scale df int (int) gsl_matrix_scale libgsl gsl_matrix_add_constant df int (int) gsl_matrix_add_constant \ Finding maximum and minimum elements of matrices libgsl gsl_matrix_max ptr (fp) gsl_matrix_max libgsl gsl_matrix_min ptr (fp) gsl_matrix_min libgsl gsl_matrix_minmax ptr ptr ptr (void) gsl_matrix_minmax libgsl gsl_matrix_min_index ptr ptr ptr (void) gsl_matrix_min_index libgsl gsl_matrix_max_index ptr ptr ptr (void) gsl_matrix_max_index libgsl gsl_matrix_minmax_index ptr ptr ptr ptr ptr (void) gsl_matrix_minmax_index \ Matrix properties libgsl gsl_matrix_isnull ptr (int) gsl_matrix_isnull libgsl gsl_matrix_ispos ptr (int) gsl_matrix_ispos libgsl gsl_matrix_isneg ptr (int) gsl_matrix_isneg \ libgsl gsl_matrix_isnonneg ptr (int) gsl_matrix_isnonneg libgsl gsl_matrix_submatrix int int int int int (int) gsl_matrix_submatrix ( *gsl_matrix k1 k2 n1 n2 -- n ) libgsl gsl_matrix_row int int (int) gsl_matrix_row ( *gsl_matrix idx -- *gsl_vector ) libgsl gsl_matrix_column int int (int) gsl_matrix_column ( *gsl_matrix idx -- *gsl_vector ) libgsl gsl_matrix_diagonal int (int) gsl_matrix_diagonal ( *gsl_matrix -- *gsl_vector ) \ BLAS Wed Sep 14 16:10:34 MDT 2005 \ libblas cblas_dgemm int int df int int int \ int df int int int int int int (void/fp) cblas_dgemm libblas cblas_dgemv int int int int df int int df int int int int (void/fp) cblas_dgemv libgsl gsl_blas_ddot int int int (int) gsl_blas_ddot ( *gsl_vector *gsl_vector df -- n ) libgsl gsl_blas_dgemm int df int int df int int (int/fp) gsl_blas_dgemm libgsl gsl_blas_dger int int int df (int/fp) gsl_blas_dger ( alpha *gsl_vector *gsl_vector *gsl_matrix -- n ) ( A=\alpha x y^T+A ) libgsl gsl_blas_dgemv int df int int df int (int/fp) gsl_blas_dgemv ( n alpha *gsl_matrix *gsl_vector beta *gsl_vector -- n ) \ Linear ALgebra Wed Sep 14 13:39:22 MDT 2005 libgsl gsl_linalg_LU_decomp int int int (int) gsl_linalg_LU_decomp ( *gsl_matrix *gsl_permutation *variable -- n ) libgsl gsl_linalg_LU_invert int int int (int) gsl_linalg_LU_invert ( *gsl_matrix *gsl_permutation *gsl_matrix -- n ) libgsl gsl_linalg_SV_decomp int int int int (int) gsl_linalg_SV_decomp ( *gsl_matrix *gsl_matrix *gsl_vector *gsl_vector -- n ) libgsl gsl_linalg_SV_decomp_mod int int int int int (int) gsl_linalg_SV_decomp_mod ( *gsl_matrix *gsl_matrix *gsl_matrix *gsl_vector *gsl_vector -- n ) \ ----------------------------------------------------------------------------- \ *** Ordinary Differential Equations *** \ --- ODE system struct{ cell func \ (* function) \ (double t, const double y[], double dydt[], void * params); cell jac \ (* jacobian) \ (double t, const double y[], double * dfdy, double dfdt[], \ void * params); cell dim \ dimension; cell params \ * params; } gsl_odeiv_system \ constants related to ODE 1 constant GSL_ODEIV_HADJ_INC 0 constant GSL_ODEIV_HADJ_NIL -1 constant GSL_ODEIV_HADJ_DEC callback gsl_odeiv_func4:1 (int) df int int int callback; callback gsl_odeiv_jac5:1 (int) df int int int int callback; \ --- Stepping Functions libgsl gsl_odeiv_step_alloc ptr int (ptr) gsl_odeiv_step_alloc ( *step_type int -- *step ) libgsl gsl_odeiv_step_reset ptr (int) gsl_odeiv_step_reset ( *step -- r ) libgsl gsl_odeiv_step_free ptr (void) gsl_odeiv_step_free ( *step -- ) libgsl gsl_odeiv_step_name ptr (ptr) gsl_odeiv_step_name ( *step -- *str0 ) libgsl gsl_odeiv_step_order ptr (int) gsl_odeiv_step_order ( *step -- order) libgsl gsl_odeiv_step_apply int int int int int df df int (int) gsl_odeiv_step_apply ( -- ) \ --- Available algorithms libgsl _gsl_odeiv_step_rk2 (int) gsl_odeiv_step_rk2 libgsl _gsl_odeiv_step_rk4 (int) gsl_odeiv_step_rk4 libgsl _gsl_odeiv_step_rkf45 (int) gsl_odeiv_step_rkf45 libgsl _gsl_odeiv_step_rkck (int) gsl_odeiv_step_rkck libgsl _gsl_odeiv_step_rk8pd (int) gsl_odeiv_step_rk8pd libgsl _gsl_odeiv_step_rk2imp (int) gsl_odeiv_step_rk2imp libgsl _gsl_odeiv_step_rk4imp (int) gsl_odeiv_step_rk4imp libgsl _gsl_odeiv_step_bsimp (int) gsl_odeiv_step_bsimp libgsl _gsl_odeiv_step_gear1 (int) gsl_odeiv_step_gear1 libgsl _gsl_odeiv_step_gear2 (int) gsl_odeiv_step_gear2 : gsl_odeiv_step_rk2 [func'] _gsl_odeiv_step_rk2 @ ; : gsl_odeiv_step_rk4 [func'] _gsl_odeiv_step_rk4 @ ; : gsl_odeiv_step_rkf45 [func'] _gsl_odeiv_step_rkf45 @ ; : gsl_odeiv_step_rkck [func'] _gsl_odeiv_step_rkck @ ; : gsl_odeiv_step_rk8pd [func'] _gsl_odeiv_step_rk8pd @ ; : gsl_odeiv_step_rk2imp [func'] _gsl_odeiv_step_rk2imp @ ; : gsl_odeiv_step_rk4imp [func'] _gsl_odeiv_step_rk4imp @ ; : gsl_odeiv_step_bsimp [func'] _gsl_odeiv_step_bsimp @ ; : gsl_odeiv_step_gear1 [func'] _gsl_odeiv_step_gear1 @ ; : gsl_odeiv_step_gear2 [func'] _gsl_odeiv_step_gear2 @ ; \ --- Adaptive Step-size Control libgsl gsl_odeiv_control_standard_new df df df df (ptr) gsl_odeiv_control_standard_new ( a_dydt a_y eps_rel eps_abs -- *control ) libgsl gsl_odeiv_control_y_new df df (int) gsl_odeiv_control_y_new ( eps_abs eps_rel -- *control ) libgsl gsl_odeiv_control_yp_new df df (ptr) gsl_odeiv_control_yp_new ( eps_abs eps_rel -- *control ) libgsl gsl_odeiv_control_free ptr (void) gsl_odeiv_control_free ( *control -- ) libgsl gsl_odeiv_control_name ptr (ptr) gsl_odeiv_control_name ( *c -- *str0 ) \ --- Evolution libgsl gsl_odeiv_evolve_alloc int (int) gsl_odeiv_evolve_alloc ( #dimensions -- evolution_func ) libgsl gsl_odeiv_evolve_apply int int df int int int int int (int) gsl_odeiv_evolve_apply ( -- ) libgsl gsl_odeiv_evolve_reset ptr (int) gsl_odeiv_evolve_reset ( *e -- r ) libgsl gsl_odeiv_evolve_free ptr (void) gsl_odeiv_evolve_free ( *e -- ) \ ----------------------------------------------------------------------------- \ *** Fast Fourier Transform *** \ -- real libgsl gsl_fft_real_wavetable_alloc int (ptr) gsl_fft_real_wavetable_alloc libgsl gsl_fft_real_wavetable_free ptr (void) gsl_fft_real_wavetable_free libgsl gsl_fft_real_workspace_alloc int (ptr) gsl_fft_real_workspace_alloc libgsl gsl_fft_real_workspace_free ptr (void) gsl_fft_real_workspace_free \ in-place libgsl gsl_fft_real_transform ptr int int ptr ptr (int) gsl_fft_real_transform libgsl gsl_fft_real_unpack ptr ptr int int (int) gsl_fft_real_unpack \ -- halfcomplex \ - mixed radix libgsl gsl_fft_hc_wtbl_alloc int (ptr) gsl_fft_halfcomplex_wavetable_alloc libgsl gsl_fft_hc_wtbl_free ptr (void) gsl_fft_halfcomplex_wavetable_free libgsl gsl_fft_hc_backward ptr int int ptr ptr (int) gsl_fft_halfcomplex_backward libgsl gsl_fft_hc_inverse ptr int int ptr ptr (int) gsl_fft_halfcomplex_inverse libgsl gsl_fft_hc_transform ptr int int ptr ptr (int) gsl_fft_halfcomplex_transform libgsl gsl_fft_hc_unpack ptr ptr int int (int) gsl_fft_halfcomplex_unpack \ - radix2 libgsl gsl_fft_hc_r2_unpack ptr ptr int int (int) gsl_fft_halfcomplex_radix2_unpack libgsl gsl_fft_hc_r2_backward ptr int int (int) gsl_fft_halfcomplex_radix2_backward libgsl gsl_fft_hc_r2_inverse ptr int int (int) gsl_fft_halfcomplex_radix2_inverse libgsl gsl_fft_hc_r2_transform ptr int int (int) gsl_fft_halfcomplex_radix2_transform | hashlen 32 vector fftpre( struct{ cell next cell size cell workspace cell r_wavetable cell hc_wavetable } gsl_fft_precomputes | create $buf 255 allot | : 2str dup >r abs s>d <# #s r> sign #> $buf 0place ; | : s>hash ( n -- key ) 2str $buf hash ; | : (cache-fft) ( n -- addr ) sizeof gsl_fft_precomputes allocate throw >r 0 r@ gsl_fft_precomputes next ! dup r@ gsl_fft_precomputes size ! dup gsl_fft_real_workspace_alloc r@ gsl_fft_precomputes workspace ! dup gsl_fft_real_wavetable_alloc r@ gsl_fft_precomputes r_wavetable ! gsl_fft_hc_wtbl_alloc r@ gsl_fft_precomputes hc_wavetable ! r> ; | : cache-fft ( size -- addr ) dup s>hash fftpre( over )@ 0= if swap (cache-fft) fftpre( rot dup >r )! fftpre( r> )@ else swap (cache-fft) swap fftpre( over )@ over gsl_fft_precomputes next ! fftpre( rot dup >r )! fftpre( r> )@ then ; \ in case not found addr is just the size | : find-fft-cache ( n -- addr 0/1 ) dup s>hash fftpre( swap )@ dup begin while 2dup gsl_fft_precomputes size @ = if nip true exit then gsl_fft_precomputes next @ dup repeat ; legacy on \ Structures struct{ cell name cell max cell min cell size cell set cell get cell get_double } gsl_rng_type struct{ cell type cell state } gsl_rng struct{ cell size cell data } gsl_block struct{ cell size cell stride cell data cell block cell owner } gsl_vector ' gsl_block alias gsl_permutation struct{ cell size1 cell size2 cell tda cell data cell block cell owner } gsl_matrix \ random number generation functions : 0-len dup 1- 0 begin 1+ 2dup + c@ 0= until nip ; : )gsl-rng ( addr i -- *gsl_rng_type ) cells + @ ; \ setting up all available random number generators gsl_rng_types_setup value gsl_rng_array( 0 value gsl_rng_default : gsl-free ( -- ) gsl_rng_default gsl_rng_free ; : borosh13 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 0 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : cmrg ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 1 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : coveyou ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 2 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : fishman18 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 3 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : fishman20 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 4 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : fishman2x ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 5 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : gfsr4 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 6 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : knuthran ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 7 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : knuthran2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 8 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : lecuyer21 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 9 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : minstd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 10 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : mrg ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 11 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : mt19937 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 12 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : mt19937_1999 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 13 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : mt19937_1998 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 14 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : r250 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 15 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ran0 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 16 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ran1 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 17 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ran2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 18 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ran3 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 19 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : rand ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 20 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : rand48 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 21 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random128-bsd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 22 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random128-glibc2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 23 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random128-libc5 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 24 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random256-bsd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 25 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random256-glibc2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 26 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random256-libc5 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 27 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random32-bsd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 28 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random32-glibc2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 29 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random32-libc5 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 30 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random64-bsd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 31 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random64-glibc2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 32 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random64-libc5 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 33 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random8-bsd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 34 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random8-glibc2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 35 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random8-libc5 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 36 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random-bsd ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 37 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random-glibc2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 38 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : random-libc5 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 39 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : randu ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 40 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranf ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 41 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlux ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 42 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlux389 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 43 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlxd1 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 44 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlxd2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 45 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlxs0 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 46 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlxs1 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 47 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranlxs2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 48 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : ranmar ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 49 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : slatec ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 50 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : taus ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 51 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : taus2 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 52 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : taus113 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 53 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : transputer ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 54 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : tt800 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 55 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : uni ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 56 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : uni32 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 57 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : vax ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 58 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : waterman14 ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 59 )gsl-rng gsl_rng_alloc to gsl_rng_default ; : zuf ( -- *gsl_rng ) gsl_rng_default 0<> if gsl-free then gsl_rng_array( 60 )gsl-rng gsl_rng_alloc to gsl_rng_default ; \ words for actual generation of random numbers : gsl-randomg ( -- n ) gsl_rng_default gsl_rng_get ; : gsl-randomu /* -- f \in [0,1) */ gsl_rng_default gsl_rng_uniform ; : gsl-randomu+ /* -- f \in (0,1) */ gsl_rng_default gsl_rng_uniform_pos ; : gsl-random-up ( n -- f \in [0,n] ) gsl_rng_default swap gsl_rng_uniform_int ; : gsl-set-seed ( n -- ) gsl_rng_default swap gsl_rng_set ; : gsl-clone ( -- *gsl_rng ) gsl_rng_default gsl_rng_clone ; : gsl-gaussian ( -- df ) gsl_rng_default !1 gsl_ran_gaussian ; : gsl-discrete ( *gsl_ran_discrete -- n ) gsl_rng_default swap gsl_ran_discrete ; \ vectors and matrices 0 constant GSL_VECTOR_TYPE 1 constant GSL_MATRIX_TYPE : gsltypeof ' >body cell + @ ; : fvector ( n -- | -- id addr ) create gsl_vector_calloc , GSL_VECTOR_TYPE , does> @ ; \ allocate a nameless vector : :] ( # -- addr ) gsl_vector_calloc ; \ allocate a nameless matrix : :]] ( # # -- addr ) gsl_matrix_calloc ; : ]@ ( addr i -- df ) gsl_vector_get ; : ]! ( df addr i -- ) gsl_vector_set ; : ]data ( addr -- *data ) gsl_vector data @ ; : ]stride ( addr -- *data ) gsl_vector stride @ ; : ]fill ( df addr -- ) gsl_vector_set_all ; : ]erase ( addr -- ) gsl_vector_set_zero ; : ]+ ( *gsl_vector *gsl_vector -- ) gsl_vector_add drop ; : ]- ( *gsl_vector *gsl_vector -- ) gsl_vector_sub drop ; : ]e*! ( *gsl_vector *gsl_vector -- ) gsl_vector_mul drop ; : ]size ( *gsl_vector -- n ) gsl_vector size @ ; : ]outer* ( *gsl_vector *gsl_vector -- *gsl_matrix ) over ]size over ]size gsl_matrix_calloc dup >r !1 gsl_blas_dger drop r> ; \ no control for divizion by zero (I get segfaults) : ]/ ( *gsl_vector *gsl_vector -- ) gsl_vector_div throw ; : ]clone ( *gsl_vector -- *gsl_vector ) dup gsl_vector size @ gsl_vector_alloc dup -rot swap gsl_vector_memcpy drop ; : ]add ( *gsl_vector *gsl_vector -- *gsl_vector ) ]clone dup -rot swap ]+ ; : ]sub ( *gsl_vector *gsl_vector -- *gsl_vector ) swap ]clone dup -rot swap ]- ; : ]mul ( *gsl_vector *gsl_vector -- *gsl_vector ) swap ]clone dup -rot swap ]e*! ; : ]div ( *gsl_vector *gsl_vector -- *gsl_vector ) swap ]clone dup -rot swap ]/ ; : ]*c ( df *gsl_vector -- ) gsl_vector_scale drop ; : ]+c ( df *gsl_vector -- ) gsl_vector_add_constant drop ; : ]max ( *gsl_vector -- ) gsl_vector_max ; : ]min ( *gsl_vector -- ) gsl_vector_min ; : ]imax ( *gsl_vector -- ) gsl_vector_max_index ; : ]imin ( *gsl_vector -- ) gsl_vector_min_index ; : ]copy] ( *gsl_vector_dest *gsl_vector_src -- ) gsl_vector_memcpy drop ; : ]negate !-1.0 ]*c ; : ]ones ( n -- *gsl_vector ) :] dup 1e ]fill ; : ]]slice ( *gsl_matrix x y n m -- *gsl_matrix ) gsl_matrix_alloc_from_matrix ; : ]slice ( *gsl_vector offset length stride -- *gsl_vector ) gsl_vector_alloc_from_vector ; : ]null? ( *gsl_vector -- 0/-1 ) gsl_vector_isnull negate ; : ]pos? ( *gsl_vector -- 0/-1 ) gsl_vector_ispos negate ; : ]neg? ( *gsl_vector -- 0/-1 ) gsl_vector_isneg negate ; \ FFT 19jan08sp : ]fft! ( *gsl_vector -- ) dup ]size >r dup ]stride >r ]data r> r> dup find-fft-cache if dup gsl_fft_precomputes r_wavetable @ swap gsl_fft_precomputes workspace @ else drop dup cache-fft dup gsl_fft_precomputes r_wavetable @ swap gsl_fft_precomputes workspace @ then gsl_fft_real_transform throw ; : ]fft ( *gsl_vector -- *gsl_vector ) ]clone dup ]fft! ; : ]ifft! ( *gsl_vector -- ) dup ]size >r dup ]stride >r ]data r> r> dup find-fft-cache if dup gsl_fft_precomputes hc_wavetable @ swap gsl_fft_precomputes workspace @ else drop dup cache-fft dup gsl_fft_precomputes hc_wavetable @ swap gsl_fft_precomputes workspace @ then gsl_fft_hc_inverse throw ; : ]ifft ( *gsl_vector -- *gsl_vector ) ]clone dup ]ifft! ; \ multiply two half complex vectors \ store result in the first : ]hc*! ( *gsl_vector *gsl_vector -- ) 2dup 0 ]@ 0 ]@ f* over 0 ]! dup ]size dup %1 and not + 1 do 2dup dup i ]@ i 1+ ]@ dup i ]@ i 1+ ]@ z* over dup i 1+ ]! i ]! 2 +loop dup ]size %1 and not if 2dup dup ]size 1- dup >r ]@ dup r@ ]@ f* r> ]! then 2drop ; \ pseudomatrices and vectors : pvector ( *data n -- *gsl_vector ) sizeof gsl_vector allocate throw dup >r dup 1 swap gsl_vector stride ! gsl_vector size ! r@ gsl_vector data ! r@ 0 swap gsl_vector owner ! r> ; : pmatrix! ( *data tda n m *pmatrix -- *gsl_matrix ) dup >r gsl_matrix size2 ! r@ gsl_matrix size1 ! r@ gsl_matrix tda ! r@ gsl_matrix data ! 0 r@ gsl_matrix owner ! r> ; : pmatrix ( *data tda n m -- *gsl_matrix ) sizeof gsl_matrix allocate throw dup 0 swap gsl_matrix owner ! pmatrix! ; \ permutations : fpermutation ( n -- | -- id addr ) create gsl_permutation_calloc , does> @ ; : }@ ( *gsl_permutation i -- n ) gsl_permutation_get ; : }data ( *gsl_permutation -- *data ) gsl_block data @ ; : }size ( *gsl_permutation -- *data ) gsl_block size @ ; : }free ( *gsl_permutation -- ) gsl_permutation_free ; : }sign ( *gsl_permutation -- 1/-1 ) 1 over dup }size 0 do dup i }@ i <> if swap negate swap then loop drop ; \ matrices : fmatrix ( n m -- | -- id addr ) create gsl_matrix_calloc , GSL_MATRIX_TYPE , does> @ ; : free_pseudomatrix ( pmatrix/pvector -- ) free throw ; create free_matrix ' free_pseudomatrix , ' gsl_matrix_free , create free_vector ' free_pseudomatrix , ' gsl_vector_free , : ]]free ( *gsl_matrix -- ) dup gsl_matrix owner @ cells free_matrix + @ execute ; : ]free ( addr -- ) dup gsl_vector owner @ cells free_vector + @ execute ; : ]]@ ( *gsl_matrix i j -- df ) gsl_matrix_get ; : ]]*@ ( *gsl_matrix i j -- *[i,j] ) gsl_matrix_ptr ; : ]]! ( *gsl_matrix i j df -- ) gsl_matrix_set ; : ]]fill ( addr df -- ) gsl_matrix_set_all ; : ]]size1 gsl_matrix size1 @ ; : ]]size2 gsl_matrix size2 @ ; : ]]dim ( *gsl_matrix -- m n ) dup ]]size1 swap ]]size2 ; : ]]dim. ( *gsl_matrix -- ) ]]dim swap . ." x" . cr ; : ]]data ( *gsl_matrix -- addr) gsl_matrix data @ ; : ]]tda gsl_matrix tda @ ; : ]]block gsl_matrix block @ ; : ]]owner gsl_matrix owner @ ; : ]]copy]] ( *gsl_matrix_dest *gsl_matrix_src -- ) gsl_matrix_memcpy drop ; : ]]'copy]] ( *gsl_matrix_dest *gsl_matrix_src -- ) gsl_matrix_transpose_memcpy drop ; \ : ]]row ( *gsl_matrix idx -- *gsl_vector ) gsl_matrix_row ; \ : ]]col ( *gsl_matrix idx -- *gsl_vector ) gsl_matrix_column ; : ]]>] ( *gsl_vector *gsl_matrix i -- ) gsl_matrix_get_col drop ; : ]]>]' ( *gsl_vector *gsl_matrix i -- ) gsl_matrix_get_row drop ; : ]>]] ( *gsl_matrix *gsl_vector i -- ) swap gsl_matrix_set_col drop ; : ]'>]] ( *gsl_matrix *gsl_vector i -- ) swap gsl_matrix_set_row drop ; : ]]max gsl_matrix_max ; : ]]min gsl_matrix_min ; : ]]add! ( *gsl_matrix *gsl_matrix -- ) gsl_matrix_add drop ; : ]]sub! ( *gsl_matrix *gsl_matrix -- ) gsl_matrix_sub drop ; : ]]e*! ( *gsl_matrix *gsl_matrix -- ) gsl_matrix_mul_elements drop ; : ]]*c ( *gsl_matrix df -- ) gsl_matrix_scale drop ; : ]]+c ( df *gsl_matrix -- ) gsl_matrix_add_constant drop ; : ]]clone ( *gsl_matrix -- *gsl_matrix ) dup dup gsl_matrix size1 @ swap gsl_matrix size2 @ gsl_matrix_alloc dup -rot swap gsl_matrix_memcpy drop ; : ]]negate !-1.0 ]]*c ; : ]]+ ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) ]]clone dup -rot swap ]]add! ; : ]]- ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) swap ]]clone dup -rot swap ]]sub! ; : ]]null? ( *gsl_matrix -- 0/-1 ) gsl_matrix_isnull negate ; : ]]pos? ( *gsl_matrix -- 0/-1 ) gsl_matrix_ispos negate ; : ]]neg? ( *gsl_matrix -- 0/-1 ) gsl_matrix_isneg negate ; \ blas \ constants 101 Constant CblasRowMajor 102 Constant CblasColMajor 111 Constant CblasNoTrans 112 Constant CblasTrans 113 Constant CblasConjTrans 121 Constant CblasUpper 122 Constant CblasLower 131 Constant CblasNonUnit 132 Constant CblasUnit 141 Constant CblasLeft 142 Constant CblasRight : action? ( *gsl_matrix *gsl_matrix n n n -- ) dup 0= if drop 2swap 2dup ]]size2 swap ]]size1 swap exit then dup 1 = if drop 2swap 2dup ]]size2 swap ]]size2 swap exit then 2 = if 2swap 2dup ]]size1 swap ]]size1 swap exit then 3 = if 2swap 2dup ]]size1 swap ]]size2 swap exit then ; create samemattable ' noop , ' ]]clone , : samemat ( *gsl_matrix *gsl_matrix -- 1/0 *gsl_matrix ) dup -rot = abs dup -rot cells samemattable + @ execute ; macro : ]]mul ( *gsl_matrix *gsl_matrix n n n -- *gsl_matrix ) !1 !0 action? gsl_matrix_alloc dup >r gsl_blas_dgemm drop r> ; : ]]* ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) 2dup samemat dup rot 2>r nip CblasNoTrans CblasNoTrans 0 ]]mul 2r> if ]]free else drop then ; : ]]'* ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) 2dup samemat dup rot 2>r nip CblasTrans CblasNoTrans 1 ]]mul 2r> if ]]free else drop then ; : ]]*' ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) 2dup samemat dup rot 2>r nip CblasNoTrans CblasTrans 2 ]]mul 2r> if ]]free else drop then ; : ]]'*' ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) 2dup samemat dup rot 2>r nip CblasTrans CblasTrans 3 ]]mul 2r> if ]]free else drop then ; : ]]mul! ( n n *gsl_matrix *gsl_matrix *gsl_matrix -- ) !1 !0 gsl_blas_dgemm drop ; : ]]*! ( *gsl_matrix *gsl_matrix *gsl_matrix -- ) >r CblasNoTrans CblasNoTrans 2swap r> ]]mul! ; : ]]'*! ( *gsl_matrix *gsl_matrix *gsl_matrix -- ) >r CblasTrans CblasNoTrans 2swap r> ]]mul! ; : ]]*'! ( *gsl_matrix *gsl_matrix *gsl_matrix -- ) >r CblasNoTrans CblasTrans 2swap r> ]]mul! ; : ]]*] ( *gsl_matrix *gsl_vector -- *gsl_vector ) over ]]size1 gsl_vector_alloc >r CblasNoTrans -rot r@ !1 !0 gsl_blas_dgemv drop r> ; : ]]'*] ( *gsl_matrix *gsl_vector -- *gsl_vector ) over ]]size1 gsl_vector_alloc >r CblasTrans -rot r@ !1 !0 gsl_blas_dgemv drop r> ; : ]]i ( *gsl_matrix -- ) dup dup ]]size1 swap ]]size2 <> if abort" ERROR: Not a square matrix!" then dup ]]size1 0 do dup i i !1 ]]! loop drop ; : identity ( n -- *gsl_matrix ) dup gsl_matrix_calloc dup ]]i ; : min-identity ( *gsl_matrix -- *gsl_matrix ) dup ]]size1 swap ]]size2 min identity ; : left/right' ( *gsl_matrix *gsl_matrix -- *gsl_matrix ) over ]]size1 over ]]size1 > if swap ]]*' exit else ]]'* exit then ; \ original matrix remains intact : ]]' ( *gsl_matrix -- *gsl_matrix ) dup min-identity dup >r left/right' r> ]]free ; : ]]T! ( *gsl_matrix -- ) gsl_matrix_transpose drop ; : ]]T ( *gsl_matrix -- *gsl_matrix ) dup ]]dim swap gsl_matrix_alloc dup rot gsl_matrix_transpose_memcpy drop ; : ]]2T ( *gsl_matr *gsl_matrix -- ) gsl_matrix_transpose_memcpy drop ; : ]]+! ( *gsl_matrix i j df -- ) >r 2dup r@ ]]@ f+ r> ]]! ; : ]]scale! ( *gsl_matrix i j df -- ) >r 2dup r@ ]]@ f* r> ]]! ; : ]]data_ij ( *gsl_matrix i j -- addr) rot >r swap r@ ]]tda dfloats * swap dfloats + r> ]]data + ; \ Cross product can be either calculated through determinant: : ]x ( *gsl_vector *gsl_vector -- *gsl_vector ) 3 gsl_vector_alloc { x1[ x2[ x3[ | x1[ 2 ]@ fnegate x2[ 1 ]@ f* x1[ 1 ]@ x2[ 2 ]@ f* f+ x3[ 0 ]! x1[ 2 ]@ x2[ 0 ]@ f* x1[ 0 ]@ fnegate x2[ 2 ]@ f* f+ x3[ 1 ]! x1[ 1 ]@ fnegate x2[ 0 ]@ f* x1[ 0 ]@ x2[ 1 ]@ f* f+ x3[ 2 ]! x3[ } ; \ or using algebraic form when first vector in the product is \ rewritten in a matrix form: \ a x b = [C_a] b \ [ 0 -a[2] a[1] ] \ [C_a] = [ a[2] 0 -a[0] ] \ [-a[1] a[0] 0 ] \ a function to convert a vector into such matrix: : ]>[x] ( ] -- ]] ) [IFDEF] debug dup ]size 3 <> abort" Not a 3D vector!" [THEN] 3 3 :]] dup >r swap 2dup 2 ]@ fdup dup fnegate 0 1 ]]! 1 0 ]]! 2dup 1 ]@ fdup dup fnegate 2 0 ]]! 0 2 ]]! 0 ]@ fdup dup fnegate 1 2 ]]! 2 1 ]]! r> ; : ]. ( *gsl_vector *gsl_vector -- f:dot_product ) { x1[ x2[ | 0 0 sp@ x1[ x2[ rot gsl_blas_ddot drop fd>f } ; : ]total ( *gsl_vector -- f:sum ) dup ]size gsl_vector_alloc dup !1 ]fill dup rot ]. ]free ; \ probability normalize - assures sum is unity : ]pnormalize ( *gsl_vector - ) dup ]total 1/f ]*c ; : |]| ( *gsl_vector -- f:norm ) dup ]. fsqrt ; \ assures vector norm is unity : ]normalize ( *gsl_vector - ) dup |]| 1/f ]*c ; : ]distance ( *gsl-vector *gsl-vector -- f ) ]sub dup |]| ]free ; : ]+! ( *gsl_vector i df -- ) 2dup ]@ f+ ]! ; : ]*! ( *gsl_vector i df -- ) 2dup ]@ f* ]! ; : ]]*]m ( *gsl_matrix *gsl_vector -- *gsl_vector ) over ]]size1 gsl_vector_calloc { m[[ x[ y[ | m[[ ]]size1 0 do m[[ ]]size2 0 do m[[ j i ]]@ x[ i ]@ f* y[ j ]+! loop loop y[ } ; : >#rows ( -- ) swap ]]size1 >= abort" number of rows is bigger than available!" ; : >#cols ( -- ) swap ]]size2 >= abort" number of columns is bigger than available!" ; : ]]row ( *gsl_matrix n -- *gsl_vector ) 2dup >#rows sizeof gsl_vector allocate throw dup 1 swap gsl_vector stride ! >r over ]]size2 r@ gsl_vector size ! 0 ]]data_ij r@ gsl_vector data ! 0 r@ gsl_vector owner ! r> ; \ assumes all dimensions are set correctly : ]]row! ( *gsl_vector *gsl_matrix n -- ) rot >r 2dup >#rows 0 ]]data_ij r> gsl_vector data ! ; : ]]col ( *gsl_matrix n -- *gsl_vector ) 2dup >#cols sizeof gsl_vector allocate throw >r over ]]tda r@ gsl_vector stride ! over ]]size1 r@ gsl_vector size ! over ]]block r@ gsl_vector block ! 0 swap ]]data_ij r@ gsl_vector data ! 0 r@ gsl_vector owner ! r> ; : ]]rfill ( f:n *gsl_matrix i -- ) ]]row dup ]fill ]free ; : ]]cfill ( f:n *gsl_matrix i -- ) ]]col dup ]fill ]free ; : ]]submat ( *gsl_matrix n1 n2 m1 m2 -- *gsl_matrix ) { m[[ n1 n2 m1 m2 | sizeof gsl_matrix allocate throw >r n2 n1 - 1+ r@ gsl_matrix size1 ! m2 m1 - 1+ r@ gsl_matrix size2 ! m[[ n1 m1 ]]data_ij r@ gsl_matrix data ! m[[ ]]tda r@ gsl_matrix tda ! 0 r@ gsl_matrix owner ! r> } ; : ?square ( *gsl_matrix -- ) dup ]]size1 swap ]]size2 <> abort" ERROR: Not a square matrix!" ; : ]]diag ( *gsl_matrix n1 n2 -- *gsl_vector ) rot dup ?square -rot sizeof gsl_vector allocate throw { d[ | over - d[ gsl_vector size ! 2dup dup ]]data_ij d[ gsl_vector data ! drop dup ]]tda d[ gsl_vector stride ! ]]block d[ gsl_vector block ! 0 d[ gsl_vector owner ! d[ } ; \ with input matrix replaced by the result : ]]gsl-svd ( *gsl_matrix -- *gsl_matrix *gsl_vector ) dup ]]size2 dup dup gsl_matrix_calloc swap dup gsl_vector_calloc swap gsl_vector_calloc { mV vS vW | mV vS vW gsl_linalg_SV_decomp drop vW ]free mV vS } ; \ seems to be 30% faster : ]]gsl-svdm ( *gsl_matrix -- *gsl_matrix *gsl_vector ) dup ]]size2 dup ( a n n -- ) dup dup gsl_matrix_calloc swap ( a n a n -- ) dup gsl_matrix_calloc rot dup ( a a a n n -- ) gsl_vector_calloc swap gsl_vector_calloc { mX mV vS vW | mX mV vS vW gsl_linalg_SV_decomp_mod drop vW ]free mX ]]free mV vS } ; : ]]alu ( *gsl_matrix -- *gsl_permutation ) ( matrix replaced with its lu ) { a[[ | CblasRowMajor a[[ ]]size1 a[[ ]]size2 a[[ ]]data a[[ ]]size1 dup gsl_permutation_alloc dup >r }data clapack_dgetrf throw r> } ; : ]]ainv ( *gsl_matrix *gsl_permutation -- ) \ LU of a matrix replaced with its inverse { a[[ t{ | CblasRowMajor a[[ ]]size2 a[[ ]]data a[[ ]]size1 t{ }data clapack_dgetri throw } ; : ]]ainvert ( *gsl_matrix -- *gsl_matrix ) [IFDEF] отладка dup ?square [THEN] ]]clone dup dup >r ]]alu dup >r ]]ainv r> }free r> ; : ]]det ( *gsl_matrix -- f:determinant ) [IFDEF] отладка dup ?square [THEN] ]]clone dup ]]alu >r 1e0 dup ]]size1 0 do dup i dup ]]@ f* loop ]]free \ compute permutation sign r> }sign s>f f* }free ; \ calculates the work needed for dgesvd_ ( see man dgesvd ) : lwork ( m n -- c ) 2dup max -rot min 3 * over + swap 5 * max ; \ this svd returns U MxM so eats a lot of memory : ]]asvda ( *gsl_matrix -- *gsl_matrix *gsl_matrix *gsl_vector ) ]]clone { A[[ | A[[ ]]size1 dup gsl_matrix_alloc A[[ ]]size2 dup gsl_matrix_alloc A[[ ]]size1 A[[ ]]size2 min gsl_vector_alloc 8 cells allocate throw { U[[ V[[ W[ p[ | ascii A p[ 0 cells + ! p[ 0 cells + ascii A p[ 1 cells + ! p[ 1 cells + A[[ ]]size1 p[ 2 cells + ! p[ 2 cells + A[[ ]]size2 p[ 3 cells + ! p[ 3 cells + A[[ ]]data p[ 2 cells + W[ ]data U[[ ]]data U[[ ]]size1 p[ 4 cells + ! p[ 4 cells + V[[ ]]data V[[ ]]size1 p[ 5 cells + ! p[ 5 cells + A[[ ]]size1 A[[ ]]size2 lwork dup gsl_vector_alloc dup >r ]data swap p[ 6 cells + ! p[ 6 cells + p[ 7 cells + dgesvd_ r> ]free p[ free throw A[[ ]]free U[[ V[[ W[ } } ; \ performs A=U*S*V^T \ A = MxN, where M>N, pass it A^T \ returns U^T (MxN), V(NxN) and vector of N eigenvalues : ]]asvdO ( *gsl_matrix -- *gsl_matrix *gsl_matrix *gsl_vector ) { A[[ | A[[ ]]size2 A[[ ]]size1 min dup gsl_matrix_alloc A[[ ]]size1 A[[ ]]size2 min gsl_vector_alloc 8 cells allocate throw { V[[ W[ p[ | ascii O p[ 0 cells + ! p[ 0 cells + ascii S p[ 1 cells + ! p[ 1 cells + A[[ ]]size2 p[ 2 cells + ! p[ 2 cells + A[[ ]]size1 p[ 3 cells + ! p[ 3 cells + A[[ ]]data p[ 2 cells + W[ ]data 0 p[ 2 cells + V[[ ]]data V[[ ]]size2 p[ 5 cells + ! p[ 5 cells + A[[ ]]size2 A[[ ]]size1 lwork dup gsl_vector_alloc dup >r ]data swap p[ 6 cells + ! p[ 6 cells + p[ 7 cells + dgesvd_ r> ]free p[ free throw A[[ V[[ W[ } } ; : ]diag[[ ( *gsl_vector -- *gsl_matrix ) dup ]size dup dup gsl_matrix_calloc swap 0 do 2dup swap i ]@ i i ]]! loop nip ; : ]print\ ( *gsl_vector -- ) dup ]size 0 do dup i ]@ fx. loop drop ; : ]print ( *gsl_vector -- ) ]print\ cr ; : ]]print ( *gsl_matrix -- ) cr precision swap 5 set-precision dup ]]size1 0 do \ i . ." : " dup ]]size2 0 do dup j i ]]@ fs. loop cr loop drop set-precision ; : ]]row-print ( *gsl_matrix i -- ) cr over gsl_matrix size2 @ 0 do 2dup i ]]@ f. loop cr 2drop ; : ]]col-print ( *gsl_matrix i -- ) cr over gsl_matrix size1 @ 0 do 2dup i swap ]]@ f. loop cr 2drop ; : ]]nthrow ( *gsl_matrix n -- addr ) over ]]tda * dfloats swap ]]data + ; : ]]randomize ( *gsl_matrix -- ) dup dup ]]size1 swap ]]size2 * 0 do dup gsl-randomu ]]data i dfloats + df! loop drop ; : ]randomize ( *gsl_vector -- ) dup ]size 0 do dup gsl-randomu i ]! loop drop ; : ]mean ( *gsl_vector -- f ) dup ]stride swap dup ]size swap ]data rot rot gsl_stats_mean ; : ]variance ( *gsl_vector -- f ) dup ]stride swap dup ]size swap ]data rot rot gsl_stats_variance ; : ]sd ( *gsl_vector -- f ) dup ]stride swap dup ]size swap ]data rot rot gsl_stats_sd ; : ]skew ( *gsl_vector -- f ) dup ]stride swap dup ]size swap ]data rot rot gsl_stats_skew ; : ]kurtosis ( *gsl_vector -- f ) dup ]stride swap dup ]size swap ]data rot rot gsl_stats_kurtosis ; : ]]gsl-lu ( *gsl_matrix -- *gsl_matrix *gsl_permutation ) 1 sp@ rot ]]clone dup >r dup ]]size1 gsl_permutation_calloc dup >r rot gsl_linalg_LU_decomp drop r> r> swap rot drop ; : ]]gsl-invert ( *gsl_matrix -- *gsl_matrix ) ]]clone dup dup ]]gsl-lu 2dup >r >r rot gsl_linalg_LU_invert drop r> ]]free r> }free ; ' ]]ainvert alias ]]invert ' ]]asvdO alias ]]svd : ]]save ( *gsl_matrix *gsl_matrix_cfa fid -- ) -rot { m[[ name[[ | >r name[[ >name count 1+ nip 0 m[[ ]]size2 m[[ ]]size1 0 sp@ 5 cells r@ write-file throw 2drop 2drop drop name[[ >name count 1+ r@ write-file throw m[[ ]]size1 m[[ ]]size2 * dfloats m[[ ]]T dup s>f ]]data swap r> write-file throw f>s ]]free } ; \ these words do not work with float matrices but are needed for \ scientific calculations, that's why they are in this module : _hmatrix ( n m size -- addr ) rot over * 2 pick * [ 2 cells ] literal + allocate throw dup [ 2 cells ] literal + >r rot over ! [ 1 cells ] literal + ! r> ; : hmatrix ( n m size -- ) create rot over * 2 pick * [ 2 cells ] literal + allocate throw dup , rot over ! [ 1 cells ] literal + ! does> @ [ 2 cells ] literal + ; : }}row-size ( hmatrix -- ) [ 2 cells ] literal - @ ; : freeHmatrix ( hmatrix -- ) [ 2 cells ] literal - free throw ; : }} ( addr i j -- addr[i][j] ) \ word to fetch 2-D array addresses >R >R \ indices to return stack temporarily DUP CELL- CELL- 2@ \ &a[0][0] size m R> * R> + * + ALIGNED ; : h->[[ ( hmatrix -- gsl_matrix ) dup }}row-size 3 swap gsl_matrix_alloc dup ]]size2 0 do 3 0 do 2dup swap i j }} w@ s>f i j ]]! loop loop nip ; \ some sequencing code : arange ( f:start f:end f:step -- x[ ) f-rot fswap fdup f>r f- fover f/ f>s :] fr> dup ]size 0 do dup fover i s>f f* fover f+ i ]! loop ; : product ( x[ -- f:P ) !1 dup ]size 0 do dup i ]@ f* loop drop ; \ initializing random number generator to some value in order to have \ it available upon loading of gsl mt19937 : )randperm ( *v( -- ) gsl_rng_default swap dup )size over )type 8 / gsl_ran_shuffle ; previous previous previous previous previous Module; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/datac.h�������������������������������������������������������������������0000644�0001750�0001750�00000101551�13513030041�016661� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * datac.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_DATAC_H_ #define _MGL_DATAC_H_ #include "mgl2/data.h" #include "mgl2/datac_cf.h" //----------------------------------------------------------------------------- #include #include //----------------------------------------------------------------------------- #ifndef SWIG dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); dual MGL_EXPORT mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx=0, dual *dy=0, dual *dz=0); dual MGL_EXPORT mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); //----------------------------------------------------------------------------- /// Class for working with complex data array class MGL_EXPORT mglDataC : public mglDataA { public: using mglDataA::Momentum; long nx; ///< number of points in 1st dimensions ('x' dimension) long ny; ///< number of points in 2nd dimensions ('y' dimension) long nz; ///< number of points in 3d dimensions ('z' dimension) dual *a; ///< data array bool link; ///< use external data (i.e. don't free it) /// Initiate by other mglDataC variable mglDataC(const mglDataC &d) { a=0; mgl_datac_set(this,&d); } // NOTE: must be constructor for mglDataC& to exclude copy one mglDataC(const mglDataA &d) { a=0; mgl_datac_set(this,&d); } #if MGL_HAVE_RVAL mglDataC(mglDataC &&d):nx(d.nx),ny(d.ny),nz(d.nz),a(d.a),link(d.link) { s=d.s; temp=d.temp; func=d.func; o=d.o; id=d.id; d.a=0; d.func=0; } #endif mglDataC(const mglDataA &re, const mglDataA &im) { a=0; mgl_datac_set_ri(this,&re,&im); } mglDataC(HCDT d) { a=0; mgl_datac_set(this, d); } mglDataC(HCDT re, HCDT im) { a=0; mgl_datac_set_ri(this, re, im); } mglDataC(bool, mglDataC *d) // NOTE: Variable d will be deleted!!! { if(d) { nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=0; temp=d->temp; func=d->func; o=d->o; s=d->s; id=d->id; link=d->link; delete d; } else { a=0; Create(1); } } /// Initiate by flat array mglDataC(int size, const dual *d) { a=0; Set(d,size); } mglDataC(int rows, int cols, const dual *d) { a=0; Set(d,cols,rows); } mglDataC(int size, const double *d) { a=0; Set(d,size); } mglDataC(int rows, int cols, const double *d) { a=0; Set(d,cols,rows); } mglDataC(int size, const float *d) { a=0; Set(d,size); } mglDataC(int rows, int cols, const float *d) { a=0; Set(d,cols,rows); } mglDataC(const dual *d, int size) { a=0; Set(d,size); } mglDataC(const dual *d, int rows, int cols) { a=0; Set(d,cols,rows); } mglDataC(const double *d, int size) { a=0; Set(d,size); } mglDataC(const double *d, int rows, int cols) { a=0; Set(d,cols,rows); } mglDataC(const float *d, int size) { a=0; Set(d,size); } mglDataC(const float *d, int rows, int cols) { a=0; Set(d,cols,rows); } /// Allocate memory and copy data from std::vector mglDataC(const std::vector &d) { a=0; Set(d); } mglDataC(const std::vector &d) { a=0; Set(d); } mglDataC(const std::vector &d) { a=0; Set(d); } mglDataC(const std::vector > &d) { a=0; Set(d); } mglDataC(const std::vector > &d) { a=0; Set(d); } /// Read data from file mglDataC(const char *fname) { a=0; Read(fname); } /// Allocate the memory for data array and initialize it zero mglDataC(long xx=1,long yy=1,long zz=1) { a=0; Create(xx,yy,zz); } /// Delete the array virtual ~mglDataC() { if(!link && a) delete []a; } /// Move all data from variable d, and delete this variable. inline void Move(mglDataC *d) // NOTE: Variable d will be deleted!!! { if(d && d->GetNN()>1) { bool l=link; dual *b=a; nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=b; temp=d->temp; func=d->func; o=d->o; s=d->s; id=d->id; link=d->link; d->link=l; delete d; } else if(d) { *this = d->a[0]; delete d; } } inline dual GetVal(long i, long j=0, long k=0) const { return mgl_datac_get_value(this,i,j,k);} inline void SetVal(dual f, long i, long j=0, long k=0) { mgl_datac_set_value(this,f,i,j,k); } /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } long GetNz() const { return nz; } /// Link external data array (don't delete it at exit) inline void Link(dual *A, long NX, long NY=1, long NZ=1) { mgl_datac_link(this,reinterpret_cast(A),NX,NY,NZ); } inline void Link(mglDataC &d) { Link(d.a,d.nx,d.ny,d.nz); } /// Allocate memory and copy the data from the gsl_vector inline void Set(gsl_vector *m) { mgl_datac_set_vector(this,m); } /// Allocate memory and copy the data from the gsl_matrix inline void Set(gsl_matrix *m) { mgl_datac_set_matrix(this,m); } /// Allocate memory and copy the data from the (float *) array inline void Set(const float *A,long NX,long NY=1,long NZ=1) { mgl_datac_set_float(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (double *) array inline void Set(const double *A,long NX,long NY=1,long NZ=1) { mgl_datac_set_double(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (complex *) array inline void Set(const dual *A,long NX,long NY=1,long NZ=1) { mgl_datac_set_complex(this,reinterpret_cast(A),NX,NY,NZ); } /// Allocate memory and scanf the data from the string inline void Set(const char *str,long NX,long NY=1,long NZ=1) { mgl_datac_set_values(this,str,NX,NY,NZ); } /// Import data from abstract type inline void Set(HCDT dat) { mgl_datac_set(this, dat); } inline void Set(const mglDataA &dat) { mgl_datac_set(this, &dat); } inline void Set(const mglDataA &re, const mglDataA &im) { mgl_datac_set_ri(this, &re, &im); } inline void Set(HCDT re, HCDT im) { mgl_datac_set_ri(this, re, im); } inline void SetAmpl(const mglDataA &l, const mglDataA &phase) { mgl_datac_set_ap(this, &l, &phase); } /// Allocate memory and copy data from std::vector inline void Set(const std::vector &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i &d) { if(d.size()>0) Set(&(a[0]),d.size()); else Create(1); } inline void Set(const std::vector &d) { if(d.size()>0) Set(&(a[0]),d.size()); else Create(1); } inline void Set(const std::vector > &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i > &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i1?nx-1:1; dif.y/=ny>1?ny-1:1; dif.z/=nz>1?nz-1:1; return val; } /// Return an approximated x-value (root) when dat(x) = val inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const { return mgl_data_solve_1d(this, val, use_spline, i0); } /// Return an approximated value (root) when dat(x) = val inline mglData Solve(mreal val, char dir, bool norm=true) const { return mglData(true,mgl_data_solve(this, val, dir, 0, norm)); } inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const { return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); } /// Copy data from other mglDataA variable inline const mglDataA &operator=(const mglDataA &d) { if(this!=&d) Set(&d); return d; } inline const mglDataC &operator=(const mglDataC &d) { if(this!=&d) Set(&d); return d; } inline dual operator=(dual val) { #pragma omp parallel for for(long i=0;i0? abs(i0? abs(j0? abs(k=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglDataC mglQO2dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglDataC(true, mgl_qo2d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0)); } inline mglDataC mglQO2dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mreal r=1, mreal k0=100) { return mglDataC(true, mgl_qo2d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy)); } /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglDataC mglQO3dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0, 0)); } inline mglDataC mglQO3dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mglData &zz, mreal r=1, mreal k0=100) { return mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz)); } /// Saves result of ODE solving for var complex variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt inline mglDataC mglODEc(const char *func, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10) { return mglDataC(true, mgl_ode_solve_str_c(func,var, &ini, dt, tmax)); } //----------------------------------------------------------------------------- /// Get array as solution of tridiagonal system of equations a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i] /** String \a how may contain: * 'x', 'y', 'z' for solving along x-,y-,z-directions, or * 'h' for solving along hexagonal direction at x-y plain (need nx=ny), * 'c' for using periodical boundary conditions, * 'd' for diffraction/diffuse calculation. */ inline mglDataC mglTridMatC(const mglDataA &A, const mglDataA &B, const mglDataA &C, const mglDataC &D, const char *how) { return mglDataC(true, mgl_datac_tridmat(&A, &B, &C, &D, how)); } //----------------------------------------------------------------------------- /// Get sub-array of the data with given fixed indexes inline mglDataC mglSubDataC(const mglDataA &dat, long xx, long yy=-1, long zz=-1) { return mglDataC(true,mgl_datac_subdata(&dat,xx,yy,zz)); } inline mglDataC mglSubDataC(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) { return mglDataC(true,mgl_datac_subdata_ext(&dat,&xx,&yy,&zz)); } inline mglDataC mglSubDataC(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy) { return mglDataC(true,mgl_datac_subdata_ext(&dat,&xx,&yy,0)); } inline mglDataC mglSubDataC(const mglDataA &dat, const mglDataA &xx) { return mglDataC(true,mgl_datac_subdata_ext(&dat,&xx,0,0)); } //----------------------------------------------------------------------------- /// Prepare coefficients for global spline interpolation inline mglDataC mglGSplineCInit(const mglDataA &xdat, const mglDataA &ydat) { return mglDataC(true,mgl_gsplinec_init(&xdat, &ydat)); } /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef inline dual mglGSplineC(const mglDataA &coef, mreal dx, dual *d1=0, dual *d2=0) { return mgl_gsplinec(&coef, dx, reinterpret_cast(d1), reinterpret_cast(d2)); } //----------------------------------------------------------------------------- #define _DN_(a) ((mglDataC *)*(a)) #define _DC_ ((mglDataC *)*d) //----------------------------------------------------------------------------- #ifndef SWIG /// Wrapper class for complex expression evaluating class MGL_EXPORT mglExprC { HAEX ex; mglExprC(const mglExprC &){} // copying is not allowed const mglExprC &operator=(const mglExprC &t){return t;} // copying is not allowed public: mglExprC(const char *expr) { ex = mgl_create_cexpr(expr); } ~mglExprC() { mgl_delete_cexpr(ex); } /// Return value of expression for given x,y,z variables inline dual Eval(dual x, dual y=0, dual z=0) { return mgl_cexpr_eval(ex,x,y,z); } /// Return value of expression for given x,y,z,u,v,w variables inline dual Eval(dual x, dual y, dual z, dual u, dual v, dual w) { mdual var[26]; var['x'-'a']=x; var['y'-'a']=y; var['z'-'a']=z; var['u'-'a']=u; var['v'-'a']=v; var['w'-'a']=w; return mgl_cexpr_eval_v(ex,var); } /// Return value of expression for given variables inline dual Eval(dual var[26]) { return mgl_cexpr_eval_v(ex,reinterpret_cast(var)); } }; #endif //----------------------------------------------------------------------------- #endif #endif �������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/type.h��������������������������������������������������������������������0000644�0001750�0001750�00000031672�13513030041�016574� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * type.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_TYPE_H_ #define _MGL_TYPE_H_ #include "mgl2/define.h" //----------------------------------------------------------------------------- const mreal mglPi = M_PI; const mreal mglNaN = NAN; const mreal mglInf = INFINITY; const mreal mgl_min_a = 1./256; //----------------------------------------------------------------------------- #define MGL_SET_XYZ(p,xx,yy,zz) {p.x=(xx);p.y=(yy);p.z=(zz);} #define MGL_SET_XY(p,xx,yy) {p.x=(xx);p.y=(yy);p.z=0;} #define MGL_SET_RGBA(p,rr,gg,bb,aa) {p.r=(rr);p.g=(gg);p.b=(bb);p.a=(aa);} #define MGL_SET_RGB(p,rr,gg,bb) {p.r=(rr);p.g=(gg);p.b=(bb);} //----------------------------------------------------------------------------- /// Class for point in 3D space struct MGL_EXPORT mglPoint { mreal x,y,z,c; mglPoint(mreal X=0,mreal Y=0,mreal Z=0,mreal C=0):x(X),y(Y),z(Z),c(C) {} mglPoint(const mglPoint &d):x(d.x),y(d.y),z(d.z),c(d.c) {} #if MGL_HAVE_RVAL mglPoint(mglPoint &&d):x(d.x),y(d.y),z(d.z),c(d.c) {} #endif inline void Set(mreal X=0,mreal Y=0,mreal Z=0,mreal C=0) {x=X;y=Y;z=Z;c=C;} inline bool IsNAN() const { return (x!=x || y!=y || z!=z || c!=c); } inline mreal val(int i) const { mreal dat[4]={x,y,z,c}; return dat[i]; } inline mreal norm() const { return sqrt(x*x+y*y+z*z); } inline void Normalize() { mreal v=norm(); x/=v; y/=v; z/=v; } inline const mglPoint &operator=(const mglPoint &p) { x=p.x; y=p.y; z=p.z; c=p.c; return p; } inline void operator+=(const mglPoint &a) { x+=a.x; y+=a.y; z+=a.z; c+=a.c; } inline void operator-=(const mglPoint &a) { x-=a.x; y-=a.y; z-=a.z; c-=a.c; } inline void operator+=(mreal a) { x+=a; y+=a; z+=a; } inline void operator-=(mreal a) { x-=a; y-=a; z-=a; } inline void operator*=(mreal a) { x*=a; y*=a; z*=a; } inline void operator/=(mreal a) { x/=a; y/=a; z/=a; } }; #ifndef SWIG inline mglPoint operator+(const mglPoint &a, const mglPoint &b) { return mglPoint(a.x+b.x, a.y+b.y, a.z+b.z, a.c+b.c); } inline mglPoint operator-(const mglPoint &a, const mglPoint &b) { return mglPoint(a.x-b.x, a.y-b.y, a.z-b.z, a.c-b.c); } inline mglPoint operator-(const mglPoint &a) { return mglPoint(-a.x, -a.y, -a.z, -a.c); } inline mglPoint operator*(mreal b, const mglPoint &a) { return mglPoint(a.x*b, a.y*b, a.z*b, a.c*b); } inline mglPoint operator*(const mglPoint &a, mreal b) { return mglPoint(a.x*b, a.y*b, a.z*b, a.c*b); } inline mglPoint operator/(const mglPoint &a, mreal b) { return mglPoint(a.x/b, a.y/b, a.z/b); } inline mreal operator*(const mglPoint &a, const mglPoint &b) { return a.x*b.x+a.y*b.y+a.z*b.z; } inline mglPoint operator/(const mglPoint &a, const mglPoint &b) { return mglPoint(a.x*b.x, a.y*b.y, a.z*b.z); } inline mglPoint operator&(const mglPoint &a, const mglPoint &b) { return a - b*((a*b)/(b*b)); } inline mglPoint operator|(const mglPoint &a, const mglPoint &b) { return b*((a*b)/(b*b)); } inline mglPoint operator^(const mglPoint &a, const mglPoint &b) { return mglPoint(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x); } inline mglPoint operator!(const mglPoint &a) { mreal f=mgl_hypot(a.x,a.y); return f==0?mglPoint(0.,1.,0.):mglPoint(-a.y/f, a.x/f, 0); } inline bool operator==(const mglPoint &a, const mglPoint &b) // NOTE: exact comparison is used here { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.c-b.c)*(a.c-b.c)==0; } //{ return !memcmp(&a, &b, sizeof(mglPoint)); } inline bool operator!=(const mglPoint &a, const mglPoint &b) // NOTE: exact comparison is used here { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.c-b.c)*(a.c-b.c)!=0; } //{ return memcmp(&a, &b, sizeof(mglPoint)); } inline bool operator<(const mglPoint &a, const mglPoint &b) { return a.x<=b.x && a.y<=b.y && a.z<=b.z; } inline bool operator>(const mglPoint &a, const mglPoint &b) { return a.x>=b.x && a.y>=b.y && a.z>=b.z; } inline mreal mgl_norm(const mglPoint &p) { return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); } inline mreal mgl_anorm(const mglPoint &p) { return fabs(p.x)+fabs(p.y)+fabs(p.z); } #endif //----------------------------------------------------------------------------- /// Class for RGBA color struct MGL_EXPORT mglColor { float r; ///< Red component of color float g; ///< Green component of color float b; ///< Blue component of color float a; ///< Alpha component of color /// Constructor for RGB components manually mglColor(float R,float G,float B, float A=1):r(R),g(G),b(B),a(A) {} /// Constructor for RGB components manually mglColor(const unsigned char *c, float A=1):r(c[0]/255.f),g(c[1]/255.f),b(c[2]/255.f),a(A) {} /// Constructor set default color mglColor():r(0),g(0),b(0),a(1) {} /// Constructor set color from character id mglColor(char c, float bright=1) { Set(c,bright); } /// Copy constructor mglColor(const mglColor &d):r(d.r),g(d.g),b(d.b),a(d.a) {} #if MGL_HAVE_RVAL mglColor(mglColor &&d):r(d.r),g(d.g),b(d.b),a(d.a) {} #endif /// Set color as Red, Green, Blue values void Set(float R,float G,float B,float A=1) { r=R; g=G; b=B; a=A; } /// Set color as Red, Green, Blue values void Set(mglColor c, float bright=1) { if(bright<0) bright=0; if(bright>2.f) bright=2.f; if(bright<=1) { r=c.r*bright; g=c.g*bright; b=c.b*bright; a = 1; } else { r=1-(1-c.r)*(2-bright); g=1-(1-c.g)*(2-bright); b=1-(1-c.b)*(2-bright); a=1; } } /// Check if color is valid inline bool Valid() const { return ((r>=0) & (r<=1) & (g>=0) & (g<=1) & (b>=0) & (b<=1) & (a>=0) & (a<=1)); } /// Get maximal spectral component inline float Norm() const { return r>g ? r : (g>b ? g : b); } inline float NormS() const { return r*r+g*g+b*b; } /// Set color from symbolic id inline void Set(char p, float bright=1) { float rgb[3]; mgl_chrrgb(p,rgb); Set(mglColor(rgb[0],rgb[1],rgb[2]),bright); } inline const mglColor &operator=(const mglColor &p) { r=p.r; g=p.g; b=p.b; a=p.a; return p; } /// Copy color from other one inline bool operator==(const mglColor &c) const // NOTE: exact comparison is used here { return (r-c.r)*(r-c.r)+(g-c.g)*(g-c.g)+(b-c.b)*(b-c.b)+(a-c.a)*(a-c.a)==0; } // { return !memcmp(this, &c, sizeof(mglColor)); } inline bool operator!=(const mglColor &c) const // NOTE: exact comparison is used here { return (r-c.r)*(r-c.r)+(g-c.g)*(g-c.g)+(b-c.b)*(b-c.b)+(a-c.a)*(a-c.a)!=0; } // { return memcmp(this, &c, sizeof(mglColor)); } inline bool operator<(const mglColor &c) const { return memcmp(this, &c, sizeof(mglColor))<0; } // transparency still the same inline void operator*=(float v) { r*=v; g*=v; b*=v; a*=v; } inline void operator+=(const mglColor &c) { r+=c.r; g+=c.g; b+=c.b; a+=c.a; } inline void operator-=(const mglColor &c) { r-=c.r; g-=c.g; b-=c.b; a-=c.a; } }; #ifndef SWIG inline mglColor operator+(const mglColor &a, const mglColor &b) { return mglColor(a.r+b.r, a.g+b.g, a.b+b.b, a.a+b.a); } inline mglColor operator-(const mglColor &a, const mglColor &b) { return mglColor(a.r-b.r, a.g-b.g, a.b-b.b, a.a-b.a); } inline mglColor operator*(const mglColor &a, float b) { return mglColor(a.r*b, a.g*b, a.b*b, a.a*b); } inline mglColor operator*(float b, const mglColor &a) { return mglColor(a.r*b, a.g*b, a.b*b, a.a*b); } inline float operator*(const mglColor &b, const mglColor &a) { return a.r*b.r+a.g*b.g+a.b*b.b; } inline mglColor operator/(const mglColor &a, float b) { return mglColor(a.r/b, a.g/b, a.b/b, a.a/b); } inline mglColor operator!(const mglColor &a) { return mglColor(1-a.r, 1-a.g, 1-a.b, a.a); } #endif //----------------------------------------------------------------------------- #ifndef SWIG /// Class for Unicode string. /** NOTE: mglString accept multi-byte char* string for converting to wchar_t*. But it keep only single-byte char*!!! */ struct MGL_EXPORT mglString { char *s; wchar_t *w; mglString() { s=new char[1]; w=new wchar_t[1]; *s=*w=0; } mglString(const mglString &str) { size_t ls = wcslen(str.w)+1; s = new char[ls]; memcpy(s,str.s,ls); w = new wchar_t[ls]; memcpy(w,str.w,ls*sizeof(wchar_t)); } #if MGL_HAVE_RVAL mglString(mglString &&d):s(d.s),w(d.w) { d.s=NULL; d.w=NULL; } #endif mglString(const char *str) { if(str) { size_t ls=mbstowcs(0,str,0); w = new wchar_t[ls+1]; mbstowcs(w,str,ls); w[ls]=0; s = new char[ls+1]; for(size_t i=0;i<=ls;i++) s[i]=w[i]; } else { s=new char[1]; w=new wchar_t[1]; *s=*w=0; } } mglString(const wchar_t *str) { if(str) { size_t len=wcslen(str); w = new wchar_t[len+1]; s = new char[len+1]; for(size_t i=0;i<=len;i++) s[i]=w[i]=str[i]; } else { s=new char[1]; w=new wchar_t[1]; *s=*w=0; } } mglString(const std::string &str) { size_t ls=mbstowcs(0,str.c_str(),0); w = new wchar_t[ls+1]; mbstowcs(w,str.c_str(),ls); w[ls]=0; s = new char[ls+1]; for(size_t i=0;i<=ls;i++) s[i]=w[i]; } mglString(const std::wstring &str) { size_t len=str.length(); w = new wchar_t[len+1]; s = new char[len+1]; for(size_t i=0;i<=len;i++) s[i]=w[i]=str[i]; } ~mglString() { if(w) { delete []s; delete []w; } } /// String length size_t length() const { return wcslen(w); } /// Crop string (like std::string::substr()) void crop(size_t pos, size_t len=size_t(-1)) { if(pos) for(size_t i=0;i * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ //----------------------------------------------------------------------------- #ifndef _MGL_GLUT_H_ #define _MGL_GLUT_H_ #ifdef __cplusplus #include //----------------------------------------------------------------------------- extern "C" { #endif void _mgl_key_up(unsigned char ch,int ,int ); HMGL MGL_EXPORT mgl_create_graph_glut(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p)); /// Switch on/off transparency (do not overwrite user settings) void MGL_EXPORT mgl_glut_toggle_alpha(HMGL gr); /// Switch on/off lighting (do not overwrite user settings) void MGL_EXPORT mgl_glut_toggle_light(HMGL gr); /// Switch off all zooming and rotation void MGL_EXPORT mgl_glut_toggle_no(HMGL gr); /// Update picture by calling user drawing function void MGL_EXPORT mgl_glut_update(HMGL gr); /// Reload user data and update picture void MGL_EXPORT mgl_glut_reload(HMGL gr); /// Show next frame (if one) void MGL_EXPORT mgl_glut_next_frame(HMGL gr); /// Show previous frame (if one) void MGL_EXPORT mgl_glut_prev_frame(HMGL gr); /// Run slideshow (animation) of frames void MGL_EXPORT mgl_glut_animation(HMGL gr); #ifdef __cplusplus } //----------------------------------------------------------------------------- class MGL_EXPORT mglGLUT: public mglGraph { mglGLUT(const mglGLUT &) {} // copying is not allowed const mglGLUT &operator=(const mglGLUT &t) { return t; } public: mglGLUT(int (*draw)(HMGL gr, void *p), const char *title="MathGL", void *par=0, void (*load)(void *p)=0) : mglGraph(-1) { gr = mgl_create_graph_glut(draw,title,par,load); } mglGLUT(int (*draw)(mglGraph *gr), const char *title="MathGL") : mglGraph(-1) { gr = mgl_create_graph_glut(draw?mgl_draw_graph:0,title,(void*)draw,0); } mglGLUT(mglDraw *draw=0, const char *title="MathGL") : mglGraph(-1) { gr = mgl_create_graph_glut(draw?mgl_draw_class:0,title,draw,mgl_reload_class); } virtual ~mglGLUT() {} inline void ToggleAlpha() ///< Switch on/off transparency (do not overwrite user settings) { mgl_glut_toggle_alpha(gr); } inline void ToggleLight() ///< Switch on/off lighting (do not overwrite user settings) { mgl_glut_toggle_light(gr); } inline void ToggleNo() ///< Switch off all zooming and rotation { mgl_glut_toggle_no(gr); } inline void Update() ///< Update picture by calling user drawing function { mgl_glut_update(gr); } inline void ReLoad() ///< Reload user data and update picture { mgl_glut_reload(gr); } inline void NextFrame() ///< Show next frame (if one) { mgl_glut_next_frame(gr); } inline void PrevFrame() ///< Show previous frame (if one) { mgl_glut_prev_frame(gr); } inline void Animation() ///< Run slideshow (animation) of frames { mgl_glut_animation(gr); } inline int Run() {return 0;}; ///< Run main loop for event handling (placed for similarity to mglWnd) }; //----------------------------------------------------------------------------- #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/data.h��������������������������������������������������������������������0000644�0001750�0001750�00000152371�13513030041�016524� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * data.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_DATA_H_ #define _MGL_DATA_H_ #include "mgl2/data_cf.h" #include "mgl2/pde.h" //----------------------------------------------------------------------------- #include //----------------------------------------------------------------------------- mreal MGL_EXPORT_PURE mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); mreal MGL_EXPORT mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0); mreal MGL_EXPORT_PURE mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); //----------------------------------------------------------------------------- /// Class for working with data array class MGL_EXPORT mglData : public mglDataA { public: using mglDataA::Momentum; long nx; ///< number of points in 1st dimensions ('x' dimension) long ny; ///< number of points in 2nd dimensions ('y' dimension) long nz; ///< number of points in 3d dimensions ('z' dimension) mreal *a; ///< data array bool link; ///< use external data (i.e. don't free it) /// Initiate by other mglData variable mglData(const mglData &d) { a=0; mgl_data_set(this,&d); } // NOTE: must be constructor for mglData& to exclude copy one #if MGL_HAVE_RVAL mglData(mglData &&d):nx(d.nx),ny(d.ny),nz(d.nz),a(d.a),link(d.link) { s=d.s; temp=d.temp; func=d.func; o=d.o; id=d.id; d.a=0; d.func=0; } #endif mglData(const mglDataA *d) { a=0; if(d) mgl_data_set(this, d); else mgl_data_create(this,1,1,1); } mglData(bool, mglData *d) // NOTE: Variable d will be deleted!!! { if(d) { nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=0; temp=d->temp; func=d->func; o=d->o; s=d->s; id=d->id; link=d->link; delete d; } else { a=0; Create(1); } } /// Initiate by flat array mglData(int size, const float *d) { a=0; Set(d,size); } mglData(int rows, int cols, const float *d) { a=0; Set(d,cols,rows); } mglData(int size, const double *d) { a=0; Set(d,size); } mglData(int rows, int cols, const double *d) { a=0; Set(d,cols,rows); } mglData(const double *d, int size) { a=0; Set(d,size); } mglData(const double *d, int rows, int cols) { a=0; Set(d,cols,rows); } mglData(const float *d, int size) { a=0; Set(d,size); } mglData(const float *d, int rows, int cols) { a=0; Set(d,cols,rows); } /// Allocate memory and copy data from std::vector mglData(const std::vector &d) { a=0; Set(d); } mglData(const std::vector &d) { a=0; Set(d); } mglData(const std::vector &d) { a=0; Set(d); } /// Read data from file mglData(const char *fname) { a=0; Read(fname); } /// Allocate the memory for data array and initialize it zero mglData(long xx=1,long yy=1,long zz=1) { a=0; Create(xx,yy,zz); } /// Delete the array virtual ~mglData() { if(!link && a) delete []a; } /// Move all data from variable d, and delete this variable. inline void Move(mglData *d) // NOTE: Variable d will be deleted!!! { if(d && d->GetNN()>1) { bool l=link; mreal *b=a; nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=b; temp=d->temp; func=d->func; o=d->o; s=d->s; id=d->id; link=d->link; d->link=l; delete d; } else if(d) { *this = d->a[0]; delete d; } } inline mreal GetVal(long i, long j=0, long k=0) const { return mgl_data_get_value(this,i,j,k);} inline void SetVal(mreal f, long i, long j=0, long k=0) { mgl_data_set_value(this,f,i,j,k); } /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } long GetNz() const { return nz; } /// Link external data array (don't delete it at exit) inline void Link(mreal *A, long NX, long NY=1, long NZ=1) { mgl_data_link(this,A,NX,NY,NZ); } inline void Link(mglData &d) { Link(d.a,d.nx,d.ny,d.nz); } /// Allocate memory and copy the data from the gsl_vector inline void Set(gsl_vector *m) { mgl_data_set_vector(this,m); } /// Allocate memory and copy the data from the gsl_matrix inline void Set(gsl_matrix *m) { mgl_data_set_matrix(this,m); } /// Allocate memory and copy the data from the (float *) array inline void Set(const float *A,long NX,long NY=1,long NZ=1) { mgl_data_set_float(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (double *) array inline void Set(const double *A,long NX,long NY=1,long NZ=1) { mgl_data_set_double(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (float **) array inline void Set(float const * const *A,long N1,long N2) { mgl_data_set_float2(this,A,N1,N2); } /// Allocate memory and copy the data from the (double **) array inline void Set(double const * const *A,long N1,long N2) { mgl_data_set_double2(this,A,N1,N2); } /// Allocate memory and copy the data from the (float ***) array inline void Set(float const * const * const *A,long N1,long N2,long N3) { mgl_data_set_float3(this,A,N1,N2,N3); } /// Allocate memory and copy the data from the (double ***) array inline void Set(double const * const * const *A,long N1,long N2,long N3) { mgl_data_set_double3(this,A,N1,N2,N3); } /// Allocate memory and scanf the data from the string inline void Set(const char *str,long NX,long NY=1,long NZ=1) { mgl_data_set_values(this,str,NX,NY,NZ); } /// Import data from abstract type inline void Set(HCDT dat) { mgl_data_set(this, dat); } inline void Set(const mglDataA &dat) { mgl_data_set(this, &dat); } /// Allocate memory and copy data from std::vector inline void Set(const std::vector &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i &d) { if(d.size()>0) Set(&(d[0]),d.size()); else Create(1); } inline void Set(const std::vector &d) { if(d.size()>0) Set(&(d[0]),d.size()); else Create(1); } /// Allocate memory and set data from variable argument list of double values inline void SetList(long n, ...) { if(n<1) return; mgl_data_create(this,n,1,1); va_list vl; va_start(vl,n); for(long i=0;i0? (i0? (j0? (k(const mglDataA &b, const mglDataA &d) { return b.Minimal()>d.Minimal(); } //----------------------------------------------------------------------------- /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase inline mglData mglTransformA(const mglDataA &am, const mglDataA &ph, const char *tr) { return mglData(true,mgl_transform_a(&am,&ph,tr)); } /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for real and imaginary parts inline mglData mglTransform(const mglDataA &re, const mglDataA &im, const char *tr) { return mglData(true,mgl_transform(&re,&im,tr)); } /// Apply Fourier transform for the data and save result into it inline void mglFourier(mglData &re, mglData &im, const char *dir) { mgl_data_fourier(&re,&im,dir); } /// Short time Fourier analysis for real and imaginary parts. Output is amplitude of partial Fourier (result will have size {dn, floor(nx/dn), ny} for dir='x' inline mglData mglSTFA(const mglDataA &re, const mglDataA &im, long dn, char dir='x') { return mglData(true, mgl_data_stfa(&re,&im,dn,dir)); } //----------------------------------------------------------------------------- /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini inline mglData mglPDE(HMGL gr, const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="") { return mglData(true, mgl_pde_solve(gr,ham, &ini_re, &ini_im, dz, k0,opt)); } /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo2d_solve(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0)); } inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo2d_solve(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy)); } /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo3d_solve(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0, 0)); } inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mglData &zz, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo3d_solve(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz)); } /// Finds ray with starting point r0, p0 (and prepares ray data for mglQO2d) inline mglData mglRay(const char *ham, mglPoint r0, mglPoint p0, mreal dt=0.1, mreal tmax=10) { return mglData(true, mgl_ray_trace(ham, r0.x, r0.y, r0.z, p0.x, p0.y, p0.z, dt, tmax)); } /// Saves result of ODE solving for var complex variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt inline mglData mglODE(const char *func, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10) { return mglData(true, mgl_ode_solve_str(func,var, &ini, dt, tmax)); } //----------------------------------------------------------------------------- /// Get array as solution of tridiagonal system of equations a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i] /** String \a how may contain: * 'x', 'y', 'z' for solving along x-,y-,z-directions, or * 'h' for solving along hexagonal direction at x-y plain (need nx=ny), * 'c' for using periodical boundary conditions, * 'd' for diffraction/diffuse calculation. */ inline mglData mglTridMat(const mglDataA &A, const mglDataA &B, const mglDataA &C, const mglDataA &D, const char *how) { return mglData(true, mgl_data_tridmat(&A, &B, &C, &D, how)); } //----------------------------------------------------------------------------- /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du inline mglData mglJacobian(const mglDataA &x, const mglDataA &y) { return mglData(true, mgl_jacobian_2d(&x, &y)); } /// Calculate Jacobian determinant for D{x(u,v,w), y(u,v,w), z(u,v,w)} inline mglData mglJacobian(const mglDataA &x, const mglDataA &y, const mglDataA &z) { return mglData(true, mgl_jacobian_3d(&x, &y, &z)); } /// Do something like Delone triangulation inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y, const mglDataA &z) { return mglData(true,mgl_triangulation_3d(&x,&y,&z)); } inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y) { return mglData(true,mgl_triangulation_2d(&x,&y)); } /// Get curves, separated by NAN, for maximal values of array d as function of x coordinate. /** Noises below lvl amplitude are ignored. * Parameter dy \in [0,ny] set the "attraction" distance of points to curve. */ inline mglData mglDetect(const mglDataA &d, mreal lvl, mreal dj, mreal di=0, mreal min_len=0) { return mglData(true,mgl_data_detect(&d, lvl, dj, di, min_len)); } //----------------------------------------------------------------------------- /// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A inline mglData mglIFS2d(const mglDataA &A, long n, long skip=20) { return mglData(true,mgl_data_ifs_2d(&A,n,skip)); } /// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A inline mglData mglIFS3d(const mglDataA &A, long n, long skip=20) { return mglData(true,mgl_data_ifs_3d(&A,n,skip)); } /// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) defined in *.ifs file 'fname' and named as 'name' inline mglData mglIFSfile(const char *fname, const char *name, long n, long skip=20) { return mglData(true,mgl_data_ifs_file(fname,name,n,skip)); } /// Get array which is n-th pairs {x[i],y[i]} for Flame fractal generated by A with functions F /** NOTE: A.nx must be >= 7 and F.nx >= 2 and F.nz=A.ny. * F[0,i,j] denote function id. F[1,i,j] give function weight, F(2:5,i,j) provide function parameters. * Resulting point is {xnew,ynew} = sum_i F[1,i,j]*F[0,i,j]{IFS2d(A[j]){x,y}}. */ inline mglData mglFlame2d(const mglDataA &A, const mglDataA &F, long n, long skip=20) { return mglData(true,mgl_data_flame_2d(&A,&F,n,skip)); } //----------------------------------------------------------------------------- /// Get sub-array of the data with given fixed indexes inline mglData mglSubData(const mglDataA &dat, long xx, long yy=-1, long zz=-1) { return mglData(true,mgl_data_subdata(&dat,xx,yy,zz)); } inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) { return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,&zz)); } inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy) { return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,0)); } inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx) { return mglData(true,mgl_data_subdata_ext(&dat,&xx,0,0)); } //----------------------------------------------------------------------------- /// Prepare coefficients for global spline interpolation inline mglData mglGSplineInit(const mglDataA &xdat, const mglDataA &ydat) { return mglData(true,mgl_gspline_init(&xdat, &ydat)); } /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef inline mreal mglGSpline(const mglDataA &coef, mreal dx, mreal *d1=0, mreal *d2=0) { return mgl_gspline(&coef, dx, d1,d2); } //----------------------------------------------------------------------------- /// Wrapper class for expression evaluating class MGL_EXPORT mglExpr { HMEX ex; mglExpr(const mglExpr &){} // copying is not allowed const mglExpr &operator=(const mglExpr &t){return t;} // copying is not allowed public: mglExpr(const char *expr) { ex = mgl_create_expr(expr); } #if MGL_HAVE_RVAL mglExpr(mglExpr &&d):ex(d.ex) { d.ex=0; } #endif ~mglExpr() { mgl_delete_expr(ex); } /// Return value of expression for given x,y,z variables inline double Eval(double x, double y=0, double z=0) { return mgl_expr_eval(ex,x,y,z); } /// Return value of expression differentiation over variable dir for given x,y,z variables inline double Diff(char dir, double x, double y=0, double z=0) { return mgl_expr_diff(ex,dir, x,y,z); } #ifndef SWIG /// Return value of expression for given variables inline double Eval(mreal var[26]) { return mgl_expr_eval_v(ex,var); } /// Return value of expression differentiation over variable dir for given variables inline double Diff(char dir, mreal var[26]) { return mgl_expr_diff_v(ex,dir, var); } #endif }; //----------------------------------------------------------------------------- /// Class which present equidistantly distributed data class MGL_EXPORT mglDataV : public mglDataA { long nx; ///< number of points in 1st dimensions ('x' dimension) long ny; ///< number of points in 2nd dimensions ('y' dimension) long nz; ///< number of points in 3d dimensions ('z' dimension) mreal di, dj, dk, a0; public: mglDataV(long xx=1,long yy=1,long zz=1,mreal x1=0,mreal x2=mglNaN,char dir='x'):nx(xx),ny(yy),nz(zz) { Fill(x1,x2,dir); } mglDataV(const mglDataV &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0) {} #if MGL_HAVE_RVAL mglDataV(mglDataV &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataV() {} /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } long GetNz() const { return nz; } /// Create or recreate the array with specified size and fill it by zero inline void Create(long mx,long my=1,long mz=1) { di=mx>1?di*(nx-1)/(mx-1):0; dj=my>1?dj*(ny-1)/(my-1):0; dk=mz>1?dk*(nz-1)/(mz-1):0; nx=mx; ny=my; nz=mz; } /// For going throw all elements inline void All() { di=dj=dk=1; a0=0; } /// Equidistantly fill the data to range [x1,x2] in direction dir inline void Fill(mreal x1,mreal x2=mglNaN,char dir='x') { di=dj=dk=0; a0=x1; if(mgl_isnum(x2)) { if(dir=='x' && nx>1) di=(x2-x1)/(nx-1); if(dir=='y' && ny>1) dj=(x2-x1)/(ny-1); if(dir=='z' && nz>1) dk=(x2-x1)/(nz-1); } } mreal Maximal() const { return a0+mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0)); } mreal Minimal() const { return a0+mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0)); } /// Copy data from other mglDataV variable inline const mglDataV &operator=(const mglDataV &d) { nx=d.nx; ny=d.ny; nz=d.nz; a0=d.a0; di=d.di; dj=d.dj; dk=d.dk; return d; } inline mreal operator=(mreal val) { di=dj=dk=0; a0=val; return val; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dx) *dx=di; if(dy) *dy=dj; if(dz) *dz=dk; return a0+di*x+dj*y+dk*z; } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal y=0,mreal z=0) const { return a0+di*x+dj*y+dk*z; } mreal v(long i,long j=0,long k=0) const { return a0+di*i+dj*j+dk*k; } mreal vthr(long ii) const { long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny); return a0+di*i+dj*j+dk*k; } // add for speeding up !!! mreal dvx(long ,long =0,long =0) const { return di; } mreal dvy(long ,long =0,long =0) const { return dj; } mreal dvz(long ,long =0,long =0) const { return dk; } }; //----------------------------------------------------------------------------- /// Class which present FFT frequency as data array class MGL_EXPORT mglDataW : public mglDataA { long nx; ///< number of points in 1st dimensions ('x' dimension) long ny; ///< number of points in 2nd dimensions ('y' dimension) long nz; ///< number of points in 3d dimensions ('z' dimension) mreal di, dj, dk; public: mglDataW(long xx=1,long yy=1,long zz=1,mreal dp=0,char dir='x'):nx(xx),ny(yy),nz(zz) { Freq(dp,dir); } mglDataW(const mglDataW &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk) {} #if MGL_HAVE_RVAL mglDataW(mglDataW &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataW() {} /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } long GetNz() const { return nz; } /// Create or recreate the array with specified size and fill it by zero inline void Create(long mx,long my=1,long mz=1) { nx=mx; ny=my; nz=mz; } /// For going throw all elements inline void All() { di=dj=dk=1; } /// Equidistantly fill the data to range [x1,x2] in direction dir inline void Freq(mreal dp,char dir='x') { di=dj=dk=0; if(dir=='x') di=dp; if(dir=='y') dj=dp; if(dir=='z') dk=dp; } mreal Maximal() const { return mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0)); } mreal Minimal() const { return mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0)); } /// Copy data from other mglDataV variable inline const mglDataW &operator=(const mglDataW &d) { nx=d.nx; ny=d.ny; nz=d.nz; di=d.di; dj=d.dj; dk=d.dk; return d; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dx) *dx=di; if(dy) *dy=dj; if(dz) *dz=dk; return di*(x1?(v2.x-v1.x)/(nx-1):0; dy = ny>1?(v2.y-v1.y)/(ny-1):0; dz = nz>1?(v2.z-v1.z)/(nz-1):0; } mreal (*dfunc)(mreal i, mreal j, mreal k, void *par); void *par; public: mglDataF(long xx=1,long yy=1,long zz=1):nx(xx),ny(yy),nz(zz), dfunc(0),par(0) { ex=0; v2.Set(1,1,1); setD(); } mglDataF(const mglDataF &d) : nx(d.nx), ny(d.ny), nz(d.nz), str(d.str), v1(d.v1), v2(d.v2), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par) { ex = mgl_create_expr(str.c_str()); } #if MGL_HAVE_RVAL mglDataF(mglDataF &&d):nx(d.nx),ny(d.ny),nz(d.nz), str(d.str), v1(d.v1),v2(d.v2), ex(d.ex), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.ex=0; d.func=0; } #endif virtual ~mglDataF() { mgl_delete_expr(ex); } /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } long GetNz() const { return nz; } /// Create or recreate the array with specified size and fill it by zero inline void Create(long mx,long my=1,long mz=1) { nx=mx; ny=my; nz=mz; setD(); } inline void SetRanges(mglPoint p1, mglPoint p2) { v1=p1; v2=p2; setD(); } /// Set formula to be used as dfunction inline void SetFormula(const char *eq) { mgl_delete_expr(ex); dfunc=0; par=0; if(eq && *eq) { ex = mgl_create_expr(eq); str=eq; } else { ex=0; str=""; } } /// Set function and coordinates range [r1,r2] inline void SetFunc(mreal (*f)(mreal,mreal,mreal,void*), void *p=NULL) { mgl_delete_expr(ex); ex=0; dfunc=f; par=p; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal i,mreal j=0,mreal k=0, mreal *di=0,mreal *dj=0,mreal *dk=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(di) *di = 0; if(dj) *dj = 0; if(dk) *dk = 0; if(dfunc) { res = dfunc(x,y,z, par); if(di) *di = dfunc(x+dx,y,z, par)-res; if(dj) *dj = dfunc(x,y+dy,z, par)-res; if(dk) *dk = dfunc(x,y,z+dz, par)-res; } else if(ex) { if(di) *di = mgl_expr_diff(ex,'x',x,y,z)*dx; if(dj) *dj = mgl_expr_diff(ex,'y',x,y,z)*dy; if(dk) *dk = mgl_expr_diff(ex,'z',x,y,z)*dz; res = mgl_expr_eval(ex,x,y,z); } return res; } /// Get the interpolated value in given data cell without border checking mreal value(mreal i,mreal j=0,mreal k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z); return res; } /// Copy data from other mglDataV variable inline const mglDataF &operator=(const mglDataF &d) { nx=d.nx; ny=d.ny; nz=d.nz; v1=d.v1; v2=d.v2; setD(); mgl_delete_expr(ex); str=d.str; ex = mgl_create_expr(str.c_str()); dfunc=d.dfunc; par=d.par; return d; } /// Get the value in given cell of the data without border checking mreal v(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z); return res; } mreal vthr(long i) const { mreal res=0, x=v1.x+dx*(i%nx), y=v1.y+dy*((i/nx)%ny), z=v1.z+dz*(i/(nx*ny)); if(dfunc) res = dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z); return res; } // add for speeding up !!! mreal dvx(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x+dx,y,z, par)-dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x+dx,y,z)-mgl_expr_eval(ex,x,y,z); return res; } mreal dvy(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y+dy,z, par)-dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y+dy,z)-mgl_expr_eval(ex,x,y,z); return res; } mreal dvz(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y,z+dz, par)-dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z+dz)-mgl_expr_eval(ex,x,y,z); return res; } }; //----------------------------------------------------------------------------- /// Class which present column of another data as data array class MGL_EXPORT mglDataT : public mglDataA { const mglDataA &dat; long ind; const mglDataT &operator=(const mglDataT &d) { return d; } public: mglDataT(const mglDataT &d) : dat(d.dat), ind(d.ind) { s = d.s; } mglDataT(const mglDataA &d, long col=0) : dat(d), ind(col) {} mglDataT(HCDT d, long col=0) : dat(*d), ind(col) {} #if MGL_HAVE_RVAL mglDataT(mglDataT &&d):dat(d.dat),ind(d.ind) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataT() {} /// Get sizes long GetNx() const { return dat.GetNy(); } long GetNy() const { return dat.GetNz(); } long GetNz() const { return 1; } mreal Maximal() const { return mglSubData(dat,ind).Maximal(); } mreal Minimal() const { return mglSubData(dat,ind).Minimal(); } inline void SetInd(long i, const wchar_t *name) { ind = i; s = name; } inline void SetInd(long i, wchar_t name) { ind = i; s = name; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal y=0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dz) *dz=0; return dat.valueD(ind,x,y,0,dx,dy); } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal y=0,mreal =0) const { return dat.value(ind,x,y); } /// Get the value in given cell of the data without border checking mreal v(long i,long j=0,long =0) const { return dat.v(ind,i,j); } mreal vthr(long i) const { return dat.vthr(ind+dat.GetNx()*i); } // add for speeding up !!! mreal dvx(long i,long j=0,long =0) const { return dat.dvy(ind,i,j); } mreal dvy(long i,long j=0,long =0) const { return dat.dvz(ind,i,j); } mreal dvz(long ,long =0,long =0) const { return 0; } }; //----------------------------------------------------------------------------- /// Class which present row of another data as data array class MGL_EXPORT mglDataR : public mglDataA { const mglDataA &dat; long ind; const mglDataR &operator=(const mglDataR &d) { return d; } public: mglDataR(const mglDataR &d) : dat(d.dat), ind(d.ind) { s = d.s; } mglDataR(const mglDataA &d, long row=0) : dat(d), ind(row) {} mglDataR(HCDT d, long row=0) : dat(*d), ind(row) {} #if MGL_HAVE_RVAL mglDataR(mglDataR &&d):dat(d.dat),ind(d.ind) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataR() {} /// Get sizes long GetNx() const { return dat.GetNx(); } long GetNy() const { return 1; } long GetNz() const { return 1; } mreal Maximal() const { return mglSubData(dat,-1,ind).Maximal(); } mreal Minimal() const { return mglSubData(dat,-1,ind).Minimal(); } inline void SetInd(long i, const wchar_t *name) { ind = i; s = name; } inline void SetInd(long i, wchar_t name) { ind = i; s = name; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal =0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dy) *dy=0; if(dz) *dz=0; return dat.valueD(x,ind,0,dx); } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal =0,mreal =0) const { return dat.value(x,ind,0); } /// Get the value in given cell of the data without border checking mreal v(long i,long =0,long =0) const { return dat.v(i,ind,0); } mreal vthr(long i) const { return dat.vthr(i+dat.GetNx()*ind); } // add for speeding up !!! mreal dvx(long i,long =0,long =0) const { return dat.dvx(i,ind,0); } mreal dvy(long ,long =0,long =0) const { return 0; } mreal dvz(long ,long =0,long =0) const { return 0; } }; //----------------------------------------------------------------------------- /// Class which present std::vector as data array class MGL_EXPORT mglDataS : public mglDataA { public: std::vector dat; mglDataS(const mglDataS &st) : dat(st.dat) {} mglDataS(const std::vector &d) : dat(d) {} mglDataS(size_t s=1) { dat.resize(s); } ~mglDataS() {} inline void reserve(size_t num) { dat.reserve(num); } inline void clear() { dat.clear(); } inline double operator[](size_t i) { return dat[i]; } inline void push_back(double t) { dat.push_back(t); } inline size_t size() const { return dat.size(); } const mglDataS &operator=(const mglDataS &st) { dat = st.dat; return st; } const std::vector &operator=(const std::vector &st) { dat = st; return st; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal =0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { return mglSpline3(dat.data(),dat.size(),1,1,x,0,0,dx,dy,dz); } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal =0,mreal =0) const { return mglSpline3s(dat.data(),dat.size(),1,1,x,0,0); } mreal v(long i,long =0,long =0) const { return dat[i]; } mreal vthr(long i) const { return dat[i]; } long GetNx() const { return dat.size(); } long GetNy() const { return 1; } long GetNz() const { return 1; } mreal dvx(long i,long =0,long =0) const { return i>0? (i * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_DATAC_CF_H_ #define _MGL_DATAC_CF_H_ //----------------------------------------------------------------------------- #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #if MGL_HAVE_GSL #include #include #else struct gsl_vector; struct gsl_matrix; #endif //----------------------------------------------------------------------------- #ifdef __cplusplus class mglDataC; typedef mglDataC* HADT; extern "C" { #else typedef void *HADT; #endif /// Get integer power of x cmdual MGL_EXPORT_CONST mgl_ipowc(mdual x,int n); cmdual MGL_EXPORT_PURE mgl_ipowc_(mdual *x,int *n); /// Get complex number from string. Parse (%g,%g), {%g,%g} and [%g,%g] if adv!=0. cmdual MGL_EXPORT mgl_atoc(const char *s, int adv); /// Get exp(i*a) cmdual MGL_EXPORT_CONST mgl_expi(mdual a); /// Create HMDT object HADT MGL_EXPORT mgl_create_datac(); uintptr_t MGL_EXPORT mgl_create_datac_(); /// Create HMDT object with specified sizes HADT MGL_EXPORT mgl_create_datac_size(long nx, long ny, long nz); uintptr_t MGL_EXPORT mgl_create_datac_size_(int *nx, int *ny, int *nz); /// Create HMDT object with data from file HADT MGL_EXPORT mgl_create_datac_file(const char *fname); uintptr_t MGL_EXPORT mgl_create_datac_file_(const char *fname, int len); /// Delete HMDT object void MGL_EXPORT mgl_delete_datac(HADT dat); void MGL_EXPORT mgl_delete_datac_(uintptr_t *dat); /// Rearange data dimensions void MGL_EXPORT mgl_datac_rearrange(HADT dat, long mx,long my,long mz); void MGL_EXPORT mgl_datac_rearrange_(uintptr_t *dat, int *mx, int *my, int *mz); /// Link external data array (don't delete it at exit) void MGL_EXPORT mgl_datac_link(HADT dat, mdual *A,long mx,long my,long mz); void MGL_EXPORT mgl_datac_link_(uintptr_t *d, mdual *A, int *nx,int *ny,int *nz); /// Allocate memory and copy the data from the (float *) array void MGL_EXPORT mgl_datac_set_float(HADT dat, const float *A,long mx,long my,long mz); void MGL_EXPORT mgl_datac_set_float_(uintptr_t *dat, const float *A,int *NX,int *NY,int *NZ); /// Allocate memory and copy the data from the (double *) array void MGL_EXPORT mgl_datac_set_double(HADT dat, const double *A,long mx,long my,long mz); void MGL_EXPORT mgl_datac_set_double_(uintptr_t *dat, const double *A,int *NX,int *NY,int *NZ); /// Allocate memory and copy the data from the (dual *) array void MGL_EXPORT mgl_datac_set_complex(HADT dat, const mdual *A,long mx,long my,long mz); void MGL_EXPORT mgl_datac_set_complex_(uintptr_t *d, const mdual *A,int *NX,int *NY,int *NZ); /// Import data from abstract type void MGL_EXPORT mgl_datac_set(HADT dat, HCDT a); void MGL_EXPORT mgl_datac_set_(uintptr_t *dat, uintptr_t *a); /// Allocate memory and copy the data from the gsl_vector void MGL_EXPORT mgl_datac_set_vector(HADT dat, gsl_vector *v); /// Allocate memory and copy the data from the gsl_matrix void MGL_EXPORT mgl_datac_set_matrix(HADT dat, gsl_matrix *m); /// Set value of data element [i,j,k] void MGL_EXPORT mgl_datac_set_value(HADT dat, mdual v, long i, long j, long k); void MGL_EXPORT mgl_datac_set_value_(uintptr_t *d, mdual *v, int *i, int *j, int *k); /// Get value of data element [i,j,k] cmdual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k); cmdual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k); /// Allocate memory and scanf the data from the string void MGL_EXPORT mgl_datac_set_values(HADT dat, const char *val, long nx, long ny, long nz); void MGL_EXPORT mgl_datac_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l); /// Get array as solution of tridiagonal matrix solution a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i] /** String \a how may contain: * 'x', 'y', 'z' for solving along x-,y-,z-directions, or * 'h' for solving along hexagonal direction at x-y plain (need nx=ny), * 'c' for using periodical boundary conditions, * 'd' for diffraction/diffuse calculation. * NOTE: It work for flat data model only (i.e. for a[i,j]==a[i+nx*j]) */ HADT MGL_EXPORT mgl_datac_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how); uintptr_t MGL_EXPORT mgl_datac_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int); /// Returns pointer to internal data array MGL_EXPORT_PURE mdual *mgl_datac_data(HADT dat); /// Returns pointer to data element [i,j,k] MGL_EXPORT mdual *mgl_datac_value(HADT dat, long i,long j,long k); /// Set the data from HCDT objects for real and imaginary parts void MGL_EXPORT mgl_datac_set_ri(HADT dat, HCDT re, HCDT im); void MGL_EXPORT mgl_datac_set_ri_(uintptr_t *dat, uintptr_t *re, uintptr_t *im); /// Set the data from HCDT objects as amplitude and phase of complex data void MGL_EXPORT mgl_datac_set_ap(HADT dat, HCDT abs, HCDT phi); void MGL_EXPORT mgl_datac_set_ap_(uintptr_t *dat, uintptr_t *abs, uintptr_t *phi); /// Read data from tab-separated text file with auto determining size int MGL_EXPORT mgl_datac_read(HADT dat, const char *fname); int MGL_EXPORT mgl_datac_read_(uintptr_t *d, const char *fname,int l); /// Read data from text file with size specified at beginning of the file int MGL_EXPORT mgl_datac_read_mat(HADT dat, const char *fname, long dim); int MGL_EXPORT mgl_datac_read_mat_(uintptr_t *dat, const char *fname, int *dim, int); /// Read data from text file with specifeid size int MGL_EXPORT mgl_datac_read_dim(HADT dat, const char *fname,long mx,long my,long mz); int MGL_EXPORT mgl_datac_read_dim_(uintptr_t *dat, const char *fname,int *mx,int *my,int *mz,int); /// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to int MGL_EXPORT mgl_datac_read_range(HADT d, const char *templ, double from, double to, double step, int as_slice); int MGL_EXPORT mgl_datac_read_range_(uintptr_t *d, const char *fname, mreal *from, mreal *to, mreal *step, int *as_slice,int l); /// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat") int MGL_EXPORT mgl_datac_read_all(HADT dat, const char *templ, int as_slice); int MGL_EXPORT mgl_datac_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l); /// Save whole data array (for ns=-1) or only ns-th slice to text file void MGL_EXPORT mgl_datac_save(HCDT dat, const char *fname,long ns); void MGL_EXPORT mgl_datac_save_(uintptr_t *dat, const char *fname,int *ns,int); /// Read data array from HDF file (parse HDF4 and HDF5 files) int MGL_EXPORT mgl_datac_read_hdf(HADT d,const char *fname,const char *data); int MGL_EXPORT mgl_datac_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n); /// Save data to HDF file void MGL_EXPORT mgl_datac_save_hdf(HCDT d,const char *fname,const char *data,int rewrite); void MGL_EXPORT mgl_datac_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n); /// Create or recreate the array with specified size and fill it by zero void MGL_EXPORT mgl_datac_create(HADT dat, long nx,long ny,long nz); void MGL_EXPORT mgl_datac_create_(uintptr_t *dat, int *nx,int *ny,int *nz); /// Transpose dimensions of the data (generalization of Transpose) void MGL_EXPORT mgl_datac_transpose(HADT dat, const char *dim); void MGL_EXPORT mgl_datac_transpose_(uintptr_t *dat, const char *dim,int); /// Get sub-array of the data with given fixed indexes HADT MGL_EXPORT mgl_datac_subdata(HCDT dat, long xx,long yy,long zz); uintptr_t MGL_EXPORT mgl_datac_subdata_(uintptr_t *dat, int *xx,int *yy,int *zz); /// Get sub-array of the data with given fixed indexes (like indirect access) HADT MGL_EXPORT mgl_datac_subdata_ext(HCDT dat, HCDT xx, HCDT yy, HCDT zz); uintptr_t MGL_EXPORT mgl_datac_subdata_ext_(uintptr_t *dat, uintptr_t *xx,uintptr_t *yy,uintptr_t *zz); /// Get column (or slice) of the data filled by formulas of named columns HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq); uintptr_t MGL_EXPORT mgl_datac_column_(uintptr_t *dat, const char *eq,int l); /// Get trace of the data array HADT MGL_EXPORT mgl_datac_trace(HCDT d); uintptr_t MGL_EXPORT mgl_datac_trace_(uintptr_t *d); /// Resize the data to new sizes HADT MGL_EXPORT mgl_datac_resize(HCDT dat, long mx,long my,long mz); uintptr_t MGL_EXPORT mgl_datac_resize_(uintptr_t *dat, int *mx,int *my,int *mz); /// Resize the data to new sizes of box [x1,x2]*[y1,y2]*[z1,z2] HADT MGL_EXPORT mgl_datac_resize_box(HCDT dat, long mx,long my,long mz,mreal x1,mreal x2,mreal y1,mreal y2,mreal z1,mreal z2); uintptr_t MGL_EXPORT mgl_datac_resize_box_(uintptr_t *dat, int *mx,int *my,int *mz,mreal *x1,mreal *x2,mreal *y1,mreal *y2,mreal *z1,mreal *z2); /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on. HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how); uintptr_t MGL_EXPORT mgl_datac_momentum_(uintptr_t *dat, char *dir, const char *how, int,int); /// Get array which values is result of interpolation this for coordinates from other arrays HADT MGL_EXPORT mgl_datac_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm); uintptr_t MGL_EXPORT mgl_datac_evaluate_(uintptr_t *dat, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm); /// Get array which is result of summation in given direction or directions HADT MGL_EXPORT mgl_datac_sum(HCDT dat, const char *dir); uintptr_t MGL_EXPORT mgl_datac_sum_(uintptr_t *dat, const char *dir,int); /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on) HADT MGL_EXPORT mgl_datac_combine(HCDT dat1, HCDT dat2); uintptr_t MGL_EXPORT mgl_datac_combine_(uintptr_t *dat1, uintptr_t *dat2); /// Get data from sections ids, separated by value val along specified direction. /** If section id is negative then reverse order is used (i.e. -1 give last section). */ HADT MGL_EXPORT mgl_datac_section(HCDT dat, HCDT ids, char dir, mreal val); uintptr_t MGL_EXPORT mgl_datac_section_(uintptr_t *d, uintptr_t *ids, const char *dir, mreal *val,int); /// Get data from section id, separated by value val along specified direction. /** If section id is negative then reverse order is used (i.e. -1 give last section). */ HADT MGL_EXPORT mgl_datac_section_val(HCDT dat, long id, char dir, mreal val); uintptr_t MGL_EXPORT mgl_datac_section_val_(uintptr_t *d, int *id, const char *dir, mreal *val,int); /// Equidistantly fill the data to range [x1,x2] in direction dir void MGL_EXPORT mgl_datac_fill(HADT dat, mdual x1,mdual x2,char dir); void MGL_EXPORT mgl_datac_fill_(uintptr_t *dat, mdual *x1,mdual *x2,const char *dir,int); /// Modify the data by specified formula assuming x,y,z in range [r1,r2] void MGL_EXPORT mgl_datac_fill_eq(HMGL gr, HADT dat, const char *eq, HCDT vdat, HCDT wdat,const char *opt); void MGL_EXPORT mgl_datac_fill_eq_(uintptr_t *gr, uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,const char *opt, int, int); /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] using global spline void MGL_EXPORT mgl_datac_refill_gs(HADT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl); void MGL_EXPORT mgl_datac_refill_gs_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl); /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] void MGL_EXPORT mgl_datac_refill_x(HADT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl); void MGL_EXPORT mgl_datac_refill_x_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl); /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in range [x1,x2]*[y1,y2] void MGL_EXPORT mgl_datac_refill_xy(HADT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl); void MGL_EXPORT mgl_datac_refill_xy_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, long *sl); /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [x1,x2]*[y1,y2]*[z1,z2] void MGL_EXPORT mgl_datac_refill_xyz(HADT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2); void MGL_EXPORT mgl_datac_refill_xyz_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2); /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range void MGL_EXPORT mgl_datac_refill_gr(HMGL gr, HADT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, long sl, const char *opt); void MGL_EXPORT mgl_datac_refill_gr_(uintptr_t *gr, uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, long *sl, const char *opt,int); /// Modify the data by specified formula void MGL_EXPORT mgl_datac_modify(HADT dat, const char *eq,long dim); void MGL_EXPORT mgl_datac_modify_(uintptr_t *dat, const char *eq,int *dim,int); /// Modify the data by specified formula void MGL_EXPORT mgl_datac_modify_vw(HADT dat, const char *eq,HCDT vdat,HCDT wdat); void MGL_EXPORT mgl_datac_modify_vw_(uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,int); /// Limit the data to be inside [-v,v], keeping the original sign void MGL_EXPORT mgl_datac_limit(HADT dat, mreal v); void MGL_EXPORT mgl_datac_limit_(uintptr_t *dat, mreal *v); /// Put value to data element(s) void MGL_EXPORT mgl_datac_put_val(HADT dat, mdual val, long i, long j, long k); void MGL_EXPORT mgl_datac_put_val_(uintptr_t *dat, mdual *val, int *i, int *j, int *k); /// Put array to data element(s) void MGL_EXPORT mgl_datac_put_dat(HADT dat, HCDT val, long i, long j, long k); void MGL_EXPORT mgl_datac_put_dat_(uintptr_t *dat, uintptr_t *val, int *i, int *j, int *k); /// Reduce size of the data void MGL_EXPORT mgl_datac_squeeze(HADT dat, long rx,long ry,long rz,long smooth); void MGL_EXPORT mgl_datac_squeeze_(uintptr_t *dat, int *rx,int *ry,int *rz,int *smooth); /// Extend data dimensions void MGL_EXPORT mgl_datac_extend(HADT dat, long n1, long n2); void MGL_EXPORT mgl_datac_extend_(uintptr_t *dat, int *n1, int *n2); /// Insert data rows/columns/slices void MGL_EXPORT mgl_datac_insert(HADT dat, char dir, long at, long num); void MGL_EXPORT mgl_datac_insert_(uintptr_t *dat, const char *dir, int *at, int *num, int); /// Delete data rows/columns/slices void MGL_EXPORT mgl_datac_delete(HADT dat, char dir, long at, long num); void MGL_EXPORT mgl_datac_delete_(uintptr_t *dat, const char *dir, int *at, int *num, int); /// Joind another data array void MGL_EXPORT mgl_datac_join(HADT dat, HCDT d); void MGL_EXPORT mgl_datac_join_(uintptr_t *dat, uintptr_t *d); /// Smooth the data on specified direction or directions /** String \a dir may contain: * ‘x’, ‘y’, ‘z’ for 1st, 2nd or 3d dimension; * ‘dN’ for linear averaging over N points; * ‘3’ for linear averaging over 3 points; * ‘5’ for linear averaging over 5 points. * By default quadratic averaging over 5 points is used. */ void MGL_EXPORT mgl_datac_smooth(HADT d, const char *dirs, mreal delta); void MGL_EXPORT mgl_datac_smooth_(uintptr_t *dat, const char *dirs, mreal *delta,int); /// Cumulative summation the data in given direction or directions void MGL_EXPORT mgl_datac_cumsum(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_cumsum_(uintptr_t *dat, const char *dir,int); /// Integrate (cumulative summation) the data in given direction or directions void MGL_EXPORT mgl_datac_integral(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_integral_(uintptr_t *dat, const char *dir,int); /// Differentiate the data in given direction or directions void MGL_EXPORT mgl_datac_diff(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_diff_(uintptr_t *dat, const char *dir,int); /// Differentiate the parametrically specified data along direction v1 with v2,v3=const (v3 can be NULL) void MGL_EXPORT mgl_datac_diff_par(HADT dat, HCDT v1, HCDT v2, HCDT v3); void MGL_EXPORT mgl_datac_diff_par_(uintptr_t *dat, uintptr_t *v1, uintptr_t *v2, uintptr_t *v3); /// Double-differentiate (like Laplace operator) the data in given direction void MGL_EXPORT mgl_datac_diff2(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_diff2_(uintptr_t *dat, const char *dir,int); /// Swap left and right part of the data in given direction (useful for Fourier spectrum) void MGL_EXPORT mgl_datac_swap(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_swap_(uintptr_t *dat, const char *dir,int); /// Roll data along direction dir by num slices void MGL_EXPORT mgl_datac_roll(HADT dat, char dir, long num); void MGL_EXPORT mgl_datac_roll_(uintptr_t *dat, const char *dir, int *num, int); /// Mirror the data in given direction (useful for Fourier spectrum) void MGL_EXPORT mgl_datac_mirror(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_mirror_(uintptr_t *dat, const char *dir,int); /// Crop the data void MGL_EXPORT mgl_datac_crop(HADT dat, long n1, long n2, char dir); void MGL_EXPORT mgl_datac_crop_(uintptr_t *dat, int *n1, int *n2, const char *dir,int); /// Crop the data to be most optimal for FFT (i.e. to closest value of 2^n*3^m*5^l) void MGL_EXPORT mgl_datac_crop_opt(HADT dat, const char *how); void MGL_EXPORT mgl_datac_crop_opt_(uintptr_t *dat, const char *how,int); /// Multiply the data by other one for each element void MGL_EXPORT mgl_datac_mul_dat(HADT dat, HCDT d); void MGL_EXPORT mgl_datac_mul_dat_(uintptr_t *dat, uintptr_t *d); /// Divide the data by other one for each element void MGL_EXPORT mgl_datac_div_dat(HADT dat, HCDT d); void MGL_EXPORT mgl_datac_div_dat_(uintptr_t *dat, uintptr_t *d); /// Add the other data void MGL_EXPORT mgl_datac_add_dat(HADT dat, HCDT d); void MGL_EXPORT mgl_datac_add_dat_(uintptr_t *dat, uintptr_t *d); /// Subtract the other data void MGL_EXPORT mgl_datac_sub_dat(HADT dat, HCDT d); void MGL_EXPORT mgl_datac_sub_dat_(uintptr_t *dat, uintptr_t *d); /// Multiply each element by the number void MGL_EXPORT mgl_datac_mul_num(HADT dat, mdual d); void MGL_EXPORT mgl_datac_mul_num_(uintptr_t *dat, mdual *d); /// Divide each element by the number void MGL_EXPORT mgl_datac_div_num(HADT dat, mdual d); void MGL_EXPORT mgl_datac_div_num_(uintptr_t *dat, mdual *d); /// Add the number void MGL_EXPORT mgl_datac_add_num(HADT dat, mdual d); void MGL_EXPORT mgl_datac_add_num_(uintptr_t *dat, mdual *d); /// Subtract the number void MGL_EXPORT mgl_datac_sub_num(HADT dat, mdual d); void MGL_EXPORT mgl_datac_sub_num_(uintptr_t *dat, mdual *d); /// Apply Hankel transform void MGL_EXPORT mgl_datac_hankel(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_hankel_(uintptr_t *dat, const char *dir,int); /// Apply Sin-Fourier transform void MGL_EXPORT mgl_datac_sinfft(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_sinfft_(uintptr_t *dat, const char *dir,int); /// Apply Cos-Fourier transform void MGL_EXPORT mgl_datac_cosfft(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_cosfft_(uintptr_t *dat, const char *dir,int); /// Apply Fourier transform void MGL_EXPORT mgl_datac_fft(HADT dat, const char *dir); void MGL_EXPORT mgl_datac_fft_(uintptr_t *dat, const char *dir,int); /// Find correlation between 2 data arrays HADT MGL_EXPORT mgl_datac_correl(HCDT dat1, HCDT dat2, const char *dir); uintptr_t MGL_EXPORT mgl_datac_correl_(uintptr_t *dat1, uintptr_t *dat2, const char *dir,int); /// Calculate one step of diffraction by finite-difference method with parameter q void MGL_EXPORT mgl_datac_diffr(HADT dat, const char *how, mreal q); void MGL_EXPORT mgl_datac_diffr_(uintptr_t *d, const char *how, double q,int l); /// Apply wavelet transform /** Parameter \a dir may contain: * ‘x‘,‘y‘,‘z‘ for directions, * ‘d‘ for daubechies, ‘D‘ for centered daubechies, * ‘h‘ for haar, ‘H‘ for centered haar, * ‘b‘ for bspline, ‘B‘ for centered bspline, * ‘i‘ for applying inverse transform. */ void MGL_EXPORT mgl_datac_wavelet(HADT dat, const char *how, int k); void MGL_EXPORT mgl_datac_wavelet_(uintptr_t *d, const char *dir, int *k,int); /// Set as the data envelop void MGL_EXPORT mgl_datac_envelop(HADT dat, char dir); void MGL_EXPORT mgl_datac_envelop_(uintptr_t *dat, const char *dir, int); /// Get real part of data values HMDT MGL_EXPORT mgl_datac_real(HCDT dat); uintptr_t MGL_EXPORT mgl_datac_real_(uintptr_t *dat); /// Get imaginary part of data values HMDT MGL_EXPORT mgl_datac_imag(HCDT dat); uintptr_t MGL_EXPORT mgl_datac_imag_(uintptr_t *dat); /// Get absolute value of data values, i.e. |u| HMDT MGL_EXPORT mgl_datac_abs(HCDT dat); uintptr_t MGL_EXPORT mgl_datac_abs_(uintptr_t *dat); /// Get argument of data values HMDT MGL_EXPORT mgl_datac_arg(HCDT dat); uintptr_t MGL_EXPORT mgl_datac_arg_(uintptr_t *dat); /// Get square of absolute value of data values, i.e. |u|^2 HMDT MGL_EXPORT mgl_datac_norm(HCDT dat); uintptr_t MGL_EXPORT mgl_datac_norm_(uintptr_t *dat); /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] cmdual MGL_EXPORT mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z); cmdual MGL_EXPORT mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z); /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] cmdual MGL_EXPORT mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, mdual *dx,mdual *dy,mdual *dz); cmdual MGL_EXPORT mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mdual *dx,mdual *dy,mdual *dz); /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] cmdual MGL_EXPORT mgl_datac_spline(HCDT dat, mreal x,mreal y,mreal z); cmdual MGL_EXPORT mgl_datac_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z); /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] cmdual MGL_EXPORT mgl_datac_spline_ext(HCDT dat, mreal x,mreal y,mreal z, mdual *dx,mdual *dy,mdual *dz); cmdual MGL_EXPORT mgl_datac_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mdual *dx,mdual *dy,mdual *dz); /// Prepare coefficients for global spline interpolation HADT MGL_EXPORT mgl_gsplinec_init(HCDT x, HCDT v); uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v); /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef cmdual MGL_EXPORT mgl_gsplinec(HCDT coef, mreal dx, mdual *d1, mdual *d2); cmdual MGL_EXPORT mgl_gsplinec_(uintptr_t *c, mreal *dx, mdual *d1, mdual *d2); /// Find roots for set of nonlinear equations defined by textual formulas HADT MGL_EXPORT mgl_find_roots_txt_c(const char *func, const char *vars, HCDT ini); uintptr_t MGL_EXPORT mgl_find_roots_txt_c_(const char *func, const char *vars, uintptr_t *ini,int,int); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/parser.h������������������������������������������������������������������0000644�0001750�0001750�00000024714�13513030041�017106� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * parser.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_PARSER_H_ #define _MGL_PARSER_H_ #ifdef __cplusplus #include "mgl2/mgl.h" #if MGL_HAVE_LTDL #include #endif //----------------------------------------------------------------------------- /// Structure for the command argument. struct mglArg { int type; ///< Type of argument {0-data,1-string,2-number} mglDataA *d; ///< Pointer to data (used if type==0) mglString s; ///< String with parameters mreal v; ///< Numerical value (used if type==2) dual c; ///< Numerical complex value (used if type==2) mglArg():type(-1),d(0),v(0),c(0.) {} }; //----------------------------------------------------------------------------- /// Structure for MGL command struct mglCommand { const char *name; ///< Name of command const char *desc; ///< Short command description (can be NULL) const char *form; ///< Format of command arguments (can be NULL) /// Function for executing (plotting) int (*exec)(mglGraph *gr, long n, mglArg *a, const char *k, const char *opt); /// Type of command: 0 - special plot, 1 - other plot, /// 2 - setup, 3 - data handle, 4 - data create, 5 - subplot, 6 - program /// 7 - 1d plot, 8 - 2d plot, 9 - 3d plot, 10 - dd plot, 11 - vector plot /// 12 - axis, 13 - primitives, 14 - axis setup, 15 - text/legend, 16 - data transform int type; }; extern mglCommand mgls_prg_cmd[], mgls_dat_cmd[], mgls_grf_cmd[], mgls_set_cmd[], mgls_prm_cmd[]; //----------------------------------------------------------------------------- /// Structure for function name and position. struct mglFunc { long pos; int narg; mglString func; mglFunc(long p, const wchar_t *f); mglFunc(const mglFunc &f):pos(f.pos),narg(f.narg),func(f.func) {} mglFunc():pos(-1),narg(-1) {} const mglFunc &operator=(const mglFunc &f) { pos=f.pos; narg=f.narg; func=f.func; return f; } }; //----------------------------------------------------------------------------- /// Structure for stack of functions and its arguments. struct mglFnStack { long pos; ///< position to return size_t stk; ///< stack at 'call' mglString par[10]; ///< input parameters mglFnStack():pos(0),stk(0) {} }; //----------------------------------------------------------------------------- /// Structure for stack of if|for|while. #define MGL_ST_TRUE 0 // condition true #define MGL_ST_FALSE 1 // condition false #define MGL_ST_DONE 2 // condition done #define MGL_ST_LOOP 4 // normal loop #define MGL_ST_BREAK 8 // loop break #define MGL_ST_STOP (MGL_ST_FALSE|MGL_ST_DONE|MGL_ST_BREAK) #define MGL_ST_SKIP (MGL_ST_FALSE|MGL_ST_DONE) struct mglPosStack { int pos; ///< position to return mglData v; ///< data to iterate long ind; ///< index in data array int par; ///< for-parameter unsigned state; ///< state of stack item mglPosStack(int st=MGL_ST_LOOP):pos(-1),ind(0),par(-1),state(st) {} }; //----------------------------------------------------------------------------- /// Function for asking question in console mode void MGL_EXPORT mgl_ask_gets(const wchar_t *quest, wchar_t *res); //----------------------------------------------------------------------------- /// Structure for the command argument (see mglGraph::Exec()). class mglParser { friend void mgl_export(wchar_t *out, const wchar_t *in, int type); public: #if MGL_HAVE_LTDL std::vector DllOpened; ///< Opened external DLL (keep ) #endif std::vector DataList; ///< List with data and its names std::vector NumList; ///< List with numbers and its names bool AllowDllCall; ///< Allow calls from external dynamic libraries bool AllowSetSize; ///< Allow using setsize command bool AllowFileIO; ///< Allow reading/saving files volatile bool Stop; ///< Stop command was. Flag prevent further execution mglCommand *Cmd; ///< Table of MGL commands (can be changed by user). It MUST be sorted by 'name'!!! long InUse; ///< Smart pointer (number of users) HMGL curGr; ///< Current grapher int StarObhID; ///< staring object id mglParser(bool setsize=false); virtual ~mglParser(); /// Find the command by the keyword name const mglCommand *FindCommand(const char *name) const MGL_FUNC_PURE; const mglCommand *FindCommand(const wchar_t *name) const MGL_FUNC_PURE; /// Parse and execute the string of MGL script inline int Parse(HMGL gr, const char *str, long pos=0) { mglGraph GR(gr); return Parse(&GR,str,pos); } int Parse(mglGraph *gr, const char *str, long pos=0); /// Parse and execute the unicode string of MGL script inline int Parse(HMGL gr, const wchar_t *str, long pos=0) { mglGraph GR(gr); return Parse(&GR,str,pos); } int Parse(mglGraph *gr, std::wstring str, long pos=0); /// Execute MGL script file fname inline void Execute(HMGL gr, FILE *fp, bool print=false) { mglGraph GR(gr); Execute(&GR,fp,print); } void Execute(mglGraph *gr, FILE *fp, bool print=false); /// Execute MGL script from array of lines inline void Execute(HMGL gr, int num, const wchar_t **text) { mglGraph GR(gr); Execute(&GR,num,text); } void Execute(mglGraph *gr, int num, const wchar_t **text); /// Execute MGL script text with '\n' separated lines inline void Execute(HMGL gr, const wchar_t *text) { mglGraph GR(gr); Execute(&GR,text); } void Execute(mglGraph *gr, const wchar_t *text); /// Execute MGL script text with '\n' separated lines inline void Execute(HMGL gr, const char *text) { mglGraph GR(gr); Execute(&GR,text); } void Execute(mglGraph *gr, const char *text); /// Scan for functions (use NULL for reset) void ScanFunc(const wchar_t *line); /// Check if name is function and return its address (or 0 if no) long IsFunc(const wchar_t *name, int *narg=0); /// Find variable or return 0 if absent mglDataA *FindVar(const char *name) MGL_FUNC_PURE; mglDataA *FindVar(const wchar_t *name) MGL_FUNC_PURE; /// Find variable or create it if absent mglDataA *AddVar(const char *name); mglDataA *AddVar(const wchar_t *name); /// Find number or return 0 if absent mglNum *FindNum(const char *name) MGL_FUNC_PURE; mglNum *FindNum(const wchar_t *name) MGL_FUNC_PURE; /// Find number or create it if absent mglNum *AddNum(const char *name); mglNum *AddNum(const wchar_t *name); /// Add string for parameter $1, ..., $9 void AddParam(int n, const char *str); void AddParam(int n, const wchar_t *str); /// Add new MGL command(s) (last command MUST HAVE name[0]=0 !!!) void AddCommand(const mglCommand *cmd); /// Restore Once flag inline void RestoreOnce() { Once = true; } /// Delete variable by its name void DeleteVar(const char *name); void DeleteVar(const wchar_t *name); /// Delete all data variables void DeleteAll(); /// Delete temporary data arrays inline void DeleteTemp() { for(size_t i=0;itemp) { mglDataA *u=DataList[i]; DataList[i]=0; delete u; } } /// Set variant of argument(s) separated by '?' to be used inline void SetVariant(int var=0) { Variant = var<=0?0:var; } protected: static mglCommand *BaseCmd; ///< Base table of MGL commands. It MUST be sorted by 'name'!!! static void FillBaseCmd(); ///< Fill BaseCmd at initialization stage ///< Test if condition is not-valid (n=1) or false (0) or true (1) int TestCond(long m, const mglArg &a0, mglArg &a1, bool &cond) { int n = 1; if(a0.type==2) { cond = a0.v!=0; n=0; } else if(a0.type==0) { n=0; cond = a0.d->FindAny((m>1 && a1.type==1) ? a1.s.s:"u"); } return n; } private: // long parlen; ///< Length of parameter strings mglString par[40]; ///< Parameter for substituting instead of $1, ..., $9 bool Once; ///< Flag for command which should be executed only once bool Skip; ///< Flag that commands should be skiped (inside 'once' block) std::vector stack; ///< Stack of if|for|while commands std::vector func; ///< function names and position std::vector fn_stack; ///< function calls stack unsigned Variant; ///< Select variant of argument(s) separated by '?' /// Parse command int Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const std::wstring &var, const wchar_t *opt); /// Fill arguments a from strings void FillArg(mglGraph *gr, int n, std::wstring *arg, mglArg *a); /// PreExecute stage -- parse some commands and create variables int PreExec(mglGraph *gr, long n, std::wstring *arg, mglArg *a); /// Execute program-flow control commands int FlowExec(mglGraph *gr, const std::wstring &com, long n, mglArg *a); /// Parse and execute the unicode string of MGL script int ParseDat(mglGraph *gr, std::wstring str, mglData &res); /// Define '$' parameters or start for loop int ParseDef(std::wstring &str); /// Parse $N arguments void PutArg(std::wstring &str, bool def); /// In skip mode bool inline ifskip() { return ( stack.size() && (stack.back().state & MGL_ST_SKIP) ); } bool inline skip() { return (Skip || (stack.size() && (stack.back().state & MGL_ST_STOP) )); } bool CheckForName(const std::wstring &s); // check if name is valid for new data }; //----------------------------------------------------------------------------- #endif #endif ����������������������������������������������������mathgl-2.4.4/include/mgl2/qt.h����������������������������������������������������������������������0000644�0001750�0001750�00000006554�13513030041�016240� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * qt.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_QT_H_ #define _MGL_QT_H_ #include //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Creates Qt window for plotting HMGL MGL_EXPORT mgl_create_graph_qt(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p)); uintptr_t MGL_EXPORT mgl_create_graph_qt_(const char *title, int); /// Run main Qt loop for event handling. int MGL_EXPORT mgl_qt_run(); int MGL_EXPORT mgl_qt_run_(); /// Return pointer to widget (QMathGL*) used for plotting MGL_EXPORT_PURE void *mgl_qt_widget(HMGL gr); #ifdef __cplusplus } //----------------------------------------------------------------------------- #include //----------------------------------------------------------------------------- /// Wrapper class for windows displaying graphics class MGL_EXPORT mglQT : public mglWnd { mglQT(const mglQT &) {} // copying is not allowed const mglQT &operator=(const mglQT &t) { return t; } public: mglQT(const char *title="MathGL") : mglWnd() { gr = mgl_create_graph_qt(0,title,0,0); } mglQT(int (*draw)(HMGL gr, void *p), const char *title="MathGL", void *par=NULL, void (*load)(void *p)=0) : mglWnd() { gr = mgl_create_graph_qt(draw,title,par,load); } mglQT(int (*draw)(mglGraph *gr), const char *title="MathGL") : mglWnd() { gr = mgl_create_graph_qt(draw?mgl_draw_graph:0,title,(void*)draw,0); } mglQT(mglDraw *draw, const char *title="MathGL") : mglWnd() { gr = mgl_create_graph_qt(draw?mgl_draw_class:0,title,draw,mgl_reload_class); mgl_set_click_func(gr, mgl_click_class); } virtual ~mglQT() {} int Run() { return mgl_qt_run(); } ///< Run main loop for event handling }; //----------------------------------------------------------------------------- void MGL_EXPORT mgl_ask_qt(const wchar_t *quest, wchar_t *res); //----------------------------------------------------------------------------- #endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/mgl.fs��������������������������������������������������������������������0000644�0001750�0001750�00000113746�13513030041�016556� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\ Mathgl library wrapper \ Copyright (C) 2008-2013, Sergey Plis, Alexey Balakin \ \ This program is free software; you can redistribute it and/or modify \ it under the terms of the GNU General Public License as published by \ the Free Software Foundation; either version 2 of the License, or \ (at your option) any later version. \ \ This program is distributed in the hope that it will be useful, \ but WITHOUT ANY WARRANTY; without even the implied warranty of \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \ GNU General Public License for more details. Module mathgl library libmgl libmgl.so library libmgl-glut libmgl-glut.so library libmgl-fltk libmgl-fltk.so library libmgl-qt libmgl-qt.so library libmgl-wx libmgl-wx.so legacy off libmgl mgl_create_graph_gl (ptr) mgl_create_graph_gl libmgl-glut mgl_create_graph_glut ptr ptr ptr (ptr) mgl_create_graph_glut libmgl-fltk mgl_create_graph_fltk ptr ptr ptr (ptr) mgl_create_graph_fltk libmgl-fltk mgl_fltk_run (void) mgl_fltk_run libmgl-qt mgl_create_graph_qt ptr ptr ptr (ptr) mgl_create_graph_qt libmgl-qt mgl_qt_run (void) mgl_qt_run libmgl mgl_get_warn ptr (int) mgl_get_warn libmgl mgl_set_warn ptr int ptr (void) mgl_set_warn libmgl gl_get_mess ptr (ptr) gl_get_mess libmgl mgl_set_plotid ptr ptr (void) mgl_set_plotid libmgl gl_get_plotid ptr (ptr) gl_get_plotid libmgl mgl_get_quality ptr (int) mgl_get_quality libmgl mgl_set_quality int ptr (void) mgl_set_quality libmgl mgl_set_draw_reg int int int ptr (void) mgl_set_draw_reg libmgl mgl_is_frames ptr (int) mgl_is_frames libmgl mgl_get_flag int ptr (int) mgl_get_flag libmgl mgl_set_flag int int ptr (void) mgl_set_flag libmgl mgl_use_graph int ptr (int) mgl_use_graph libmgl mgl_start_group ptr ptr (void) mgl_start_group libmgl mgl_end_group ptr (void) mgl_end_group libmgl mgl_highlight int ptr (void) mgl_highlight libmgl mgl_set_palette ptr ptr (void) mgl_set_palette libmgl mgl_set_color double double double char (void) mgl_set_color libmgl mgl_set_def_sch ptr ptr (void) mgl_set_def_sch libmgl mgl_set_mask ptr char (void) mgl_set_mask libmgl mgl_set_mask_angle int ptr (void) mgl_set_mask_angle libmgl mgl_set_alpha_default double ptr (void) mgl_set_alpha_default libmgl mgl_set_bar_width double ptr (void) mgl_set_bar_width libmgl mgl_set_meshnum int ptr (void) mgl_set_meshnum libmgl mgl_set_facenum int ptr (void) mgl_set_facenum libmgl mgl_clear_unused ptr (void) mgl_clear_unused libmgl mgl_set_ambbr double ptr (void) mgl_set_ambbr libmgl mgl_set_difbr double ptr (void) mgl_set_difbr libmgl mgl_set_light_dif int ptr (void) mgl_set_light_dif libmgl mgl_set_cut int ptr (void) mgl_set_cut libmgl mgl_set_cut_box double double double double double double ptr (void) mgl_set_cut_box libmgl mgl_set_cutoff ptr ptr (void) mgl_set_cutoff libmgl mgl_set_ranges double double double double double double ptr (void) mgl_set_ranges libmgl mgl_set_range_val double double char ptr (void) mgl_set_range_val libmgl mgl_set_range_dat int ptr char ptr (void) mgl_set_range_dat libmgl mgl_set_auto_ranges double double double double double double double double ptr (void) mgl_set_auto_ranges libmgl mgl_zoom_axis double double double double double double double double ptr (void) mgl_zoom_axis libmgl mgl_set_origin double double double ptr (void) mgl_set_origin libmgl mgl_set_func ptr ptr ptr ptr ptr (void) mgl_set_func libmgl mgl_set_coor int ptr (void) mgl_set_coor libmgl mgl_set_ternary int ptr (void) mgl_set_ternary libmgl mgl_set_tick_rotate int ptr (void) mgl_set_tick_rotate libmgl mgl_set_tick_skip int ptr (void) mgl_set_tick_skip libmgl mgl_def_font ptr ptr (void) mgl_def_font libmgl mgl_set_mark_size double ptr (void) mgl_set_mark_size libmgl mgl_set_arrow_size double ptr (void) mgl_set_arrow_size libmgl mgl_set_font_size double ptr (void) mgl_set_font_size libmgl mgl_set_font_def ptr ptr (void) mgl_set_font_def libmgl mgl_set_rotated_text int ptr (void) mgl_set_rotated_text libmgl mgl_load_font ptr ptr ptr (void) mgl_load_font libmgl mgl_copy_font ptr ptr (void) mgl_copy_font libmgl mgl_restore_font ptr (void) mgl_restore_font libmgl mgl_srnd int (void) mgl_srnd libmgl mgl_rnd (double) mgl_rnd libmgl mgl_ipow int double (double) mgl_ipow libmgl mgl_get_time ptr ptr (double) mgl_get_time libmgl mgl_create_data (ptr) mgl_create_data libmgl mgl_create_data_size int int int (ptr) mgl_create_data_size libmgl mgl_create_data_file ptr (ptr) mgl_create_data_file libmgl mgl_delete_data ptr (void) mgl_delete_data libmgl gl_data_info ptr (ptr) gl_data_info libmgl mgl_data_rearrange int int int ptr (void) mgl_data_rearrange libmgl mgl_data_link int int int ptr ptr (void) mgl_data_link libmgl mgl_data_set_float int int int ptr ptr (void) mgl_data_set_float libmgl mgl_data_set_double int int int ptr ptr (void) mgl_data_set_double libmgl mgl_data_set ptr ptr (void) mgl_data_set libmgl mgl_data_set_vector ptr ptr (void) mgl_data_set_vector libmgl mgl_data_set_matrix ptr ptr (void) mgl_data_set_matrix libmgl mgl_data_set_value int int int sf ptr (void) mgl_data_set_value libmgl mgl_data_get_value int int int ptr (sf) mgl_data_get_value libmgl mgl_data_set_values int int int ptr ptr (void) mgl_data_set_values libmgl mgl_data_read_hdf ptr ptr ptr (int) mgl_data_read_hdf libmgl mgl_data_save_hdf int ptr ptr ptr (void) mgl_data_save_hdf libmgl mgl_datas_hdf int ptr ptr (int) mgl_datas_hdf libmgl mgl_data_read ptr ptr (int) mgl_data_read libmgl mgl_data_read_mat int ptr ptr (int) mgl_data_read_mat libmgl mgl_data_read_dim int int int ptr ptr (int) mgl_data_read_dim libmgl mgl_data_read_range int double double double ptr ptr (int) mgl_data_read_range libmgl mgl_data_read_all int ptr ptr (int) mgl_data_read_all libmgl mgl_data_save int ptr ptr (void) mgl_data_save libmgl mgl_data_export int sf sf ptr ptr ptr (void) mgl_data_export libmgl mgl_data_import sf sf ptr ptr ptr (void) mgl_data_import libmgl mgl_data_create int int int ptr (void) mgl_data_create libmgl mgl_data_transpose ptr ptr (void) mgl_data_transpose libmgl mgl_data_norm int int sf sf ptr (void) mgl_data_norm libmgl mgl_data_norm_slice int int char sf sf ptr (void) mgl_data_norm_slice libmgl mgl_data_subdata int int int ptr (ptr) mgl_data_subdata libmgl mgl_data_subdata_ext ptr ptr ptr ptr (ptr) mgl_data_subdata_ext libmgl mgl_data_column ptr ptr (ptr) mgl_data_column libmgl mgl_data_set_id ptr ptr (void) mgl_data_set_id libmgl mgl_data_fill char sf sf ptr (void) mgl_data_fill libmgl mgl_data_fill_eq ptr ptr ptr ptr ptr ptr (void) mgl_data_fill_eq libmgl mgl_data_refill_x int sf sf ptr ptr ptr (void) mgl_data_refill_x libmgl mgl_data_refill_xy int sf sf sf sf ptr ptr ptr ptr (void) mgl_data_refill_xy libmgl mgl_data_refill_xyz sf sf sf sf sf sf ptr ptr ptr ptr ptr (void) mgl_data_refill_xyz libmgl mgl_data_refill_gr ptr int ptr ptr ptr ptr ptr ptr (void) mgl_data_refill_gr libmgl mgl_data_grid ptr ptr ptr ptr ptr ptr (void) mgl_data_grid libmgl mgl_data_grid_xy sf sf sf sf ptr ptr ptr ptr (void) mgl_data_grid_xy libmgl mgl_data_put_val int int int sf ptr (void) mgl_data_put_val libmgl mgl_data_put_dat int int int ptr ptr (void) mgl_data_put_dat libmgl mgl_data_modify int ptr ptr (void) mgl_data_modify libmgl mgl_data_modify_vw ptr ptr ptr ptr (void) mgl_data_modify_vw libmgl mgl_data_squeeze int int int int ptr (void) mgl_data_squeeze libmgl mgl_data_max ptr (sf) mgl_data_max libmgl mgl_data_min ptr (sf) mgl_data_min libmgl gl_data_value int int int ptr (ptr) gl_data_value libmgl gl_data_data ptr (ptr) gl_data_data libmgl mgl_data_get_nx ptr (int) mgl_data_get_nx libmgl mgl_data_get_ny ptr (int) mgl_data_get_ny libmgl mgl_data_get_nz ptr (int) mgl_data_get_nz libmgl mgl_data_first ptr ptr ptr ptr ptr (sf) mgl_data_first libmgl mgl_data_last ptr ptr ptr ptr ptr (sf) mgl_data_last libmgl mgl_data_find int int int char ptr ptr (int) mgl_data_find libmgl mgl_data_find_any ptr ptr (int) mgl_data_find_any libmgl mgl_data_max_int ptr ptr ptr ptr (sf) mgl_data_max_int libmgl mgl_data_max_real ptr ptr ptr ptr (sf) mgl_data_max_real libmgl mgl_data_min_int ptr ptr ptr ptr (sf) mgl_data_min_int libmgl mgl_data_min_real ptr ptr ptr ptr (sf) mgl_data_min_real libmgl mgl_data_momentum_val ptr ptr ptr ptr char ptr (sf) mgl_data_momentum_val libmgl mgl_data_combine ptr ptr (ptr) mgl_data_combine libmgl mgl_data_extend int int ptr (void) mgl_data_extend libmgl mgl_data_insert int int char ptr (void) mgl_data_insert libmgl mgl_data_delete int int char ptr (void) mgl_data_delete libmgl mgl_data_join ptr ptr (void) mgl_data_join libmgl mgl_data_smooth sf ptr ptr (void) mgl_data_smooth libmgl mgl_data_sum ptr ptr (ptr) mgl_data_sum libmgl mgl_data_max_dir ptr ptr (ptr) mgl_data_max_dir libmgl mgl_data_min_dir ptr ptr (ptr) mgl_data_min_dir libmgl mgl_data_cumsum ptr ptr (void) mgl_data_cumsum libmgl mgl_data_integral ptr ptr (void) mgl_data_integral libmgl mgl_data_diff ptr ptr (void) mgl_data_diff libmgl mgl_data_diff_par ptr ptr ptr ptr (void) mgl_data_diff_par libmgl mgl_data_diff2 ptr ptr (void) mgl_data_diff2 libmgl mgl_data_swap ptr ptr (void) mgl_data_swap libmgl mgl_data_roll int char ptr (void) mgl_data_roll libmgl mgl_data_mirror ptr ptr (void) mgl_data_mirror libmgl mgl_data_sort int int ptr (void) mgl_data_sort libmgl mgl_data_hankel ptr ptr (void) mgl_data_hankel libmgl mgl_data_sinfft ptr ptr (void) mgl_data_sinfft libmgl mgl_data_cosfft ptr ptr (void) mgl_data_cosfft libmgl mgl_data_fill_sample ptr ptr (void) mgl_data_fill_sample libmgl mgl_data_correl ptr ptr ptr (ptr) mgl_data_correl libmgl mgl_clear_fft (void) mgl_clear_fft libmgl mgl_data_spline sf sf sf ptr (sf) mgl_data_spline libmgl mgl_data_linear sf sf sf ptr (sf) mgl_data_linear libmgl mgl_data_spline_ext ptr ptr ptr sf sf sf ptr (sf) mgl_data_spline_ext libmgl mgl_data_linear_ext ptr ptr ptr sf sf sf ptr (sf) mgl_data_linear_ext libmgl mgl_data_solve_1d int int sf ptr (sf) mgl_data_solve_1d libmgl mgl_data_solve int ptr char sf ptr (ptr) mgl_data_solve libmgl mgl_data_trace ptr (ptr) mgl_data_trace libmgl mgl_data_resize int int int ptr (ptr) mgl_data_resize libmgl mgl_data_resize_box sf sf sf sf sf sf int int int ptr (ptr) mgl_data_resize_box libmgl mgl_data_hist int sf sf int ptr (ptr) mgl_data_hist libmgl mgl_data_hist_w int sf sf int ptr ptr (ptr) mgl_data_hist_w libmgl mgl_data_momentum ptr char ptr (ptr) mgl_data_momentum libmgl mgl_data_evaluate int ptr ptr ptr ptr (ptr) mgl_data_evaluate libmgl mgl_data_envelop char ptr (void) mgl_data_envelop libmgl mgl_data_sew sf ptr ptr (void) mgl_data_sew libmgl mgl_data_crop char int int ptr (void) mgl_data_crop libmgl mgl_data_clean int ptr (void) mgl_data_clean libmgl mgl_data_mul_dat ptr ptr (void) mgl_data_mul_dat libmgl mgl_data_div_dat ptr ptr (void) mgl_data_div_dat libmgl mgl_data_add_dat ptr ptr (void) mgl_data_add_dat libmgl mgl_data_sub_dat ptr ptr (void) mgl_data_sub_dat libmgl mgl_data_mul_num sf ptr (void) mgl_data_mul_num libmgl mgl_data_div_num sf ptr (void) mgl_data_div_num libmgl mgl_data_add_num sf ptr (void) mgl_data_add_num libmgl mgl_data_sub_num sf ptr (void) mgl_data_sub_num libmgl mgl_transform_a ptr ptr ptr (ptr) mgl_transform_a libmgl mgl_transform ptr ptr ptr (ptr) mgl_transform libmgl mgl_data_fourier ptr ptr ptr (void) mgl_data_fourier libmgl mgl_data_stfa char int ptr ptr (ptr) mgl_data_stfa libmgl mgl_triangulation_3d ptr ptr ptr (ptr) mgl_triangulation_3d libmgl mgl_triangulation_2d ptr ptr (ptr) mgl_triangulation_2d libmgl mgl_find_root_txt char sf ptr (sf) mgl_find_root_txt libmgl mgl_data_roots char ptr ptr (ptr) mgl_data_roots libmgl mgl_datac_save int ptr ptr (void) mgl_datac_save libmgl mgl_datac_save_hdf int ptr ptr ptr (void) mgl_datac_save_hdf libmgl mgl_datac_real ptr (ptr) mgl_datac_real libmgl mgl_datac_imag ptr (ptr) mgl_datac_imag libmgl mgl_datac_abs ptr (ptr) mgl_datac_abs libmgl mgl_datac_arg ptr (ptr) mgl_datac_arg libmgl mgl_text_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_text_xyz libmgl mgl_textw_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_textw_xyz libmgl mgl_text_xy ptr ptr ptr ptr ptr ptr (void) mgl_text_xy libmgl mgl_textw_xy ptr ptr ptr ptr ptr ptr (void) mgl_textw_xy libmgl mgl_text_y ptr ptr ptr ptr ptr (void) mgl_text_y libmgl mgl_textw_y ptr ptr ptr ptr ptr (void) mgl_textw_y libmgl mgl_cont_gen ptr ptr ptr ptr ptr double ptr (void) mgl_cont_gen libmgl mgl_contf_gen ptr ptr ptr ptr ptr double double ptr (void) mgl_contf_gen libmgl mgl_cont_xy_val ptr ptr ptr ptr ptr ptr ptr (void) mgl_cont_xy_val libmgl mgl_cont_val ptr ptr ptr ptr ptr (void) mgl_cont_val libmgl mgl_cont_xy ptr ptr ptr ptr ptr ptr (void) mgl_cont_xy libmgl mgl_cont ptr ptr ptr ptr (void) mgl_cont libmgl mgl_contf_xy_val ptr ptr ptr ptr ptr ptr ptr (void) mgl_contf_xy_val libmgl mgl_contf_val ptr ptr ptr ptr ptr (void) mgl_contf_val libmgl mgl_contf_xy ptr ptr ptr ptr ptr ptr (void) mgl_contf_xy libmgl mgl_contf ptr ptr ptr ptr (void) mgl_contf libmgl mgl_contd_xy_val ptr ptr ptr ptr ptr ptr ptr (void) mgl_contd_xy_val libmgl mgl_contd_val ptr ptr ptr ptr ptr (void) mgl_contd_val libmgl mgl_contd_xy ptr ptr ptr ptr ptr ptr (void) mgl_contd_xy libmgl mgl_contd ptr ptr ptr ptr (void) mgl_contd libmgl mgl_contv_xy_val ptr ptr ptr ptr ptr ptr ptr (void) mgl_contv_xy_val libmgl mgl_contv_val ptr ptr ptr ptr ptr (void) mgl_contv_val libmgl mgl_contv_xy ptr ptr ptr ptr ptr ptr (void) mgl_contv_xy libmgl mgl_contv ptr ptr ptr ptr (void) mgl_contv libmgl mgl_axial_xy_val ptr ptr ptr ptr ptr ptr ptr (void) mgl_axial_xy_val libmgl mgl_axial_val ptr ptr ptr ptr ptr (void) mgl_axial_val libmgl mgl_axial_xy ptr ptr ptr ptr ptr ptr (void) mgl_axial_xy libmgl mgl_axial ptr ptr ptr ptr (void) mgl_axial libmgl mgl_torus ptr ptr ptr ptr ptr (void) mgl_torus libmgl mgl_grid3_xyz ptr double ptr ptr ptr ptr ptr ptr (void) mgl_grid3_xyz libmgl mgl_grid3 ptr double ptr ptr ptr (void) mgl_grid3 libmgl mgl_dens3_xyz ptr double ptr ptr ptr ptr ptr ptr (void) mgl_dens3_xyz libmgl mgl_dens3 ptr double ptr ptr ptr (void) mgl_dens3 libmgl mgl_cont3_xyz_val ptr double ptr ptr ptr ptr ptr ptr ptr (void) mgl_cont3_xyz_val libmgl mgl_cont3_val ptr double ptr ptr ptr ptr (void) mgl_cont3_val libmgl mgl_cont3_xyz ptr double ptr ptr ptr ptr ptr ptr (void) mgl_cont3_xyz libmgl mgl_cont3 ptr double ptr ptr ptr (void) mgl_cont3 libmgl mgl_contf3_xyz_val ptr double ptr ptr ptr ptr ptr ptr ptr (void) mgl_contf3_xyz_val libmgl mgl_contf3_val ptr double ptr ptr ptr ptr (void) mgl_contf3_val libmgl mgl_contf3_xyz ptr double ptr ptr ptr ptr ptr ptr (void) mgl_contf3_xyz libmgl mgl_contf3 ptr double ptr ptr ptr (void) mgl_contf3 libmgl mgl_fit_1 ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_1 libmgl mgl_fit_2 ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_2 libmgl mgl_fit_3 ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_3 libmgl mgl_fit_xy ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_xy libmgl mgl_fit_xyz ptr ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_xyz libmgl mgl_fit_xyza ptr ptr ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_xyza libmgl mgl_fit_ys ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_ys libmgl mgl_fit_xys ptr ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_xys libmgl mgl_fit_xyzs ptr ptr ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_xyzs libmgl mgl_fit_xyzas ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr (ptr) mgl_fit_xyzas libmgl gl_get_fit ptr (ptr) gl_get_fit libmgl mgl_hist_x ptr ptr ptr ptr (ptr) mgl_hist_x libmgl mgl_hist_xy ptr ptr ptr ptr ptr (ptr) mgl_hist_xy libmgl mgl_hist_xyz ptr ptr ptr ptr ptr ptr (ptr) mgl_hist_xyz libmgl mgl_puts_fit double ptr ptr double double double ptr (void) mgl_puts_fit libmgl mgl_fplot ptr ptr ptr ptr (void) mgl_fplot libmgl mgl_fplot_xyz ptr ptr ptr ptr ptr ptr (void) mgl_fplot_xyz libmgl mgl_radar ptr ptr ptr ptr (void) mgl_radar libmgl mgl_plot_xyz ptr ptr ptr ptr ptr ptr (void) mgl_plot_xyz libmgl mgl_plot_xy ptr ptr ptr ptr ptr (void) mgl_plot_xy libmgl mgl_plot ptr ptr ptr ptr (void) mgl_plot libmgl mgl_tens_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_tens_xyz libmgl mgl_tens_xy ptr ptr ptr ptr ptr ptr (void) mgl_tens_xy libmgl mgl_tens ptr ptr ptr ptr ptr (void) mgl_tens libmgl mgl_tape_xyz ptr ptr ptr ptr ptr ptr (void) mgl_tape_xyz libmgl mgl_tape_xy ptr ptr ptr ptr ptr (void) mgl_tape_xy libmgl mgl_tape ptr ptr ptr ptr (void) mgl_tape libmgl mgl_boxplot_xy ptr ptr ptr ptr ptr (void) mgl_boxplot_xy libmgl mgl_boxplot ptr ptr ptr ptr (void) mgl_boxplot libmgl mgl_area_xyz ptr ptr ptr ptr ptr ptr (void) mgl_area_xyz libmgl mgl_area_xy ptr ptr ptr ptr ptr (void) mgl_area_xy libmgl mgl_area ptr ptr ptr ptr (void) mgl_area libmgl mgl_region_xy ptr ptr ptr ptr ptr ptr (void) mgl_region_xy libmgl mgl_region ptr ptr ptr ptr ptr (void) mgl_region libmgl mgl_stem_xyz ptr ptr ptr ptr ptr ptr (void) mgl_stem_xyz libmgl mgl_stem_xy ptr ptr ptr ptr ptr (void) mgl_stem_xy libmgl mgl_stem ptr ptr ptr ptr (void) mgl_stem libmgl mgl_step_xyz ptr ptr ptr ptr ptr ptr (void) mgl_step_xyz libmgl mgl_step_xy ptr ptr ptr ptr ptr (void) mgl_step_xy libmgl mgl_step ptr ptr ptr ptr (void) mgl_step libmgl mgl_bars_xyz ptr ptr ptr ptr ptr ptr (void) mgl_bars_xyz libmgl mgl_bars_xy ptr ptr ptr ptr ptr (void) mgl_bars_xy libmgl mgl_bars ptr ptr ptr ptr (void) mgl_bars libmgl mgl_barh_yx ptr ptr ptr ptr ptr (void) mgl_barh_yx libmgl mgl_barh ptr ptr ptr ptr (void) mgl_barh libmgl mgl_ohlc_x ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_ohlc_x libmgl mgl_ohlc ptr ptr ptr ptr ptr ptr ptr (void) mgl_ohlc libmgl mgl_chart ptr ptr ptr ptr (void) mgl_chart libmgl mgl_error_exy ptr ptr ptr ptr ptr ptr ptr (void) mgl_error_exy libmgl mgl_error_xy ptr ptr ptr ptr ptr ptr (void) mgl_error_xy libmgl mgl_error ptr ptr ptr ptr ptr (void) mgl_error libmgl mgl_mark_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_mark_xyz libmgl mgl_mark_xy ptr ptr ptr ptr ptr ptr (void) mgl_mark_xy libmgl mgl_mark_y ptr ptr ptr ptr ptr (void) mgl_mark_y libmgl mgl_tube_xyzr ptr ptr ptr ptr ptr ptr ptr (void) mgl_tube_xyzr libmgl mgl_tube_xyr ptr ptr ptr ptr ptr ptr (void) mgl_tube_xyr libmgl mgl_tube_r ptr ptr ptr ptr ptr (void) mgl_tube_r libmgl mgl_tube_xyz ptr ptr double ptr ptr ptr ptr (void) mgl_tube_xyz libmgl mgl_tube_xy ptr ptr double ptr ptr ptr (void) mgl_tube_xy libmgl mgl_tube ptr ptr double ptr ptr (void) mgl_tube libmgl mgl_candle_xyv ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_candle_xyv libmgl mgl_candle_yv ptr ptr ptr ptr ptr ptr ptr (void) mgl_candle_yv libmgl mgl_candle ptr ptr ptr ptr ptr ptr (void) mgl_candle libmgl mgl_fsurf ptr ptr ptr ptr (void) mgl_fsurf libmgl mgl_fsurf_xyz ptr ptr ptr ptr ptr ptr (void) mgl_fsurf_xyz libmgl mgl_grid_xy ptr ptr ptr ptr ptr ptr (void) mgl_grid_xy libmgl mgl_grid ptr ptr ptr ptr (void) mgl_grid libmgl mgl_mesh_xy ptr ptr ptr ptr ptr ptr (void) mgl_mesh_xy libmgl mgl_mesh ptr ptr ptr ptr (void) mgl_mesh libmgl mgl_fall_xy ptr ptr ptr ptr ptr ptr (void) mgl_fall_xy libmgl mgl_fall ptr ptr ptr ptr (void) mgl_fall libmgl mgl_belt_xy ptr ptr ptr ptr ptr ptr (void) mgl_belt_xy libmgl mgl_belt ptr ptr ptr ptr (void) mgl_belt libmgl mgl_surf_xy ptr ptr ptr ptr ptr ptr (void) mgl_surf_xy libmgl mgl_surf ptr ptr ptr ptr (void) mgl_surf libmgl mgl_dens_xy ptr ptr ptr ptr ptr ptr (void) mgl_dens_xy libmgl mgl_dens ptr ptr ptr ptr (void) mgl_dens libmgl mgl_boxs_xy ptr ptr ptr ptr ptr ptr (void) mgl_boxs_xy libmgl mgl_boxs ptr ptr ptr ptr (void) mgl_boxs libmgl mgl_tile_xy ptr ptr ptr ptr ptr ptr (void) mgl_tile_xy libmgl mgl_tile ptr ptr ptr ptr (void) mgl_tile libmgl mgl_tiles_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_tiles_xy libmgl mgl_tiles ptr ptr ptr ptr ptr (void) mgl_tiles libmgl mgl_surfc_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_surfc_xy libmgl mgl_surfc ptr ptr ptr ptr ptr (void) mgl_surfc libmgl mgl_surfa_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_surfa_xy libmgl mgl_surfa ptr ptr ptr ptr ptr (void) mgl_surfa libmgl mgl_stfa_xy ptr ptr int ptr ptr ptr ptr ptr (void) mgl_stfa_xy libmgl mgl_stfa ptr ptr int ptr ptr ptr (void) mgl_stfa libmgl mgl_map_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_map_xy libmgl mgl_map ptr ptr ptr ptr ptr (void) mgl_map libmgl mgl_surf3_xyz_val ptr ptr ptr ptr ptr ptr double ptr (void) mgl_surf3_xyz_val libmgl mgl_surf3_val ptr ptr ptr double ptr (void) mgl_surf3_val libmgl mgl_surf3_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_surf3_xyz libmgl mgl_surf3 ptr ptr ptr ptr (void) mgl_surf3 libmgl mgl_surf3a_xyz_val ptr ptr ptr ptr ptr ptr ptr double ptr (void) mgl_surf3a_xyz_val libmgl mgl_surf3a_val ptr ptr ptr ptr double ptr (void) mgl_surf3a_val libmgl mgl_surf3a_xyz ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_surf3a_xyz libmgl mgl_surf3a ptr ptr ptr ptr ptr (void) mgl_surf3a libmgl mgl_surf3c_xyz_val ptr ptr ptr ptr ptr ptr ptr double ptr (void) mgl_surf3c_xyz_val libmgl mgl_surf3c_val ptr ptr ptr ptr double ptr (void) mgl_surf3c_val libmgl mgl_surf3c_xyz ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_surf3c_xyz libmgl mgl_surf3c ptr ptr ptr ptr ptr (void) mgl_surf3c libmgl mgl_cloud_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_cloud_xyz libmgl mgl_cloud ptr ptr ptr ptr (void) mgl_cloud libmgl mgl_beam_val int ptr double ptr ptr ptr ptr double ptr (void) mgl_beam_val libmgl mgl_beam int int ptr double ptr ptr ptr ptr ptr (void) mgl_beam libmgl mgl_traj_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_traj_xy libmgl mgl_traj_xyz ptr ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_traj_xyz libmgl mgl_vect_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_vect_xy libmgl mgl_vect_2d ptr ptr ptr ptr ptr (void) mgl_vect_2d libmgl mgl_vect_xyz ptr ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_vect_xyz libmgl mgl_vect_3d ptr ptr ptr ptr ptr ptr (void) mgl_vect_3d libmgl mgl_flow_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_flow_xy libmgl mgl_flow_2d ptr ptr ptr ptr ptr (void) mgl_flow_2d libmgl mgl_flow_xyz ptr ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_flow_xyz libmgl mgl_flow_3d ptr ptr ptr ptr ptr ptr (void) mgl_flow_3d libmgl mgl_flowp_xy ptr ptr ptr ptr ptr ptr double double double ptr (void) mgl_flowp_xy libmgl mgl_flowp_2d ptr ptr ptr ptr double double double ptr (void) mgl_flowp_2d libmgl mgl_flowp_xyz ptr ptr ptr ptr ptr ptr ptr ptr double double double ptr (void) mgl_flowp_xyz libmgl mgl_flowp_3d ptr ptr ptr ptr ptr double double double ptr (void) mgl_flowp_3d libmgl mgl_pipe_xy ptr double ptr ptr ptr ptr ptr ptr (void) mgl_pipe_xy libmgl mgl_pipe_2d ptr double ptr ptr ptr ptr (void) mgl_pipe_2d libmgl mgl_pipe_xyz ptr double ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_pipe_xyz libmgl mgl_pipe_3d ptr double ptr ptr ptr ptr ptr (void) mgl_pipe_3d libmgl mgl_grad_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_grad_xyz libmgl mgl_grad_xy ptr ptr ptr ptr ptr ptr (void) mgl_grad_xy libmgl mgl_grad ptr ptr ptr ptr (void) mgl_grad libmgl mgl_vect3_xyz ptr double ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_vect3_xyz libmgl mgl_vect3 ptr double ptr ptr ptr ptr ptr (void) mgl_vect3 libmgl mgl_mark ptr double double double ptr (void) mgl_mark libmgl mgl_ball double double double ptr (void) mgl_ball libmgl mgl_line int ptr double double double double double double ptr (void) mgl_line libmgl mgl_curve int ptr double double double double double double double double double double double double ptr (void) mgl_curve libmgl mgl_error_box ptr double double double double double double ptr (void) mgl_error_box libmgl mgl_face ptr double double double double double double double double double double double double ptr (void) mgl_face libmgl mgl_facex double double ptr double double double double double ptr (void) mgl_facex libmgl mgl_facey double double ptr double double double double double ptr (void) mgl_facey libmgl mgl_facez double double ptr double double double double double ptr (void) mgl_facez libmgl mgl_sphere ptr double double double double ptr (void) mgl_sphere libmgl mgl_drop double double ptr double double double double double double double ptr (void) mgl_drop libmgl mgl_cone ptr double double double double double double double double ptr (void) mgl_cone libmgl mgl_ellipse ptr double double double double double double double ptr (void) mgl_ellipse libmgl mgl_rhomb ptr double double double double double double double ptr (void) mgl_rhomb libmgl mgl_cones_xyz ptr ptr ptr ptr ptr ptr (void) mgl_cones_xyz libmgl mgl_cones_xz ptr ptr ptr ptr ptr (void) mgl_cones_xz libmgl mgl_cones ptr ptr ptr ptr (void) mgl_cones libmgl mgl_dew_xy ptr ptr ptr ptr ptr ptr ptr (void) mgl_dew_xy libmgl mgl_dew_2d ptr ptr ptr ptr ptr (void) mgl_dew_2d libmgl mgl_puts_dir double ptr ptr double double double double double double ptr (void) mgl_puts_dir libmgl mgl_putsw_dir double ptr ptr double double double double double double ptr (void) mgl_putsw_dir libmgl mgl_textmark_xyzr ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_textmark_xyzr libmgl mgl_textmarkw_xyzr ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_textmarkw_xyzr libmgl mgl_textmark_xyr ptr ptr ptr ptr ptr ptr ptr (void) mgl_textmark_xyr libmgl mgl_textmarkw_xyr ptr ptr ptr ptr ptr ptr ptr (void) mgl_textmarkw_xyr libmgl mgl_textmark_yr ptr ptr ptr ptr ptr ptr (void) mgl_textmark_yr libmgl mgl_textmarkw_yr ptr ptr ptr ptr ptr ptr (void) mgl_textmarkw_yr libmgl mgl_textmark ptr ptr ptr ptr ptr (void) mgl_textmark libmgl mgl_textmarkw ptr ptr ptr ptr ptr (void) mgl_textmarkw libmgl mgl_label_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_label_xyz libmgl mgl_labelw_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_labelw_xyz libmgl mgl_label_xy ptr ptr ptr ptr ptr ptr (void) mgl_label_xy libmgl mgl_labelw_xy ptr ptr ptr ptr ptr ptr (void) mgl_labelw_xy libmgl mgl_label_y ptr ptr ptr ptr ptr (void) mgl_label_y libmgl mgl_labelw_y ptr ptr ptr ptr ptr (void) mgl_labelw_y libmgl mgl_table ptr ptr ptr ptr double double ptr (void) mgl_table libmgl mgl_tablew ptr ptr ptr ptr double double ptr (void) mgl_tablew libmgl mgl_triplot_xyzc ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_triplot_xyzc libmgl mgl_triplot_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_triplot_xyz libmgl mgl_triplot_xy ptr ptr ptr ptr ptr ptr (void) mgl_triplot_xy libmgl mgl_quadplot_xyzc ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_quadplot_xyzc libmgl mgl_quadplot_xyz ptr ptr ptr ptr ptr ptr ptr (void) mgl_quadplot_xyz libmgl mgl_quadplot_xy ptr ptr ptr ptr ptr ptr (void) mgl_quadplot_xy libmgl mgl_tricont_xyzcv ptr ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_tricont_xyzcv libmgl mgl_tricont_xycv ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_tricont_xycv libmgl mgl_tricont_xyzc ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_tricont_xyzc libmgl mgl_tricont_xyc ptr ptr ptr ptr ptr ptr ptr (void) mgl_tricont_xyc libmgl mgl_dots ptr ptr ptr ptr ptr ptr (void) mgl_dots libmgl mgl_dots_a ptr ptr ptr ptr ptr ptr ptr (void) mgl_dots_a libmgl mgl_dots_ca ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_dots_ca libmgl mgl_crust ptr ptr ptr ptr ptr ptr (void) mgl_crust libmgl mgl_dens_x ptr double ptr ptr ptr (void) mgl_dens_x libmgl mgl_dens_y ptr double ptr ptr ptr (void) mgl_dens_y libmgl mgl_dens_z ptr double ptr ptr ptr (void) mgl_dens_z libmgl mgl_cont_x ptr double ptr ptr ptr (void) mgl_cont_x libmgl mgl_cont_y ptr double ptr ptr ptr (void) mgl_cont_y libmgl mgl_cont_z ptr double ptr ptr ptr (void) mgl_cont_z libmgl mgl_cont_x_val ptr double ptr ptr ptr ptr (void) mgl_cont_x_val libmgl mgl_cont_y_val ptr double ptr ptr ptr ptr (void) mgl_cont_y_val libmgl mgl_cont_z_val ptr double ptr ptr ptr ptr (void) mgl_cont_z_val libmgl mgl_contf_x ptr double ptr ptr ptr (void) mgl_contf_x libmgl mgl_contf_y ptr double ptr ptr ptr (void) mgl_contf_y libmgl mgl_contf_z ptr double ptr ptr ptr (void) mgl_contf_z libmgl mgl_contf_x_val ptr double ptr ptr ptr ptr (void) mgl_contf_x_val libmgl mgl_contf_y_val ptr double ptr ptr ptr ptr (void) mgl_contf_y_val libmgl mgl_contf_z_val ptr double ptr ptr ptr ptr (void) mgl_contf_z_val libmgl mgl_create_graph int int (ptr) mgl_create_graph libmgl mgl_delete_graph ptr (void) mgl_delete_graph libmgl mgl_set_size int int ptr (void) mgl_set_size libmgl mgl_set_def_param ptr (void) mgl_set_def_param libmgl mgl_combine_gr ptr ptr (void) mgl_combine_gr libmgl mgl_finish ptr (void) mgl_finish libmgl mgl_set_tick_len double double ptr (void) mgl_set_tick_len libmgl mgl_set_axis_stl ptr ptr ptr ptr (void) mgl_set_axis_stl libmgl mgl_adjust_ticks ptr ptr (void) mgl_adjust_ticks libmgl mgl_set_ticks double int double char ptr (void) mgl_set_ticks libmgl mgl_set_ticks_str int ptr char ptr (void) mgl_set_ticks_str libmgl mgl_set_ticks_wcs int ptr char ptr (void) mgl_set_ticks_wcs libmgl mgl_set_ticks_val int ptr ptr char ptr (void) mgl_set_ticks_val libmgl mgl_set_ticks_valw int ptr ptr char ptr (void) mgl_set_ticks_valw libmgl mgl_tune_ticks double int ptr (void) mgl_tune_ticks libmgl mgl_set_tick_templ ptr char ptr (void) mgl_set_tick_templ libmgl mgl_set_tick_templw ptr char ptr (void) mgl_set_tick_templw libmgl mgl_set_ticks_time ptr double char ptr (void) mgl_set_ticks_time libmgl mgl_set_tick_shift double double double double ptr (void) mgl_set_tick_shift libmgl mgl_box ptr (void) mgl_box libmgl mgl_box_str int ptr ptr (void) mgl_box_str libmgl mgl_axis ptr ptr ptr ptr (void) mgl_axis libmgl mgl_axis_grid ptr ptr ptr ptr (void) mgl_axis_grid libmgl mgl_label ptr double ptr char ptr (void) mgl_label libmgl mgl_labelw ptr double ptr char ptr (void) mgl_labelw libmgl mgl_colorbar ptr ptr (void) mgl_colorbar libmgl mgl_colorbar_ext double double double double ptr ptr (void) mgl_colorbar_ext libmgl mgl_colorbar_val ptr ptr ptr (void) mgl_colorbar_val libmgl mgl_colorbar_val_ext double double double double ptr ptr ptr (void) mgl_colorbar_val_ext libmgl mgl_add_legend ptr ptr ptr (void) mgl_add_legend libmgl mgl_add_legendw ptr ptr ptr (void) mgl_add_legendw libmgl mgl_clear_legend ptr (void) mgl_clear_legend libmgl mgl_legend_pos ptr ptr double double ptr (void) mgl_legend_pos libmgl mgl_legend ptr ptr int ptr (void) mgl_legend libmgl mgl_set_legend_marks int ptr (void) mgl_set_legend_marks libmgl mgl_show_image int ptr ptr (void) mgl_show_image libmgl mgl_write_frame ptr ptr ptr (void) mgl_write_frame libmgl mgl_write_tga ptr ptr ptr (void) mgl_write_tga libmgl mgl_write_bmp ptr ptr ptr (void) mgl_write_bmp libmgl mgl_write_jpg ptr ptr ptr (void) mgl_write_jpg libmgl mgl_write_png ptr ptr ptr (void) mgl_write_png libmgl mgl_write_png_solid ptr ptr ptr (void) mgl_write_png_solid libmgl mgl_write_bps ptr ptr ptr (void) mgl_write_bps libmgl mgl_write_eps ptr ptr ptr (void) mgl_write_eps libmgl mgl_write_svg ptr ptr ptr (void) mgl_write_svg libmgl mgl_write_tex ptr ptr ptr (void) mgl_write_tex libmgl mgl_write_obj int ptr ptr ptr (void) mgl_write_obj libmgl mgl_write_obj_old int ptr ptr ptr (void) mgl_write_obj_old libmgl mgl_write_stl ptr ptr ptr (void) mgl_write_stl libmgl mgl_write_off int ptr ptr ptr (void) mgl_write_off libmgl mgl_write_xyz ptr ptr ptr (void) mgl_write_xyz libmgl mgl_write_prc int ptr ptr ptr (void) mgl_write_prc libmgl mgl_write_gif ptr ptr ptr (void) mgl_write_gif libmgl mgl_start_gif int ptr ptr (void) mgl_start_gif libmgl mgl_close_gif ptr (void) mgl_close_gif libmgl mgl_export_mgld ptr ptr ptr (void) mgl_export_mgld libmgl mgl_import_mgld int ptr ptr (void) mgl_import_mgld libmgl mgl_write_json ptr ptr ptr (void) mgl_write_json libmgl mgl_write_json_z ptr ptr ptr (void) mgl_write_json_z libmgl gl_get_json ptr (ptr) gl_get_json libmgl gl_get_rgb ptr (ptr) gl_get_rgb libmgl gl_get_rgba ptr (ptr) gl_get_rgba libmgl mgl_set_obj_id int ptr (void) mgl_set_obj_id libmgl mgl_get_obj_id int int ptr (int) mgl_get_obj_id libmgl mgl_get_spl_id int int ptr (int) mgl_get_spl_id libmgl mgl_get_width ptr (int) mgl_get_width libmgl mgl_get_height ptr (int) mgl_get_height libmgl mgl_calc_xyz ptr ptr ptr int int ptr (void) mgl_calc_xyz libmgl mgl_calc_scr ptr ptr double double double ptr (void) mgl_calc_scr libmgl mgl_is_active int int int ptr (int) mgl_is_active libmgl mgl_new_frame ptr (int) mgl_new_frame libmgl mgl_end_frame ptr (void) mgl_end_frame libmgl mgl_get_num_frame ptr (int) mgl_get_num_frame libmgl mgl_reset_frames ptr (void) mgl_reset_frames libmgl mgl_get_frame int ptr (void) mgl_get_frame libmgl mgl_set_frame int ptr (void) mgl_set_frame libmgl mgl_show_frame int ptr (void) mgl_show_frame libmgl mgl_del_frame int ptr (void) mgl_del_frame libmgl mgl_set_transp_type int ptr (void) mgl_set_transp_type libmgl mgl_set_alpha int ptr (void) mgl_set_alpha libmgl mgl_set_fog double double ptr (void) mgl_set_fog libmgl mgl_set_light int ptr (void) mgl_set_light libmgl mgl_set_light_n int int ptr (void) mgl_set_light_n libmgl mgl_add_light double double double int ptr (void) mgl_add_light libmgl mgl_add_light_ext double double char double double double int ptr (void) mgl_add_light_ext libmgl mgl_add_light_loc double double char double double double double double double int ptr (void) mgl_add_light_loc libmgl mgl_mat_pop ptr (void) mgl_mat_pop libmgl mgl_mat_push ptr (void) mgl_mat_push libmgl mgl_clf ptr (void) mgl_clf libmgl mgl_clf_rgb double double double ptr (void) mgl_clf_rgb libmgl mgl_clf_chr char ptr (void) mgl_clf_chr libmgl mgl_subplot ptr int int int ptr (void) mgl_subplot libmgl mgl_subplot_d double double ptr int int int ptr (void) mgl_subplot_d libmgl mgl_multiplot ptr int int int int int ptr (void) mgl_multiplot libmgl mgl_inplot double double double double ptr (void) mgl_inplot libmgl mgl_relplot double double double double ptr (void) mgl_relplot libmgl mgl_columnplot double int int ptr (void) mgl_columnplot libmgl mgl_gridplot double int int int ptr (void) mgl_gridplot libmgl mgl_stickplot double double int int ptr (void) mgl_stickplot libmgl mgl_title double ptr ptr ptr (void) mgl_title libmgl mgl_titlew double ptr ptr ptr (void) mgl_titlew libmgl mgl_set_plotfactor double ptr (void) mgl_set_plotfactor libmgl mgl_aspect double double double ptr (void) mgl_aspect libmgl mgl_rotate double double double ptr (void) mgl_rotate libmgl mgl_rotate_vector double double double double ptr (void) mgl_rotate_vector libmgl mgl_perspective double ptr (void) mgl_perspective libmgl mgl_view double double double ptr (void) mgl_view libmgl mgl_zoom double double double double ptr (void) mgl_zoom libmgl mgl_wnd_set_delay double ptr (void) mgl_wnd_set_delay libmgl mgl_wnd_get_delay ptr (double) mgl_wnd_get_delay libmgl mgl_setup_window int int ptr (void) mgl_setup_window libmgl mgl_wnd_toggle_alpha ptr (void) mgl_wnd_toggle_alpha libmgl mgl_wnd_toggle_light ptr (void) mgl_wnd_toggle_light libmgl mgl_wnd_toggle_zoom ptr (void) mgl_wnd_toggle_zoom libmgl mgl_wnd_toggle_rotate ptr (void) mgl_wnd_toggle_rotate libmgl mgl_wnd_toggle_no ptr (void) mgl_wnd_toggle_no libmgl mgl_wnd_update ptr (void) mgl_wnd_update libmgl mgl_wnd_reload ptr (void) mgl_wnd_reload libmgl mgl_wnd_adjust ptr (void) mgl_wnd_adjust libmgl mgl_wnd_next_frame ptr (void) mgl_wnd_next_frame libmgl mgl_wnd_prev_frame ptr (void) mgl_wnd_prev_frame libmgl mgl_wnd_animation ptr (void) mgl_wnd_animation libmgl mgl_get_last_mouse_pos ptr ptr ptr ptr (void) mgl_get_last_mouse_pos libmgl mgl_create_parser (ptr) mgl_create_parser libmgl mgl_use_parser int ptr (int) mgl_use_parser libmgl mgl_delete_parser ptr (void) mgl_delete_parser libmgl mgl_parser_add_param ptr int ptr (void) mgl_parser_add_param libmgl mgl_parser_add_paramw ptr int ptr (void) mgl_parser_add_paramw libmgl mgl_parser_add_var ptr ptr (ptr) mgl_parser_add_var libmgl mgl_parser_add_varw ptr ptr (ptr) mgl_parser_add_varw libmgl mgl_parser_find_var ptr ptr (ptr) mgl_parser_find_var libmgl mgl_parser_find_varw ptr ptr (ptr) mgl_parser_find_varw libmgl mgl_parser_del_var ptr ptr (void) mgl_parser_del_var libmgl mgl_parser_del_varw ptr ptr (void) mgl_parser_del_varw libmgl mgl_parser_del_all ptr (void) mgl_parser_del_all libmgl mgl_parse_line int ptr ptr ptr (int) mgl_parse_line libmgl mgl_parse_linew int ptr ptr ptr (int) mgl_parse_linew libmgl mgl_parse_text ptr ptr ptr (void) mgl_parse_text libmgl mgl_parse_textw ptr ptr ptr (void) mgl_parse_textw libmgl mgl_parser_restore_once ptr (void) mgl_parser_restore_once libmgl mgl_parser_allow_setsize int ptr (void) mgl_parser_allow_setsize libmgl mgl_parser_allow_file_io int ptr (void) mgl_parser_allow_file_io libmgl mgl_parser_stop ptr (void) mgl_parser_stop libmgl mgl_parser_cmd_type ptr ptr (int) mgl_parser_cmd_type libmgl gl_parser_cmd_desc ptr ptr (ptr) gl_parser_cmd_desc libmgl gl_parser_cmd_frmt ptr ptr (ptr) gl_parser_cmd_frmt libmgl gl_parser_cmd_name int ptr (ptr) gl_parser_cmd_name libmgl mgl_parser_cmd_num ptr (int) mgl_parser_cmd_num libmgl mgl_parser_calc ptr ptr (ptr) mgl_parser_calc libmgl mgl_parser_calcw ptr ptr (ptr) mgl_parser_calcw libmgl mgl_create_expr ptr (ptr) mgl_create_expr libmgl mgl_delete_expr ptr (void) mgl_delete_expr libmgl mgl_expr_eval double double double ptr (double) mgl_expr_eval libmgl mgl_expr_eval_v ptr ptr (double) mgl_expr_eval_v libmgl mgl_expr_diff double double double char ptr (double) mgl_expr_diff libmgl mgl_expr_diff_v ptr char ptr (double) mgl_expr_diff_v libmgl mgl_gauss_rnd (double) mgl_gauss_rnd libmgl mgl_fft_freq int ptr (void) mgl_fft_freq libmgl mgl_strcls ptr (void) mgl_strcls libmgl mgl_strpos ptr ptr (int) mgl_strpos libmgl mgl_chrpos char ptr (int) mgl_chrpos libmgl mgl_istrue char (int) mgl_istrue ��������������������������mathgl-2.4.4/include/mgl2/base.h��������������������������������������������������������������������0000644�0001750�0001750�00000111642�13513030041�016521� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * base.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_BASE_H_ #define _MGL_BASE_H_ //#if !defined(_MSC_VER) && !defined(__BORLANDC__) #include "mgl2/abstract.h" #ifdef __cplusplus #if (MGL_HAVE_PTHREAD|MGL_HAVE_PTHR_WIDGET) #include #endif #if MGL_HAVE_PTHREAD #define MGL_PUSH(a,v,m) {pthread_mutex_lock(&m); a.push_back(v); pthread_mutex_unlock(&m);} #else #define MGL_PUSH(a,v,m) a.push_back(v); #endif #if MGL_HAVE_PTHREAD #define MGL_PUSHs(func,m) {pthread_mutex_lock(&m); func; pthread_mutex_unlock(&m);} #else #define MGL_PUSHs(func,m) {func;} #endif //----------------------------------------------------------------------------- inline mreal mgl_d(mreal v,mreal v1,mreal v2) { return v2!=v1?(v-v1)/(v2-v1):NAN; } //----------------------------------------------------------------------------- mglPoint GetX(HCDT x, int i, int j, int k=0); mglPoint GetY(HCDT y, int i, int j, int k=0); mglPoint GetZ(HCDT z, int i, int j, int k=0); //----------------------------------------------------------------------------- /// Class for replacement of std::vector // NOTE memcpy is used --> no memory allocation in T template class mglStack { T **dat; unsigned MGL_PB; ///< size of buffer (real size is 2^pb == 1L< &st) { mutex = 0; n=0; nb=1; MGL_PB = mgl_bsize(0); dat = new T*[(size_t)1<(nb<>MGL_PB); for(;nb>MGL_PB; return dat[d][i-(d<>MGL_PB; return dat[d][i-(d<=(nb<>MGL_PB; dat[d][n-(d<=(nb<>MGL_PB; dat[d][n-(d< &operator=(const mglStack &st) { clear(); reserve(st.n); for(size_t i=0;i(const mglPrim &a,const mglPrim &b); //----------------------------------------------------------------------------- /// Structure for light source struct MGL_EXPORT mglLight { mglLight():a(0),b(0),n(false) {} mglLight(const mglLight &aa) : d(aa.d),r(aa.r),q(aa.q),p(aa.p),c(aa.c),a(aa.a),b(aa.b),n(aa.n) {} const mglLight &operator=(const mglLight &aa) { d=aa.d; r=aa.r; q=aa.q; p=aa.p; c=aa.c; a=aa.a; b=aa.b; n=aa.n; return aa; } mglPoint d; ///< Direction of light sources mglPoint r; ///< Position of light sources (NAN for infinity) mglPoint q; ///< Actual position of light sources (filled by LightScale() function) mglPoint p; ///< Actual direction of light sources (filled by LightScale() function) mglColor c; ///< Color of light sources float a; ///< Aperture of light sources float b; ///< Brightness of light sources bool n; ///< Availability of light sources }; //----------------------------------------------------------------------------- /// Structure for inplot struct MGL_EXPORT mglBlock { long n1,n2,n3,n4; ///< coordinates of corners {n1=x1,n2=x2,n3=y1,n4=y2} mglLight light[10]; ///< Light sources float AmbBr; ///< Default ambient light brightness float DifBr; ///< Default diffusive light brightness mglMatrix B; ///< Transformation matrix int id; ///< object id mglBlock():n1(0),n2(0),n3(0),n4(0),AmbBr(0.5),DifBr(0.5),id(0) {} mglBlock(const mglBlock &aa) { memcpy(this, &aa, sizeof(mglBlock)); } const mglBlock &operator=(const mglBlock &aa) { n1=aa.n1; n2=aa.n2; n3=aa.n3; n4=aa.n4; for(int i=0;i<10;i++) light[i]=aa.light[i]; AmbBr=aa.AmbBr; DifBr=aa.DifBr; B=aa.B; id=aa.id; return aa; } }; //----------------------------------------------------------------------------- /// Structure for group of primitives struct MGL_EXPORT mglGroup { std::vector p; ///< list of primitives (not filled!!!) int Id; ///< Current list of primitives std::string Lbl; ///< Group label mglGroup(const char *lbl="", int id=0) : Id(id), Lbl(lbl) {} mglGroup(const mglGroup &aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl) {} #if MGL_HAVE_RVAL mglGroup(mglGroup &&aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl) {} #endif inline const mglGroup &operator=(const mglGroup &aa) { Lbl = aa.Lbl; Id = aa.Id; p = aa.p; return aa; } }; //----------------------------------------------------------------------------- /// Structure for text label struct MGL_EXPORT mglText { std::wstring text; std::string stl; float val; mglText(const wchar_t *txt=L"", const char *fnt="", float v=0) : text(txt), stl(fnt), val(v) {} mglText(const std::wstring &txt, float v=0): text(txt), val(v) {} mglText(const mglText &aa) : text(aa.text),stl(aa.stl),val(aa.val) {} #if MGL_HAVE_RVAL mglText(mglText &&aa) : text(aa.text),stl(aa.stl),val(aa.val) {} #endif const mglText&operator=(const mglText &aa) { text=aa.text; stl=aa.stl; val=aa.val; return aa; } }; //----------------------------------------------------------------------------- /// Structure for internal point representation struct MGL_EXPORT mglPnt // NOTE: use float for reducing memory size { union { float dat[15]; struct { float x,y,z; // coordinates float u,v,w; // normales float r,g,b,a; // RGBA color float xx,yy,zz; // original coordinates float c,ta; // index in color scheme }; }; int sub; // subplot id and rotation information (later will be in subplot) mglPnt(float X=0, float Y=0, float Z=0, float U=0, float V=0, float W=0, float R=0, float G=0, float B=0, float A=0, short s=0) :x(X),y(Y),z(Z),u(U),v(V),w(W),r(R),g(G),b(B),a(A),xx(X),yy(Y),zz(Z),c(0),ta(0),sub(s) {} mglPnt(const mglPnt &aa) : sub(aa.sub) { memcpy(dat,aa.dat,15*sizeof(float)); } inline const mglPnt&operator=(const mglPnt &aa) { sub=aa.sub; memcpy(dat,aa.dat,15*sizeof(float)); return aa; } inline bool same(const mglPnt &p, mreal d) const { return fabs(x-p.x); MGL_EXTERN template class MGL_EXPORT mglStack; MGL_EXTERN template class MGL_EXPORT std::vector; MGL_EXTERN template class MGL_EXPORT std::vector; MGL_EXTERN template class MGL_EXPORT std::vector; MGL_EXTERN template class MGL_EXPORT std::vector; MGL_EXTERN template class MGL_EXPORT std::vector; MGL_EXTERN template class MGL_EXPORT std::vector; MGL_EXTERN template class MGL_EXPORT mglStack; #endif //----------------------------------------------------------------------------- /// Base class for canvas which handle all basic drawing class MGL_EXPORT mglBase { public: mglBase(); virtual ~mglBase(); mglPoint Min; ///< Lower edge of bounding box for graphics. mglPoint Max; ///< Upper edge of bounding box for graphics. mreal ZMin; ///< Adjusted minimal z-value 1D plots std::string Mess; ///< Buffer for receiving messages int ObjId; ///< object id for mglPrim int HighId; ///< object id to be highlited std::vector Grp; ///< List of groups with names -- need for export mglStack Act; ///< Position of active points std::string PlotId; ///< Id of plot for saving filename (in GLUT window for example) int BBoxX1, BBoxY1, BBoxX2, BBoxY2; ///< BBox region for exporting 2d graphics std::vector UserGlf; ///< User-defined glyphs data mreal CDef; ///< Default (current) color in texture mreal AlphaDef; ///< Default value of alpha channel (transparency) mreal BarWidth; ///< Relative width of rectangles in Bars(). int MeshNum; ///< Set approximate number of lines in Mesh and Grid. By default (=0) it draw all lines. int FaceNum; ///< Set approximate number of visible faces and lines. By default (=0) it draw everything. char Arrow1, Arrow2;///< Style of arrows at end and at start of curve long InUse; ///< Smart pointer (number of users) uint32_t Flag; ///< Flags for controlling drawing mreal size_opt; ///< Value of size option (or NAN if not specified) inline bool get(uint32_t fl) const { return Flag&fl; } inline void set(uint32_t fl) { Flag |= fl; } inline void clr(uint32_t fl) { Flag &=~fl; } inline void set(bool v,uint32_t fl) { Flag = v ? Flag|fl : Flag&(~fl); } /// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image! inline void ZoomAxis(mglPoint p1=mglPoint(0,0,0,0), mglPoint p2=mglPoint(1,1,1,1)) { AMin = p1; AMax = p2; } /// Set values of mglGraph::Min and mglGraph::Max inline void SetRanges(mreal x1, mreal x2, mreal y1, mreal y2, mreal z1=0, mreal z2=0, mreal c1=0, mreal c2=0) { SetRanges(mglPoint(x1,y1,z1,c1),mglPoint(x2,y2,z2,c2)); } void SetRanges(mglPoint v1, mglPoint v2); /// Set values of mglGraph::Cmin and mglGraph::Cmax as minimal and maximal values of data a void CRange(HCDT a, bool add = false, mreal fact=0); void CRange(mreal v1,mreal v2,bool add=false); /// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a void XRange(HCDT a, bool add = false, mreal fact=0); void XRange(mreal v1,mreal v2,bool add=false); /// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a void YRange(HCDT a, bool add = false, mreal fact=0); void YRange(mreal v1,mreal v2,bool add=false); /// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a void ZRange(HCDT a, bool add = false, mreal fact=0); void ZRange(mreal v1,mreal v2,bool add=false); /// Set ranges for automatic variables void SetAutoRanges(mreal x1, mreal x2, mreal y1=0, mreal y2=0, mreal z1=0, mreal z2=0, mreal c1=0, mreal c2=0); /// Set axis origin void SetOrigin(mreal x0, mreal y0, mreal z0=NAN, mreal c0=NAN); /// Save ranges into internal variable and put parsed mreal SaveState(const char *opt); /// Load ranges from internal variable void LoadState(); /// Increase ZMin mreal AdjustZMin() { ZMin /= MGL_FEPSILON; return Max.z - ZMin*(Max.z-Min.z); } /// Safetly set the transformation formulas for coordinate. void SetFunc(const char *EqX, const char *EqY, const char *EqZ=0, const char *EqA=0); /// Set one of predefined transformation rule void SetCoor(int how); /// Safetly set the cutting off condition (formula). void CutOff(const char *EqCut); /// Set to draw Ternary axis (triangle like axis, grid and so on) void Ternary(int tern); /// Set cutting for points outside of bounding box inline void SetCut(bool val) { set(val, MGL_ENABLE_CUT); } /// Set additional cutting box inline void SetCutBox(mreal x1, mreal y1, mreal z1, mreal x2, mreal y2, mreal z2) { CutMin.Set(x1,y1,z1); CutMax.Set(x2,y2,z2); } inline void SetCutBox(mglPoint v1, mglPoint v2) { CutMin=v1; CutMax=v2; } /// Reset mask to solid state inline void ResetMask() { mask = MGL_SOLID_MASK; MaskAn = DefMaskAn; } /// Set default mask rotation angle inline void SetMaskAngle(int angle) { DefMaskAn = angle; } /// Set the using of light on/off. virtual bool Light(bool enable) { bool t=get(MGL_ENABLE_LIGHT); set(enable,MGL_ENABLE_LIGHT); return t; } /// Set to attach light sources to inplot. virtual bool AttachLight(bool enable) { bool t=get(MGL_LOCAL_LIGHT); set(enable,MGL_LOCAL_LIGHT); return t; } /// Set ambient light brightness virtual void SetAmbient(mreal bright=0.5); /// Set diffusive light brightness virtual void SetDiffuse(mreal bright=0.5); /// Use diffusive light (only for local light sources) inline void SetDifLight(bool dif) { SetDiffuse(dif?0.5:0); } /// Set the transparency on/off. virtual bool Alpha(bool enable) { bool t=get(MGL_ENABLE_ALPHA); set(enable,MGL_ENABLE_ALPHA); return t; } /// Set default value of alpha-channel inline void SetAlphaDef(mreal val) { AlphaDef=val; } /// Set default palette inline void SetPalette(const char *colors) { Txt[0].Set(mgl_have_color(colors)?colors:MGL_DEF_PAL,-1); } inline void ResetPal() { CurrPal=0; } inline long GetNumPal(long id) const { return Txt[labs(id)/256].n; } /// Set default color scheme inline void SetDefScheme(const char *colors) { Txt[1].Set(mgl_have_color(colors)?colors:MGL_DEF_SCH); } /// Set number of mesh lines inline void SetMeshNum(int val) { MeshNum=val; } /// Set relative width of rectangles in Bars, Barh, BoxPlot inline void SetBarWidth(mreal val) { BarWidth=val>0?val:-BarWidth*val; } /// Set size of marks inline void SetMarkSize(mreal val) { MarkSize=val>0?0.02*val:-val*MarkSize; } /// Set size of arrows inline void SetArrowSize(mreal val) { ArrowSize=val>0?0.03*val:-val*ArrowSize; } /// Get unscaled arrow size inline mreal GetArrowSize() const { return ArrowSize/0.03; } /// Set warning code ant fill Message void SetWarn(int code, const char *who); int inline GetWarn() const { return WarnCode; } virtual void StartAutoGroup (const char *)=0; void StartGroup(const char *name, int id); virtual void EndGroup()=0; // { LoadState(); } /// Highlight group inline void Highlight(int id) { HighId=id; } /// Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72) virtual void SetFontSizePT(mreal pt, int dpi=72){ FontSize = pt*27.f/dpi; } /// Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt) inline void SetFontSizeCM(mreal cm, int dpi=72) { SetFontSizePT(cm*28.45f,dpi); } /// Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt) inline void SetFontSizeIN(mreal in, int dpi=72) { SetFontSizePT(in*72.27f,dpi); } /// Set font typeface. Note that each mglFont instance can be used with ONLY ONE mglGraph instance at a moment of time! void SetFont(mglFont *f); /// Get current typeface. Note that this variable can be deleted at next SetFont() call! inline mglFont *GetFont() { return fnt; } /// Restore font void RestoreFont(); /// Load font from file void LoadFont (const char *name, const char *path=NULL); /// Copy font from another mglGraph instance void CopyFont(mglBase *gr); /// Set default font size inline void SetFontSize(mreal val) { FontSize=val>0 ? val:-FontSize*val; } inline mreal GetFontSize() const { return FontSize; } mreal TextWidth(const char *text, const char *font, mreal size) const MGL_FUNC_PURE; mreal TextWidth(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE; mreal TextHeight(const char *text, const char *font, mreal size) const MGL_FUNC_PURE; mreal TextHeight(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE; mreal TextHeight(const char *font, mreal size) const MGL_FUNC_PURE; inline mreal FontFactor() const { return font_factor; } virtual mreal GetRatio() const MGL_FUNC_CONST; virtual int GetWidth() const MGL_FUNC_CONST; virtual int GetHeight() const MGL_FUNC_CONST; /// Add user-defined glyph void DefineGlyph(HCDT x, HCDT y, unsigned char id=0); /// Set to use or not text rotation inline void SetRotatedText(bool val) { set(val,MGL_ENABLE_RTEXT); } /// Set default font style and color inline void SetFontDef(const char *font){ mgl_strncpy(FontDef, font, 31); } /// Set to use or not text rotation inline void SetTickRotate(bool val) { set(val,MGL_TICKS_ROTATE); } /// Set to use or not text rotation inline void SetTickSkip(bool val) { set(val,MGL_TICKS_SKIP); } /// Add string to legend void AddLegend(const char *text,const char *style); void AddLegend(const wchar_t *text,const char *style); /// Clear saved legend string inline void ClearLegend() { Leg.clear(); } /// Set plot quality virtual void SetQuality(int qual=MGL_DRAW_NORM) { Quality=qual; } inline int GetQuality() const { return Quality; } inline void SetDrawReg(long nx=1, long ny=1, long m=0) { dr_x=nx; dr_y=ny; dr_p=m; } // ~~~~~~~~~~~~~~~~~~~~~~ Developer functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// Add point to the Pnt and return its position inline long AddPnt(mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1) { return AddPnt(&B,p,c,n,a,scl); } long AddPnt(const mglMatrix *M, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1); bool AddPntQ(mglPnt &q, const mglMatrix *M, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1); inline bool AddPntQ(mglPnt &q, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1) { return AddPntQ(q,&B,p,c,n,a,scl); } inline bool AddPntQ(long id, const mglMatrix *M, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1) { return AddPntQ(Pnt[id],M,p,c,n,a,scl); } inline bool AddPntQ(long id, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1) { return AddPntQ(Pnt[id],&B,p,c,n,a,scl); } inline void SetPntOff(size_t id) { Pnt[id].x=NAN; } long AllocPnts(size_t num); long PushPnts(size_t num, const mglPnt *qq); long CopyNtoC(long k, mreal c); bool CopyNtoC(mglPnt &q, long k, mreal c); inline bool CopyNtoC(long id, long k, mreal c) { return (id>=0)?CopyNtoC(Pnt[id],k,c):false; } long CopyProj(long from, mglPoint p, mglPoint n, short sub=0); bool CopyProj(mglPnt &q, long from, mglPoint p, mglPoint n, short sub=0); void CopyProj(long id, long from, mglPoint p, mglPoint n, short sub=0) { if(id>=0) CopyProj(Pnt[id],from,p,n,sub); } void DisablePnt(long id) { Pnt[id].x = NAN; } void SetRGBA(long k, const mglColor &c) { if(k>=0) {mglPnt &p=Pnt[k]; p.r = c.r; p.g = c.g; p.b = c.b; p.a = c.a;} } virtual void Reserve(long n); ///< Allocate n-cells for Pnt and return current position /// Set to reduce accuracy of points (to reduce size of output files) inline void SetReduceAcc(bool val) { set(val, MGL_REDUCEACC); } /// Add glyph of current font to the Glf and return its position long AddGlyph(int s, long j); /// Add glyph to the Glf and return its position long AddGlyph(unsigned char id); /// Add active point as k-th element of Pnt void AddActive(long k,int n=0); /// Clear unused points and primitives void ClearUnused(); inline mreal GetPenWidth() { return PenWidth; } inline const mglMatrix *GetB() const { return &B; } inline mglPoint GetPntP(long i) const { const mglPnt &p=Pnt[i]; return mglPoint(p.x,p.y,p.z); } inline mglPoint GetPntN(long i) const { const mglPnt &p=Pnt[i]; return mglPoint(p.u,p.v,p.w); } inline mglColor GetPntC(long i) const { const mglPnt &p=Pnt[i]; return mglColor(p.r,p.g,p.b,p.a); } inline float GetClrC(long i) const { return Pnt[i].c; } inline const mglGlyph &GetGlf(long i) const { return Glf[i]; } inline long GetGlfNum() const { return Glf.size(); } inline const mglPnt &GetPnt(long i) const { return Pnt[i]; } inline long GetPntNum() const { return Pnt.size(); } inline bool SamePnt(long i, long j) const { if(i<0 || j<0) return true; const mglPnt &p=Pnt[i], &q=Pnt[j]; return mgl_isnan(p.x) || mgl_isnan(q.x) || (p.x==q.x && p.y==q.y); } inline bool ValidPnt(size_t i) { return mgl_isnum(Pnt[i].x); } // inline mglPrim &GetPrm(long i) { return Prm[i]; } inline mglPrim &GetPrm(long i, bool sort=true) { return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i]; } inline const mglPrim &GetPrm(long i, bool sort=true) const { return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i]; } inline long GetPrmNum() const { return Prm.size(); } inline const mglText &GetPtx(long i) const { return Ptx[i]; } inline long GetPtxNum() const { return Ptx.size(); } inline const mglTexture &GetTxt(long i) const { return Txt[i]; } inline long GetTxtNum() const { return Txt.size(); } /// Scale coordinates and cut off some points virtual bool ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan=true) const; inline const mglBlock &GetSub(size_t i) const { return Sub[i]; } inline const mglBlock &GetSub() const { return Sub.back(); } virtual mreal GetOrgX(char dir, bool inv=false) const=0; ///< Get Org.x (parse NAN value) virtual mreal GetOrgY(char dir, bool inv=false) const=0; ///< Get Org.y (parse NAN value) virtual mreal GetOrgZ(char dir, bool inv=false) const=0; ///< Get Org.z (parse NAN value) /// Get color depending on single variable z, which should be scaled if scale=true inline mreal GetC(long s,mreal z,bool scale = true) const { return s+(scale?GetA(z):(z<0?0:z/MGL_FEPSILON)); } // { return s+(scale?GetA(z):(z>0?z/MGL_FEPSILON:0)); } /// Get alpha value depending on single variable a mreal GetA(mreal a) const MGL_FUNC_PURE; /// Set pen/palette char SetPenPal(const char *stl, long *id=0, bool pal=true); /// Add texture (like color scheme) and return the position of first color long AddTexture(const char *cols, int smooth=0); // inline mreal AddTexture(char col) { return AddTexture(mglColor(col)); } mreal AddTexture(mglColor col); inline void DefColor(mglColor col) { CDef = AddTexture(col); } /// Set mask for face coloring void SetMask(const char *mask); /// Set next color from palette mreal NextColor(long &id); mreal NextColor(long id, long sh); virtual void mark_plot(long p, char type, mreal size=1)=0; virtual void arrow_plot(long p1, long p2, char st)=0; virtual void line_plot(long p1, long p2)=0; virtual void trig_plot(long p1, long p2, long p3)=0; virtual void quad_plot(long p1, long p2, long p3, long p4)=0; virtual void smbl_plot(long p1, char id, double size)=0; void curve_plot(size_t n, size_t kq, size_t step=1); virtual void Glyph(mreal x, mreal y, mreal f, int style, long icode, mreal col)=0; virtual float GetGlyphPhi(const mglPnt &q, float phi)=0; virtual mreal text_plot(long p,const wchar_t *text,const char *fnt,mreal size=-1,mreal sh=0,mreal col=-('k'),bool rot=true)=0; void vect_plot(long p1, long p2, mreal s=1); // check if visible virtual bool trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const =0; virtual bool quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const =0; inline mreal mark_size() { return MarkSize*font_factor; } // inline char last_color() { return last_style[1]; } inline const char *last_line() { return last_style; } int PrmCmp(size_t i, size_t j) const MGL_FUNC_PURE; // compare 2 primitives with indexes i,j /// Check if plot termination is asked bool NeedStop() { if(event_cb) event_cb(event_par); return Stop; } /// Ask to stop drawing void AskStop(bool stop=true) { Stop = stop; } /// Set callback function for event processing void SetEventFunc(void (*func)(void *), void *par) { event_cb=func; event_par=par; } protected: volatile bool Stop; ///< Flag that execution should be terminated. void (*event_cb)(void *); ///< Function to be called for event processing void *event_par; ///< Parameter for event processing function mglPoint OMin; ///< Lower edge for original axis (before scaling) mglPoint OMax; ///< Upper edge for original axis (before scaling) mglPoint AMin; ///< Lower edge for axis scaling mglPoint AMax; ///< Upper edge for axis scaling mglPoint FMin; ///< Actual lower edge after transformation formulas. mglPoint FMax; ///< Actual upper edge after transformation formulas. mglPoint Org; ///< Center of axis cross section. int WarnCode; ///< Warning code size_t *PrmInd; ///< Indexes of sorted primitives mglStack Pnt; ///< Internal points mglStack Prm; ///< Primitives (lines, triangles and so on) -- need for export std::vector Sub; ///< InPlot regions std::vector Ptx; ///< Text labels for mglPrim std::vector Leg; ///< Text labels for legend std::vector Glf; ///< Glyphs data std::vector Txt; ///< Pointer to textures #if MGL_HAVE_PTHREAD pthread_mutex_t mutexPnt, mutexTxt, mutexLeg, mutexGlf, mutexAct, mutexDrw; pthread_mutex_t mutexSub, mutexPrm, mutexPtx, mutexStk, mutexGrp, mutexClf; #endif void *lockClf; ///< pointer to mutex for mglStack int TernAxis; ///< Flag that Ternary axis is used unsigned PDef; ///< Pen bit mask mreal pPos; ///< Current position in pen mask mreal PenWidth; ///< Pen width for further line plotting (must be >0 !!!) // long numT; ///< Number of textures mreal AmbBr; ///< Default ambient light brightness mreal DifBr; ///< Default diffusive light brightness mreal persp; ///< Original value for perspective mglMatrix Bp; ///< Transformation matrix for View() and Zoom() mglMatrix B; ///< Transformation matrix mglMatrix B1; ///< Transformation matrix for colorbar mglFont *fnt; ///< Class for printing vector text mreal FontSize; ///< The size of font for tick and axis labels char FontDef[32]; ///< Font specification (see mglGraph::Puts). Default is Roman with align at center. int Quality; ///< Quality of plot (0x0-pure, 0x1-fast; 0x2-fine; 0x4 - low memory) HMEX fx; ///< Transformation formula for x direction. HMEX fy; ///< Transformation formula for y direction. HMEX fz; ///< Transformation formula for z direction. HMEX fa; ///< Transformation formula for coloring. HMEX fc; ///< Cutting off condition (formula). long CurrPal; ///< Current palette index mreal MarkSize; ///< The size of marks for 1D plots. mreal ArrowSize; ///< The size of arrows. char last_style[64];///< Last pen style TODO: replace by std::string mreal font_factor; ///< Font scaling factor long dr_x, dr_y, dr_p; ///< default drawing region for quality&4 mode virtual void LightScale(const mglMatrix *M)=0; ///< Scale positions of light sources void ClearPrmInd(); // block for SaveState() mglPoint MinS; ///< Saved lower edge of bounding box for graphics. mglPoint MaxS; ///< Saved upper edge of bounding box for graphics. mreal MSS, ASS, FSS, ADS, MNS, LSS; ///< Saved state mreal PrevState; ///< Previous value of SaveState() long CSS; ///< Saved flags bool saved; ///< State is saved std::string leg_str;///< text to be save in legend union { uint64_t mask; ///< Mask to be used for coloring unsigned char mask_ch[8]; }; int MaskAn; ///< Mask rotation angle in degrees int DefMaskAn; ///< Default mask rotation angle in degrees private: mglBase(const mglBase &){} // copying is not allowed const mglBase &operator=(const mglBase &t){return t;} // copying is not allowed mglPoint CutMin; ///< Lower edge of bounding box for cut off. mglPoint CutMax; ///< Upper edge of bounding box for cut off. bool RecalcCRange(); ///< Recalculate internal parameter for correct coloring. void RecalcBorder(); ///< Recalculate internal parameter for correct transformation rules. bool SetFBord(mreal x,mreal y,mreal z); ///< Set internal boundng box depending on transformation formula void ClearEq(); ///< Clear the used variables for axis transformation }; //----------------------------------------------------------------------------- bool MGL_EXPORT mgl_check_dim0(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less=false); bool MGL_EXPORT mgl_check_dim1(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less=false); bool MGL_EXPORT mgl_check_dim2(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, bool less=false); bool MGL_EXPORT mgl_check_dim3(HMGL gr, bool both, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *name); bool MGL_EXPORT mgl_check_vec3(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *name); bool MGL_EXPORT mgl_check_trig(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, int d=3); bool MGL_EXPORT mgl_isnboth(HCDT x, HCDT y, HCDT z, HCDT a); bool MGL_EXPORT mgl_isboth(HCDT x, HCDT y, HCDT z, HCDT a); inline bool mgl_islog(mreal a,mreal b) { return a*b>0 && (b/a+a/b)>=10.1; } //----------------------------------------------------------------------------- #endif #endif ����������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/font.h��������������������������������������������������������������������0000644�0001750�0001750�00000017261�13513030041�016557� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * font.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ //----------------------------------------------------------------------------- #ifndef _MGL_FONT_H_ #define _MGL_FONT_H_ #include "mgl2/define.h" //----------------------------------------------------------------------------- #define MGL_FONT_BOLD 0x01000000 // This value is used binary #define MGL_FONT_ITAL 0x02000000 // This value is used binary #define MGL_FONT_BOLD_ITAL 0x03000000 #define MGL_FONT_WIRE 0x04000000 #define MGL_FONT_OLINE 0x08000000 // This value is used binary #define MGL_FONT_ULINE 0x10000000 #define MGL_FONT_ZEROW 0x20000000 // internal codes #define MGL_FONT_UPPER 0x40000000 #define MGL_FONT_LOWER 0x80000000 #define MGL_FONT_ROMAN 0xfcffffff #define MGL_FONT_MASK 0x00ffffff #define MGL_COLOR_MASK 0xffffff00 #define MGL_FONT_STYLE 0x3f000000 //----------------------------------------------------------------------------- struct mglGlyphDescr { wchar_t id; ///< Unicode ID for glyph int tr[4]; ///< Shift of glyph description by triangles (for solid font) int ln[4]; ///< Shift of glyph description by lines (for wire font) short numt[4]; ///< Number of triangles in glyph description (for solid font) short numl[4]; ///< Number of lines in glyph description (for wire font) short width[4]; ///< Width of glyph for wire font short y1[4], y2[4]; ///< minimal and maximal y-coordinates mglGlyphDescr() { memset(this,0,sizeof(mglGlyphDescr)); } }; inline bool operator<(const mglGlyphDescr &a,const mglGlyphDescr &b) { return a.id(const mglGlyphDescr &a,const mglGlyphDescr &b) { return a.id>b.id; } #if defined(_MSC_VER) MGL_EXTERN template class MGL_EXPORT std::vector; #endif //----------------------------------------------------------------------------- extern const float mgl_fact; struct MGL_EXPORT mglTeXsymb { unsigned kod; const wchar_t *tex; }; const float mgl_fgen = 4*14; /// Get font color, style and align for internal parser bool MGL_EXPORT mglGetStyle(const char *how, int *font, int *align=0); long MGL_EXPORT mgl_internal_code(unsigned s, const std::vector &glyphs); class mglBase; //----------------------------------------------------------------------------- /// Class for font typeface and text plotting procedures class MGL_EXPORT mglFont { public: mglBase *gr; ///< mglBase class used for drawing characters mglFont(const char *name=0, const char *path=0); virtual ~mglFont(); bool parse; ///< Parse LaTeX symbols /// Load font data to memory. Normally used by constructor. bool Load(const char *base, const char *path=0); /// Load binary font data to memory. Normally used by constructor. bool LoadBin(const char *base, const char *path=0); /// Save binary font data size_t SaveBin(const char *fname); /// Free memory void Clear(); /// Copy data from other font void Copy(mglFont *); /// Restore default font void Restore(); /// Return true if font is loaded inline bool Ready() const { return GetNumGlyph()!=0; } /// Get height of text float Height(int font) const MGL_FUNC_PURE; /// Get height of text float Height(const char *how) const MGL_FUNC_PURE; /// Print text string for font specified by string float Puts(const char *str,const char *how,float c1,float c2) const; /// Get width of text string for font specified by string float Width(const char *str, const char *how, float *y1=0, float *y2=0) const; /// Print text string for font specified by string float Puts(const wchar_t *str,const char *how,float c1,float c2) const; /// Get width of text string for font specified by string float Width(const wchar_t *str,const char *how, float *y1=0, float *y2=0) const; /// Get internal code for symbol inline long Internal(unsigned s) const { return mgl_internal_code(s,glyphs); } /// Return number of glyphs inline unsigned GetNumGlyph() const { return glyphs.size(); }; /// Return some of pointers inline const short *GetTr(int s, long j) const { return Buf+glyphs[j].tr[s]; } inline const short *GetLn(int s, long j) const { return Buf+glyphs[j].ln[s]; } inline int GetNt(int s, long j) const { return glyphs[j].numt[s]; } inline int GetNl(int s, long j) const { return glyphs[j].numl[s]; } inline short GetWidth(int s, long j) const { return glyphs[j].width[s]; } inline float GetFact(int s) const { return fact[s]; } inline wchar_t GetUnicode(long j) const { return j>=0?glyphs[j].id:0; } protected: std::vector glyphs; ///< information about know glyphs float fact[4]; ///< Divider for width of glyph short *Buf; ///< Buffer for glyph descriptions size_t numb; ///< Buffer size /// Print text string for font specified by integer constant float Puts(const wchar_t *str,int font,int align, float c1,float c2) const; /// Get height of text string for font specified by integer constant float Height(const wchar_t *str,int font) const; /// Get width of text string for font specified by integer constant float Width(const wchar_t *str,int font,int align, float &y1, float &y2) const; /// Replace TeX symbols by its UTF code and add font styles void Convert(const wchar_t *str, unsigned *res) const; /// Fill minimal and maximal y-coordinates void FillY12(); /// Draw string recursively /* x,y - position, f - factor, style: 0x1 - italic, 0x2 - bold, 0x4 - overline, 0x8 - underline, 0x10 - empty (not draw) */ float Puts(const unsigned *str, float x,float y,float f,int style,float c1,float c2, float &y1, float &y2) const; /// Parse LaTeX command unsigned Parse(const wchar_t *s) const; /// Get symbol for character ch with given font style unsigned Symbol(char ch) const MGL_FUNC_PURE; private: float get_ptr(long &i,unsigned *str, unsigned **b1, unsigned **b2,float &w1,float &w2, float f1, float f2, int st) const; bool read_data(const char *fname, int s, std::vector &buf, std::vector &extra); void main_copy(); bool read_main(const char *fname, std::vector &buf); inline void mem_alloc(long numg) { glyphs.resize(numg); } bool read_def(); void draw_ouline(int st, float x, float y, float f, float g, float ww, float ccol) const; }; //----------------------------------------------------------------------------- #endif //----------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/define.h������������������������������������������������������������������0000644�0001750�0001750�00000037332�13513030041�017044� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * define.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_DEFINE_H_ #define _MGL_DEFINE_H_ //----------------------------------------------------------------------------- // Disable warnings for MSVC: // 4190 - C-linkage of std::complex, // 4996 - deprecated abi functions // 4786 - disable warnings on 255 char debug symbols // 4231 - disable warnings on extern before template instantiation // 4800 - "int,uint32_t,etc" forcing value to bool 'true' or 'false' (performance warning) // 4244 - conversion from 'mreal,double' to 'float', possible loss of data // 4267 - conversion from 'size_t' to 'long,int,etc', possible loss of data // 4305 - truncation from 'double' to 'float' // 4251 - class 'type' needs to have dll-interface to be used by clients of class 'type2' #if defined(_MSC_VER) #pragma warning(disable: 4190 4996 4786 4800 4244 4267 4305 4251) #endif #if defined(_WIN32) && !defined(WIN32) #define WIN32 1 #endif #include "mgl2/config.h" #ifndef SWIG #if MGL_HAVE_PTHR_WIDGET|MGL_HAVE_PTHREAD #include #endif #include "mgl2/dllexport.h" #if defined(MGL_LIB_MSVC) #define MGL_EXTERN #else #define MGL_EXTERN extern #endif #if defined(_MSC_VER) #define MGL_OBSOLETE MGL_NO_EXPORT #else #define MGL_OBSOLETE MGL_EXPORT #endif #if MGL_HAVE_ATTRIBUTE #define MGL_FUNC_CONST __attribute__((const)) #define MGL_FUNC_PURE __attribute__((pure)) #else #define MGL_FUNC_CONST #define MGL_FUNC_PURE #endif #define MGL_EXPORT_CONST MGL_EXPORT MGL_FUNC_CONST #define MGL_EXPORT_PURE MGL_EXPORT MGL_FUNC_PURE #define MGL_LOCAL_CONST MGL_NO_EXPORT MGL_FUNC_CONST #define MGL_LOCAL_PURE MGL_NO_EXPORT MGL_FUNC_PURE #if MGL_HAVE_RVAL // C++11 don't support register keyword #endif #endif //----------------------------------------------------------------------------- #ifdef MGL_SRC #if MGL_USE_GETTEXT #include #define _(x) gettext(x) #else #define _(x) (x) #endif #if MGL_HAVE_ZLIB #include #ifndef Z_BEST_COMPRESSION #define Z_BEST_COMPRESSION 9 #endif #else #define gzFile FILE* #define gzread(fp,buf,size) fread(buf,1,size,fp) #define gzopen fopen #define gzclose fclose #define gzprintf fprintf #define gzgets(fp,str,size) fgets(str,size,fp) #define gzgetc fgetc #endif #endif #if (defined(_MSC_VER) && (_MSC_VER<1600)) || defined(__BORLANDC__) typedef signed char int8_t; typedef signed short int16_t; typedef signed long int32_t; typedef signed long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; typedef unsigned long long uint64_t; #else #include #endif #if defined(__BORLANDC__) typedef unsigned long uintptr_t; #endif #if ((defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(M_PI)) //_MSC_VER needs this before math.h #define _USE_MATH_DEFINES #endif #include #include #include #include #include #if defined(_MSC_VER) typedef long msize; #define collapse(a) // MSVS don't support OpenMP 3.* #if (_MSC_VER<=1800) #define strtoull _strtoui64 //#define hypot _hypot #define getcwd _getcwd #define chdir _chdir // BORLAND has chdir #endif #define snprintf _snprintf #if (_MSC_VER<1600) // based on https://hg.python.org/cpython/rev/9aedb876c2d7 #define hypot _hypot #endif #else typedef size_t msize; #endif #if !MGL_SYS_NAN #include #include const unsigned long long mgl_nan[2] = {0x7fffffffffffffff, 0x7fffffff}; const unsigned long long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000}; #define NANd (*(double*)mgl_nan) #define NANf (*(float*)(mgl_nan+1)) #define INFd (*(double*)mgl_inf) #define INFf (*(float*)(mgl_inf+1)) #if !defined(NAN) #if MGL_USE_DOUBLE #define NAN NANd #else #define NAN NANf #endif #endif #if !defined(INFINITY) #if MGL_USE_DOUBLE #define INFINITY INFd #else #define INFINITY INFf #endif #endif #endif // !MGL_SYS_NAN #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif //----------------------------------------------------------------------------- #ifdef WIN32 #define mglprintf _snwprintf #else #define mglprintf swprintf #endif //#define FLT_EPS 1.1920928955078125e-07 //----------------------------------------------------------------------------- #if MGL_USE_DOUBLE typedef double mreal; #define MGL_EPSILON (1.+1e-10) #define MGL_MIN_VAL 1e-307 #else typedef float mreal; #define MGL_EPSILON (1.+1e-5) #define MGL_MIN_VAL 1e-37 #endif #define MGL_FEPSILON (1.+1e-5) //----------------------------------------------------------------------------- #ifndef MGL_CMAP_COLOR #define MGL_CMAP_COLOR 32 #endif //----------------------------------------------------------------------------- #ifndef MGL_DEF_VIEWER #define MGL_DEF_VIEWER "evince" #endif //----------------------------------------------------------------------------- enum{ // types of predefined curvelinear coordinate systems mglCartesian = 0, // no transformation mglPolar, mglSpherical, mglParabolic, mglParaboloidal, mglOblate, mglProlate, mglElliptic, mglToroidal, mglBispherical, mglBipolar, mglLogLog, mglLogX, mglLogY }; //----------------------------------------------------------------------------- // types of drawing #define MGL_DRAW_WIRE 0 // fastest, no faces #define MGL_DRAW_FAST 1 // fast, no color interpolation #define MGL_DRAW_NORM 2 // high quality, slower #define MGL_DRAW_LMEM 4 // low memory usage (direct to pixel) #define MGL_DRAW_DOTS 8 // draw dots instead of primitives #define MGL_DRAW_NONE 9 // no ouput (for testing only) //----------------------------------------------------------------------------- enum{ // Codes for warnings/messages mglWarnNone = 0,// Everything OK mglWarnDim, // Data dimension(s) is incompatible mglWarnLow, // Data dimension(s) is too small mglWarnNeg, // Minimal data value is negative mglWarnFile, // No file or wrong data dimensions mglWarnMem, // Not enough memory mglWarnZero, // Data values are zero mglWarnLeg, // No legend entries mglWarnSlc, // Slice value is out of range mglWarnCnt, // Number of contours is zero or negative mglWarnOpen, // Couldn't open file mglWarnLId, // Light: ID is out of range mglWarnSize, // Setsize: size(s) is zero or negative mglWarnFmt, // Format is not supported for that build mglWarnTern, // Axis ranges are incompatible mglWarnNull, // Pointer is NULL mglWarnSpc, // Not enough space for plot mglScrArg, // Wrong argument(s) in MGL script mglScrCmd, // Wrong command in MGL script mglScrLong, // Too long line in MGL script mglScrStr, // Unbalanced ' in MGL script mglScrTemp, // Change temporary data in MGL script mglWarnEnd // Maximal number of warnings (must be last) }; //----------------------------------------------------------------------------- #define MGL_DEF_PAL "bgrcmyhlnqeupH" // default palette #define MGL_DEF_SCH "BbcyrR" // default palette #define MGL_COLORS "kwrgbcymhWRGBCYMHlenpquLENPQU" //----------------------------------------------------------------------------- /// Brushes for mask with symbol "-+=;oOsS~<>jdD*^" correspondingly extern MGL_EXPORT uint64_t mgl_mask_val[16]; #define MGL_MASK_ID "-+=;oOsS~<>jdD*^" #define MGL_SOLID_MASK 0xffffffffffffffff //----------------------------------------------------------------------------- #define MGL_TRANSP_NORM 0x00000000 #define MGL_TRANSP_GLASS 0x00000001 #define MGL_TRANSP_LAMP 0x00000002 #define MGL_ENABLE_CUT 0x00000004 ///< Flag which determines how points outside bounding box are drown. #define MGL_ENABLE_RTEXT 0x00000008 ///< Use text rotation along axis #define MGL_AUTO_FACTOR 0x00000010 ///< Enable autochange PlotFactor #define MGL_ENABLE_ALPHA 0x00000020 ///< Flag that Alpha is used #define MGL_ENABLE_LIGHT 0x00000040 ///< Flag of using lightning #define MGL_TICKS_ROTATE 0x00000080 ///< Allow ticks rotation #define MGL_TICKS_SKIP 0x00000100 ///< Allow ticks rotation // flags for internal use only #define MGL_DISABLE_SCALE 0x00000200 ///< Temporary flag for disable scaling (used for axis) #define MGL_FINISHED 0x00000400 ///< Flag that final picture (i.e. mglCanvas::G) is ready #define MGL_USE_GMTIME 0x00000800 ///< Use gmtime instead of localtime #define MGL_SHOW_POS 0x00001000 ///< Switch to show or not mouse click position #define MGL_CLF_ON_UPD 0x00002000 ///< Clear plot before Update() #define MGL_NOSUBTICKS 0x00004000 ///< Disable subticks drawing (for bounding box) #define MGL_LOCAL_LIGHT 0x00008000 ///< Keep light sources for each inplot #define MGL_VECT_FRAME 0x00010000 ///< Use DrwDat to remember all data of frames #define MGL_REDUCEACC 0x00020000 ///< Reduce accuracy of points (to reduce size of output files) #define MGL_PREFERVC 0x00040000 ///< Prefer vertex color instead of texture if output format supports #define MGL_ONESIDED 0x00080000 ///< Render only front side of surfaces if output format supports (for debugging) #define MGL_NO_ORIGIN 0x00100000 ///< Don't draw tick labels at axis origin #define MGL_GRAY_MODE 0x00200000 ///< Convert all colors to gray ones #define MGL_FULL_CURV 0x00400000 ///< Disable omitting points in straight-line part(s). #define MGL_NO_SCALE_REL 0x00800000 ///< Disable font scaling in relative inplots //----------------------------------------------------------------------------- #ifdef __cplusplus #include #include #include typedef std::complex dual; //----------------------------------------------------------------------------- inline bool mgl_isrange(double a, double b) { return fabs(a-b)>MGL_MIN_VAL && a-a==0. && b-b==0.; } inline bool mgl_isbad(double a) { return a-a!=0; } inline bool mgl_isbad(dual a) { return a-a!=mreal(0); } inline bool mgl_isfin(double a) { return a-a==0; } inline bool mgl_isfin(dual a) { return a-a==mreal(0); } inline bool mgl_isnum(double a) { return a==a; } inline bool mgl_isnum(dual a) { return a==a; } inline bool mgl_isnan(double a) { return a!=a; } inline bool mgl_isnan(dual a) { return a!=a; } inline int mgl_sign(double a) { return a<0?-1:1; } inline long mgl_int(double a) { return long(a+(a>=0?0.5:-0.5)); } inline double mgl_min(double a, double b) { return a>b?b:a; } inline double mgl_max(double a, double b) { return a>b?a:b; } inline long mgl_imin(long a, long b) { return a>b?b:a; } inline long mgl_imax(long a, long b) { return a>b?a:b; } inline void mgl_strncpy(char *a, const char *b, size_t s) { strncpy(a,b,s); a[s-1]=0; } //----------------------------------------------------------------------------- extern "C" { #endif //----------------------------------------------------------------------------- struct cmdual // complex number (bypass C/C++ incompatibility) { mreal re,im; // real and imaginary parts #ifdef __cplusplus operator dual() const { return dual(re,im); } mreal real() const { return re; } mreal imag() const { return im; } #endif }; #ifdef __cplusplus struct mdual : public cmdual { mdual(const cmdual &c) { re=c.re; im=c.im; } mdual(const std::complex &c) { re=c.real(); im=c.imag(); } mdual(const std::complex &c){ re=c.real(); im=c.imag(); } mdual(mreal r=0, mreal i=0) { re=r; im=i; } mdual &operator=(const cmdual &c) { re=c.re; im=c.im; return *this; } mdual &operator=(const std::complex &c) { re=c.real(); im=c.imag(); return *this; } mdual &operator=(const std::complex &c) { re=c.real(); im=c.imag(); return *this; } mdual &operator=(mreal r) { re=r; im=0; return *this; } }; #else typedef struct cmdual cmdual; typedef cmdual mdual; #if MGL_HAVE_C99_COMPLEX #include #if MGL_USE_DOUBLE typedef double _Complex dual; #else typedef float _Complex dual; #endif MGL_EXPORT dual mdual2c(cmdual c); MGL_EXPORT cmdual c2mdual(dual c); #endif #endif //----------------------------------------------------------------------------- extern float mgl_cos[360]; ///< contain cosine with step 1 degree //----------------------------------------------------------------------------- /// Calculate sqrt(x*x+y*y) double MGL_EXPORT_CONST mgl_hypot(double x, double y); /// Find length of wchar_t string (bypass standard wcslen bug) size_t MGL_EXPORT_PURE mgl_wcslen(const wchar_t *str); /// Get RGB values for given color id or fill by -1 if no one found void MGL_EXPORT mgl_chrrgb(char id, float rgb[3]); /// Get number of colors in the string size_t MGL_EXPORT_PURE mgl_get_num_color(const char *s, int smooth); /// Check if string contain color id and return its number long MGL_EXPORT_PURE mgl_have_color(const char *stl); /// Find symbol in string excluding {} and return its position or NULL MGL_EXPORT_PURE const char *mglchr(const char *str, char ch); /// Find any symbol from chr in string excluding {} and return its position or NULL MGL_EXPORT_PURE const char *mglchrs(const char *str, const char *chr); /// Set number of thread for plotting and data handling (for pthread version only) void MGL_EXPORT mgl_set_num_thr(int n); void MGL_EXPORT mgl_set_num_thr_(int *n); void MGL_EXPORT mgl_test_txt(const char *str, ...); void MGL_EXPORT mgl_set_test_mode(int enable); /// Remove spaces at begining and at the end of the string void MGL_EXPORT mgl_strtrim(char *str); void MGL_EXPORT mgl_wcstrim(wchar_t *str); /** Change register to lowercase (only for ANSI symbols) */ void MGL_EXPORT mgl_strlwr(char *str); void MGL_EXPORT mgl_wcslwr(wchar_t *str); /// Convert wchar_t* string into char* one void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size); /// Clear internal data for speeding up FFT and Hankel transforms void MGL_EXPORT mgl_clear_fft(); /// Set global warning message void MGL_EXPORT mgl_set_global_warn(const char *text); void MGL_EXPORT mgl_set_global_warn_(const char *text,int); /// Get text of global warning message(s) MGL_EXPORT_PURE const char *mgl_get_global_warn(); int MGL_EXPORT mgl_get_global_warn_(char *out, int len); /// Setup gettext usage. NOTE: Russian translation MUST be installed. void MGL_EXPORT mgl_textdomain(const char *argv0, const char *locale); void MGL_EXPORT mgl_textdomain_(const char *locale, int); /// size of var array const int MGL_VS = 'z'-'a'+1; #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif //----------------------------------------------------------------------------- ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/other.h�������������������������������������������������������������������0000644�0001750�0001750�00000035220�13513030041�016725� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * other.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_OTHER_H_ #define _MGL_OTHER_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Draw triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the triangle colors, else vertex colors. */ void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_triplot_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw triangle mesh for points in arrays {x,y,z} with color proportional to z. /** Style ‘#’ produce wire plot. */ void MGL_EXPORT mgl_triplot_xyz(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_triplot_xyz_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw triangle mesh for points in arrays {x,y} /** Style ‘#’ produce wire plot. */ void MGL_EXPORT mgl_triplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt); void MGL_EXPORT mgl_triplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, const char *sch, const char *opt,int,int); /// Draw quad mesh for points in arrays {x,y,z} with specified color c. /** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_quadplot_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw quad mesh for points in arrays {x,y,z} with color proportional to z. /** Style ‘#’ produce wire plot. */ void MGL_EXPORT mgl_quadplot_xyz(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_quadplot_xyz_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw quad mesh for points in arrays {x,y}. /** Style ‘#’ produce wire plot. */ void MGL_EXPORT mgl_quadplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt); void MGL_EXPORT mgl_quadplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, const char *sch, const char *opt,int,int); /// Draw manual contour lines for triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_tricont_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw manual contour lines for triangle mesh for points in arrays {x,y,z}. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ void MGL_EXPORT mgl_tricont_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_tricont_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_tricont_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_tricont_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int, int); /// Draw contour lines for triangle mesh for points in arrays {x,y,z}. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_tricont_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_tricont_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int, int); /// Draw manual contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c. /** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ void MGL_EXPORT mgl_tricontv_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_tricontv_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int); /// Draw manual contour tubes for triangle mesh for points in arrays {x,y,z}. /** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ void MGL_EXPORT mgl_tricontv_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_tricontv_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c. /** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_tricontv_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt); void MGL_EXPORT mgl_tricontv_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int, int); /// Draw contour tubes for triangle mesh for points in arrays {x,y,z}. /** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_tricontv_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_tricontv_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int, int); /// Draw dots in points {x,y,z}. void MGL_EXPORT mgl_dots(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_dots_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw semitransparent dots in points {x,y,z} with specified alpha a. void MGL_EXPORT mgl_dots_a(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_dots_a_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw semitransparent dots in points {x,y,z} with specified color c and alpha a. void MGL_EXPORT mgl_dots_ca(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt); void MGL_EXPORT mgl_dots_ca_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int,int); /// Draw surface reconstructed for points in arrays {x,y,z}. /** Style ‘#’ produce wired plot. */ void MGL_EXPORT mgl_crust(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt); void MGL_EXPORT mgl_crust_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int); /// Draw density plot for data at x = sVal /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_dens_x(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_dens_x_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw density plot for data at y = sVal /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_dens_y(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_dens_y_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw density plot for data at z = sVal /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_dens_z(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_dens_z_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw contour lines for data at x = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont_x(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_cont_x_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw contour lines for data at y = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont_y(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_cont_y_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw contour lines for data at z = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_cont_z(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_cont_z_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw manual contour lines for data at x = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont_x_val(HMGL graph, HCDT v, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_cont_x_val_(uintptr_t *graph, uintptr_t *v, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw manual contour lines for data at y = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont_y_val(HMGL graph, HCDT v, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_cont_y_val_(uintptr_t *graph, uintptr_t *v, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw manual contour lines for data at z = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. */ void MGL_EXPORT mgl_cont_z_val(HMGL graph, HCDT v, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_cont_z_val_(uintptr_t *graph, uintptr_t *v, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw solid contours for data at x = sVal /** Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf_x(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_contf_x_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw solid contours for data at y = sVal /** Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf_y(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_contf_y_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw solid contours for data at z = sVal /** Option "value" set the number of contour levels (default is 7). */ void MGL_EXPORT mgl_contf_z(HMGL graph, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_contf_z_(uintptr_t *graph, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw manual solid contours for data at x = sVal void MGL_EXPORT mgl_contf_x_val(HMGL graph, HCDT v, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_contf_x_val_(uintptr_t *graph, uintptr_t *v, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw manual solid contours for data at y = sVal void MGL_EXPORT mgl_contf_y_val(HMGL graph, HCDT v, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_contf_y_val_(uintptr_t *graph, uintptr_t *v, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); /// Draw manual solid contours for data at z = sVal void MGL_EXPORT mgl_contf_z_val(HMGL graph, HCDT v, HCDT a, const char *stl, double sVal, const char *opt); void MGL_EXPORT mgl_contf_z_val_(uintptr_t *graph, uintptr_t *v, uintptr_t *a, const char *stl, mreal *sVal, const char *opt,int,int); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/canvas_cf.h���������������������������������������������������������������0000644�0001750�0001750�00000116472�13513030041�017540� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * canvas_cf.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MGL_CANVAS_CF_H #define MGL_CANVAS_CF_H #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Create HMGL object with specified sizes HMGL MGL_EXPORT mgl_create_graph(int width, int height); uintptr_t MGL_EXPORT mgl_create_graph_(int *width, int *height); /// Delete HMGL object void MGL_EXPORT mgl_delete_graph(HMGL gr); void MGL_EXPORT mgl_delete_graph_(uintptr_t *gr); /// Set size of frame in pixels. Normally this function is called internally. void MGL_EXPORT mgl_set_size(HMGL gr, int width, int height); void MGL_EXPORT mgl_set_size_(uintptr_t *gr, int *width, int *height); /// Set size of frame in pixels, but don't erase primitives void MGL_EXPORT mgl_scale_size(HMGL gr, int width, int height); void MGL_EXPORT mgl_scale_size_(uintptr_t *gr, int *width, int *height); /// Scaling for all further set size calls. void MGL_EXPORT mgl_set_size_scl(double scl); void MGL_EXPORT mgl_set_size_scl_(double *scl); /// Set default parameters for plotting void MGL_EXPORT mgl_set_def_param(HMGL gr); void MGL_EXPORT mgl_set_def_param_(uintptr_t *gr); /// Combine plots from 2 canvases. Result will be saved into gr void MGL_EXPORT mgl_combine_gr(HMGL gr, HMGL gr2); void MGL_EXPORT mgl_combine_gr_(uintptr_t *gr, uintptr_t *gr2); /// Force preparing the image. It can be useful for OpenGL mode mostly. void MGL_EXPORT mgl_finish(HMGL gr); void MGL_EXPORT mgl_finish_(uintptr_t *gr); /// Force preparing the image and save result into background one. void MGL_EXPORT mgl_rasterize(HMGL gr); void MGL_EXPORT mgl_rasterize_(uintptr_t *gr); /// Set boundary box for export graphics into 2D file formats. /** If x2<0 (y2<0) then full width (height) will be used. * If x1<0 or y1<0 or x1>=x2|Width or y1>=y2|Height then cropping will be disabled. */ void MGL_EXPORT mgl_set_bbox(HMGL gr, int x1, int y1, int x2, int y2); void MGL_EXPORT mgl_set_bbox_(uintptr_t *gr, int *x1, int *y1, int *x2, int *y2); /// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1. void MGL_EXPORT mgl_pen_delta(HMGL gr, double d); void MGL_EXPORT mgl_pen_delta_(uintptr_t *gr, double *d); /// Set tick length void MGL_EXPORT mgl_set_tick_len(HMGL gr, double len, double stt); void MGL_EXPORT mgl_set_tick_len_(uintptr_t *gr, mreal *len, mreal *stt); /// Set axis and ticks style void MGL_EXPORT mgl_set_axis_stl(HMGL gr, const char *stl, const char *tck, const char *sub); void MGL_EXPORT mgl_set_axis_stl_(uintptr_t *gr, const char *stl, const char *tck, const char *sub, int,int,int); /// Auto adjust ticks void MGL_EXPORT mgl_adjust_ticks(HMGL gr, const char *dir); void MGL_EXPORT mgl_adjust_ticks_(uintptr_t *gr, const char *dir, int); /// Auto adjust ticks and set ticks format ("+E0123456789-fF") void MGL_EXPORT mgl_adjust_ticks_ext(HMGL gr, const char *dir, const char *stl); void MGL_EXPORT mgl_adjust_ticks_ext_(uintptr_t *gr, const char *dir, const char *stl, int, int); /// Set the ticks parameters void MGL_EXPORT mgl_set_ticks(HMGL gr, char dir, double d, int ns, double org); void MGL_EXPORT mgl_set_ticks_(uintptr_t *gr, char *dir, mreal *d, int *ns, mreal *org, int); /// Set the ticks parameters and specify ticks factor string void MGL_EXPORT mgl_set_ticks_fact(HMGL gr, char dir, double d, int ns, double org, const char *fact); void MGL_EXPORT mgl_set_ticks_factw(HMGL gr, char dir, double d, int ns, double org, const wchar_t *fact); void MGL_EXPORT mgl_set_ticks_fact_(uintptr_t *gr, char *dir, double *d, int *ns, double *org, const char *fact,int,int); /// Set manual ticks text (\n separated). Use "" to disable this feature. void MGL_EXPORT mgl_set_ticks_str(HMGL gr, char dir, const char *lbl, int add); void MGL_EXPORT mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *lbl, int *add,int,int); void MGL_EXPORT mgl_set_ticks_wcs(HMGL gr, char dir, const wchar_t *lbl, int add); /// Set manual ticks position and text (\n separated). Use "" to disable this feature. void MGL_EXPORT mgl_set_ticks_val(HMGL gr, char dir, HCDT val, const char *lbl, int add); void MGL_EXPORT mgl_set_ticks_val_(uintptr_t *gr, const char *dir, uintptr_t *val, const char *lbl, int *add,int,int); void MGL_EXPORT mgl_set_ticks_valw(HMGL gr, char dir, HCDT val, const wchar_t *lbl, int add); /// Add manual tick at given position. Use "" to disable this feature. void MGL_EXPORT mgl_add_tick(HMGL gr, char dir, double val, const char *lbl); void MGL_EXPORT mgl_add_tick_(uintptr_t *gr, const char *dir, mreal *val, const char *lbl,int,int); void MGL_EXPORT mgl_add_tickw(HMGL gr, char dir, double val, const wchar_t *lbl); /// Tune ticks (tune|1 for common multiplier, tune|2 for common component) void MGL_EXPORT mgl_tune_ticks(HMGL gr, int tune, double fact_pos); void MGL_EXPORT mgl_tune_ticks_(uintptr_t *gr, int *tune, mreal *fact_pos); /// Set templates for ticks void MGL_EXPORT mgl_set_tick_templ(HMGL gr, char dir, const char *templ); void MGL_EXPORT mgl_set_tick_templ_(uintptr_t *gr, const char *dir, const char *templ,int,int); void MGL_EXPORT mgl_set_tick_templw(HMGL gr, char dir, const wchar_t *templ); /// Set time templates for ticks void MGL_EXPORT mgl_set_ticks_time(HMGL gr, char dir, double d, const char *t); void MGL_EXPORT mgl_set_ticks_time_(uintptr_t *gr, const char *dir, mreal *d, const char *t,int,int); /// Set additional shift of tick labels void MGL_EXPORT mgl_set_tick_shift(HMGL gr, double sx, double sy, double sz, double sc); void MGL_EXPORT mgl_set_tick_shift_(uintptr_t *gr, mreal *sx, mreal *sy, mreal *sz, mreal *sc); /// Draws bounding box outside the plotting volume void MGL_EXPORT mgl_box(HMGL gr); void MGL_EXPORT mgl_box_(uintptr_t *gr); /// Draws bounding box outside the plotting volume with color c /** Style ‘@’ produce filled back faces. */ void MGL_EXPORT mgl_box_str(HMGL gr, const char *col, int ticks); void MGL_EXPORT mgl_box_str_(uintptr_t *gr, const char *col, int *ticks, int); /// Draw axises with ticks in direction(s) dir. /** Parameter \a dir may contain: * ‘xyzt’for drawing axis in corresponding direction; * ‘XYZT’ for drawing axis in corresponding direction but with inverted positions of labels; * ‘~’, ‘_’ for disabling tick labels; * ‘U’ for disabling rotation of tick labels; * ‘^’ for inverting default axis origin; * ‘!’ for disabling ticks tuning; * ‘AKDTVISO’ for drawing arrow at the end of axis; * ‘a’ for forced adjusting of axis ticks; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels. * Option "value" set the manual rotation angle for the ticks.*/ void MGL_EXPORT mgl_axis(HMGL gr, const char *dir, const char *stl, const char *opt); void MGL_EXPORT mgl_axis_(uintptr_t *gr, const char *dir, const char *stl, const char *opt,int,int,int); /// Draw grid lines perpendicular to direction(s) dir. void MGL_EXPORT mgl_axis_grid(HMGL gr, const char *dir,const char *pen, const char *opt); void MGL_EXPORT mgl_axis_grid_(uintptr_t *gr, const char *dir,const char *pen, const char *opt,int,int,int); /// Print the label text for axis dir. /** Option "value" set additional shifting of the label. */ void MGL_EXPORT mgl_label(HMGL gr, char dir, const char *text, double pos, const char *opt); void MGL_EXPORT mgl_label_(uintptr_t *gr, const char *dir, const char *text, mreal *pos, const char *opt,int,int,int); /// Print the label text for axis dir. /** Option "value" set additional shifting of the label. */ void MGL_EXPORT mgl_labelw(HMGL gr, char dir, const wchar_t *text, double pos, const char *opt); /// Draw colorbar at edge of axis /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ void MGL_EXPORT mgl_colorbar(HMGL gr, const char *sch); void MGL_EXPORT mgl_colorbar_(uintptr_t *gr, const char *sch,int); /// Draw colorbar at manual position /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ void MGL_EXPORT mgl_colorbar_ext(HMGL gr, const char *sch, double x, double y, double w, double h); void MGL_EXPORT mgl_colorbar_ext_(uintptr_t *gr, const char *sch, mreal *x, mreal *y, mreal *w, mreal *h, int); /// Draw colorbar with manual colors at edge of axis /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ void MGL_EXPORT mgl_colorbar_val(HMGL gr, HCDT dat, const char *sch); void MGL_EXPORT mgl_colorbar_val_(uintptr_t *gr, uintptr_t *dat, const char *sch,int); /// Draw colorbar with manual colors at manual position /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ void MGL_EXPORT mgl_colorbar_val_ext(HMGL gr, HCDT dat, const char *sch,double x, double y, double w, double h); void MGL_EXPORT mgl_colorbar_val_ext_(uintptr_t *gr, uintptr_t *dat, const char *sch, mreal *x, mreal *y, mreal *w, mreal *h, int); /// Add string to legend void MGL_EXPORT mgl_add_legend(HMGL gr, const char *text,const char *style); void MGL_EXPORT mgl_add_legend_(uintptr_t *gr, const char *text,const char *style,int,int); void MGL_EXPORT mgl_add_legendw(HMGL gr, const wchar_t *text,const char *style); /// Clear saved legend string void MGL_EXPORT mgl_clear_legend(HMGL gr); void MGL_EXPORT mgl_clear_legend_(uintptr_t *gr); /// Draw legend of accumulated strings at position {x,y} /** Parameter fnt may contain: * font style for legend text; * colors for background (first one), border (second one) and text (last one); * ‘A’ for positioning in absolute coordinates; * ‘^’ for positioning outside of specified point; * ‘-’ for arranging entries horizontally; * ‘#’ for drawing box around legend. * Option value set the space between line samples and text (default is 0.1).*/ void MGL_EXPORT mgl_legend_pos(HMGL gr, double x, double y, const char *font, const char *opt); void MGL_EXPORT mgl_legend_pos_(uintptr_t *gr, mreal *x, mreal *y, const char *font, const char *opt,int,int); /// Draw legend of accumulated strings /** Parameter fnt may contain: * font style for legend text; * colors for background (first one), border (second one) and text (last one); * ‘A’ for positioning in absolute coordinates; * ‘^’ for positioning outside of specified point; * ‘-’ for arranging entries horizontally; * ‘#’ for drawing box around legend. * Option value set the space between line samples and text (default is 0.1). * Parameter \a where sets position: 0 at bottom-left, 1 at bottom-right, 2 at top-left, 3 at top-right (default).*/ void MGL_EXPORT mgl_legend(HMGL gr, int where, const char *font, const char *opt); void MGL_EXPORT mgl_legend_(uintptr_t *gr, int *where, const char *font, const char *opt,int,int); /// Set number of marks in legend sample void MGL_EXPORT mgl_set_legend_marks(HMGL gr, int num); void MGL_EXPORT mgl_set_legend_marks_(uintptr_t *gr, int *num); /// Show current image void MGL_EXPORT mgl_show_image(HMGL gr, const char *viewer, int keep); void MGL_EXPORT mgl_show_image_(uintptr_t *gr, const char *viewer, int *keep, int); /// Write the frame in file (depending extension, write current frame if fname is empty) void MGL_EXPORT mgl_write_frame(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_frame_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using BMP format void MGL_EXPORT mgl_write_tga(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_tga_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using BMP format void MGL_EXPORT mgl_write_bmp(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_bmp_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using JPEG format void MGL_EXPORT mgl_write_jpg(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_jpg_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using PNG format with transparency void MGL_EXPORT mgl_write_png(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_png_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using PNG format without transparency void MGL_EXPORT mgl_write_png_solid(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_png_solid_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using PostScript format as bitmap void MGL_EXPORT mgl_write_bps(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_bps_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using PostScript format void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_eps_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using SVG format void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_svg_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using LaTeX format void MGL_EXPORT mgl_write_tex(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_tex_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using OBJ format void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int use_png); void MGL_EXPORT mgl_write_obj_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int,int); /// Write the frame in file using OBJ format (old version) void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr, int use_png); void MGL_EXPORT mgl_write_obj_old_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int,int); /// Write the frame in file using STL format (faces only) void MGL_EXPORT mgl_write_stl(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_stl_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Write the frame in file using OFF format void MGL_EXPORT mgl_write_off(HMGL gr, const char *fname,const char *descr, int colored); void MGL_EXPORT mgl_write_off_(uintptr_t *gr, const char *fname,const char *descr,int *colored,int,int); /// Write the frame in file using XYZ format void MGL_EXPORT mgl_write_xyz(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_xyz_(uintptr_t *gr, const char *fname,const char *descr,int,int); /*void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_x3d_(uintptr_t *gr, const char *fname,const char *descr,int,int); void MGL_EXPORT mgl_write_wgl(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_wgl_(uintptr_t *gr, const char *fname,const char *descr,int,int);*/ /// Write the frame in file using PRC format void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char *descr, int make_pdf); void MGL_EXPORT mgl_write_prc_(uintptr_t *gr, const char *fname,const char *descr, int *make_pdf,int,int); /// Write the frame in file using GIF format (only for current frame!) void MGL_EXPORT mgl_write_gif(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_gif_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Start write frames to cinema using GIF format void MGL_EXPORT mgl_start_gif(HMGL gr, const char *fname,int ms); void MGL_EXPORT mgl_start_gif_(uintptr_t *gr, const char *fname,int *ms,int); /// Stop writing cinema using GIF format void MGL_EXPORT mgl_close_gif(HMGL gr); void MGL_EXPORT mgl_close_gif_(uintptr_t *gr); /// Export points and primitives in file using MGLD format void MGL_EXPORT mgl_export_mgld(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_export_mgld_(uintptr_t *gr, const char *fname,const char *descr,int,int); /// Import points and primitives from file using MGLD format void MGL_EXPORT mgl_import_mgld(HMGL gr, const char *fname, int add); void MGL_EXPORT mgl_import_mgld_(uintptr_t *gr, const char *fname, int *add, int); /// Export in JSON format suitable for later drawing by JavaScript void MGL_EXPORT mgl_write_json(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_json_(uintptr_t *gr, const char *fname,const char *descr,int,int); void MGL_EXPORT mgl_write_json_z(HMGL gr, const char *fname,const char *descr); void MGL_EXPORT mgl_write_json_z_(uintptr_t *gr, const char *fname,const char *descr,int,int); MGL_EXPORT const char *mgl_get_json(HMGL gr); /// Get RGB values of current bitmap /** Position of element {i,j} is [3*i + 3*Width*j]. */ MGL_EXPORT const unsigned char *mgl_get_rgb(HMGL gr); MGL_EXPORT const unsigned char *mgl_get_rgb_(uintptr_t *gr); /// Get RGBA values of current bitmap /** Position of element {i,j} is [4*i + 4*Width*j]. */ MGL_EXPORT const unsigned char *mgl_get_rgba(HMGL gr); MGL_EXPORT const unsigned char *mgl_get_rgba_(uintptr_t *gr); /// Get RGBA values of background image /** Position of element {i,j} is [4*i + 4*Width*j]. */ MGL_EXPORT_PURE const unsigned char *mgl_get_background(HMGL gr); MGL_EXPORT_PURE const unsigned char *mgl_get_background_(uintptr_t *gr); /// Set object/subplot id void MGL_EXPORT mgl_set_obj_id(HMGL gr, int id); void MGL_EXPORT mgl_set_obj_id_(uintptr_t *gr, int *id); /// Get object id int MGL_EXPORT_PURE mgl_get_obj_id(HMGL gr, int x, int y); int MGL_EXPORT_PURE mgl_get_obj_id_(uintptr_t *gr, int *x, int *y); /// Get subplot id int MGL_EXPORT_PURE mgl_get_spl_id(HMGL gr, int x, int y); int MGL_EXPORT_PURE mgl_get_spl_id_(uintptr_t *gr, int *x, int *y); /// Get width of the image int MGL_EXPORT mgl_get_width(HMGL gr); int MGL_EXPORT mgl_get_width_(uintptr_t *gr); /// Get height of the image int MGL_EXPORT mgl_get_height(HMGL gr); int MGL_EXPORT mgl_get_height_(uintptr_t *gr); /// Calculate 3D coordinate {x,y,z} for screen point {xs,ys} void MGL_EXPORT mgl_calc_xyz(HMGL gr, int xs, int ys, mreal *x, mreal *y, mreal *z); void MGL_EXPORT mgl_calc_xyz_(uintptr_t *gr, int *xs, int *ys, mreal *x, mreal *y, mreal *z); /// Calculate screen point {xs,ys} for 3D coordinate {x,y,z} void MGL_EXPORT mgl_calc_scr(HMGL gr, double x, double y, double z, int *xs, int *ys); void MGL_EXPORT mgl_calc_scr_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, int *xs, int *ys); /// Check if {xs,ys} is close to active point with accuracy d, and return its position or -1 long MGL_EXPORT_PURE mgl_is_active(HMGL gr, int xs, int ys, int d); long MGL_EXPORT_PURE mgl_is_active_(uintptr_t *gr, int *xs, int *ys, int *d); /// Create new frame. int MGL_EXPORT mgl_new_frame(HMGL gr); int MGL_EXPORT mgl_new_frame_(uintptr_t *gr); /// Finish frame drawing void MGL_EXPORT mgl_end_frame(HMGL gr); void MGL_EXPORT mgl_end_frame_(uintptr_t *gr); /// Get the number of created frames int MGL_EXPORT_PURE mgl_get_num_frame(HMGL gr); int MGL_EXPORT_PURE mgl_get_num_frame_(uintptr_t *gr); /// Reset frames counter (start it from zero) void MGL_EXPORT mgl_reset_frames(HMGL gr); void MGL_EXPORT mgl_reset_frames_(uintptr_t *gr); /// Get drawing data for i-th frame (work if MGL_VECT_FRAME is set on) void MGL_EXPORT mgl_get_frame(HMGL gr, int i); void MGL_EXPORT mgl_get_frame_(uintptr_t *gr, int *i); /// Set drawing data for i-th frame (work if MGL_VECT_FRAME is set on) void MGL_EXPORT mgl_set_frame(HMGL gr, int i); void MGL_EXPORT mgl_set_frame_(uintptr_t *gr, int *i); /// Append drawing data from i-th frame (work if MGL_VECT_FRAME is set on) void MGL_EXPORT mgl_show_frame(HMGL gr, int i); void MGL_EXPORT mgl_show_frame_(uintptr_t *gr, int *i); /// Delete primitives for i-th frame (work if MGL_VECT_FRAME is set on) void MGL_EXPORT mgl_del_frame(HMGL gr, int i); void MGL_EXPORT mgl_del_frame_(uintptr_t *gr, int *i); /// Clear list of primitives for current drawing void MGL_EXPORT mgl_clear_frame(HMGL gr); void MGL_EXPORT mgl_clear_frame_(uintptr_t *gr); /// Set the transparency type (0 - usual, 1 - glass, 2 - lamp) void MGL_EXPORT mgl_set_transp_type(HMGL gr, int kind); void MGL_EXPORT mgl_set_transp_type_(uintptr_t *gr, int *kind); /// Set the transparency on/off. void MGL_EXPORT mgl_set_alpha(HMGL gr, int enable); void MGL_EXPORT mgl_set_alpha_(uintptr_t *gr, int *enable); /// Set the gray-scale mode on/off. void MGL_EXPORT mgl_set_gray(HMGL gr, int enable); void MGL_EXPORT mgl_set_gray_(uintptr_t *gr, int *enable); /// Set the fog distance or switch it off (if d=0). void MGL_EXPORT mgl_set_fog(HMGL gr, double d, double dz); void MGL_EXPORT mgl_set_fog_(uintptr_t *gr, mreal *dist, mreal *dz); /// Set the using of light on/off. void MGL_EXPORT mgl_set_light(HMGL gr, int enable); void MGL_EXPORT mgl_set_light_(uintptr_t *gr, int *enable); /// Switch on/off the specified light source. void MGL_EXPORT mgl_set_light_n(HMGL gr, int n, int enable); void MGL_EXPORT mgl_set_light_n_(uintptr_t *gr, int *n, int *enable); /// Set to attach light settings to inplot. void MGL_EXPORT mgl_set_attach_light(HMGL gr, int enable); void MGL_EXPORT mgl_set_attach_light_(uintptr_t *gr, int *enable); /// Add white light source at infinity. void MGL_EXPORT mgl_add_light(HMGL gr, int n, double x, double y, double z); void MGL_EXPORT mgl_add_light_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z); /// Add light source at infinity (more settings). void MGL_EXPORT mgl_add_light_ext(HMGL gr, int n, double x, double y, double z, char c, double br, double ap); void MGL_EXPORT mgl_add_light_ext_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z, char *c, mreal *br, mreal *ap, int); /// Add local light source. void MGL_EXPORT mgl_add_light_loc(HMGL gr, int n, double x, double y, double z, double dx, double dy, double dz, char c, double br, double ap); void MGL_EXPORT mgl_add_light_loc_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z, mreal *dx, mreal *dy, mreal *dz, char *c, mreal *br, mreal *ap, int); /// Pop transformation matrix from stack void MGL_EXPORT mgl_mat_pop(HMGL gr); void MGL_EXPORT mgl_mat_pop_(uintptr_t *gr); /// Push transformation matrix into stack void MGL_EXPORT mgl_mat_push(HMGL gr); void MGL_EXPORT mgl_mat_push_(uintptr_t *gr); /// Clear up the frame void MGL_EXPORT mgl_clf(HMGL gr); void MGL_EXPORT mgl_clf_(uintptr_t *gr); /// Clear up the frame but keep fog settings void MGL_EXPORT mgl_clf_nfog(HMGL gr); void MGL_EXPORT mgl_clf_nfog_(uintptr_t *gr); /// Clear up the frame and fill background by specified color void MGL_EXPORT mgl_clf_rgb(HMGL gr, double r, double g, double b); void MGL_EXPORT mgl_clf_rgb_(uintptr_t *gr, mreal *r, mreal *g, mreal *b); /// Clear up the frame and fill background by specified color void MGL_EXPORT mgl_clf_chr(HMGL gr, char col); void MGL_EXPORT mgl_clf_chr_(uintptr_t *gr, const char *col, int); /// Clear up the frame and fill background by specified color with manual transparency void MGL_EXPORT mgl_clf_str(HMGL gr, const char *col); void MGL_EXPORT mgl_clf_str_(uintptr_t *gr, const char *col, int); /// Load background image void MGL_EXPORT mgl_load_background(HMGL gr, const char *fname, double alpha); void MGL_EXPORT mgl_load_background_(uintptr_t *gr, const char *fname, mreal *alpha, int); /// Put further plotting in m-th cell of nx*ny grid of the image. /** String \a style may contain: * '<' for reserving space at left * '>' for reserving space at right * '^' for reserving space at top * '_' for reserving space at bottom * '#' for using whole region. */ void MGL_EXPORT mgl_subplot(HMGL gr, int nx,int ny,int m,const char *style); void MGL_EXPORT mgl_subplot_(uintptr_t *gr, int *nx,int *ny,int *m, const char *s,int); /// Put further plotting in m-th cell of nx*ny grid of the image and shift it by distance {dx,dy}. /** String \a style may contain: * '<' for reserving space at left * '>' for reserving space at right * '^' for reserving space at top * '_' for reserving space at bottom * '#' for using whole region. */ void MGL_EXPORT mgl_subplot_d(HMGL gr, int nx,int ny,int m,const char *style, double dx, double dy); void MGL_EXPORT mgl_subplot_d_(uintptr_t *gr, int *nx,int *ny,int *m,const char *style, mreal *dx, mreal *dy,int l); /// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image. /** String \a style may contain: * '<' for reserving space at left * '>' for reserving space at right * '^' for reserving space at top * '_' for reserving space at bottom * '#' for using whole region. */ void MGL_EXPORT mgl_multiplot(HMGL gr, int nx,int ny,int m,int dx,int dy,const char *style); void MGL_EXPORT mgl_multiplot_(uintptr_t *gr, int *nx,int *ny,int *m,int *dx,int *dy, const char *s,int); /// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image and shift it by distance {sx,sy}.. /** String \a style may contain: * '<' for reserving space at left * '>' for reserving space at right * '^' for reserving space at top * '_' for reserving space at bottom * '#' for using whole region. */ void MGL_EXPORT mgl_multiplot_d(HMGL gr, int nx,int ny,int m,int dx,int dy,const char *style,double sx,double sy); void MGL_EXPORT mgl_multiplot_d_(uintptr_t *gr, int *nx,int *ny,int *m,int *dx,int *dy, const char *s, mreal *sx, mreal *sy,int); /// Put further plotting in a region [x1,x2]*[y1,y2] of the image (x1,x2,y1,y2 in range [0, 1]). void MGL_EXPORT mgl_inplot(HMGL gr, double x1,double x2,double y1,double y2); void MGL_EXPORT mgl_inplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2); /// Put further plotting in a region [x1,x2]*[y1,y2] of the subplot (x1,x2,y1,y2 in range [0, 1]). void MGL_EXPORT mgl_relplot(HMGL gr, double x1,double x2,double y1,double y2); void MGL_EXPORT mgl_relplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2); /// Put further plotting in column cell of previous subplot/inplot. void MGL_EXPORT mgl_columnplot(HMGL gr, int num, int ind, double d); void MGL_EXPORT mgl_columnplot_(uintptr_t *gr, int *num, int *i, mreal *d); /// Put further plotting in matrix cell of previous subplot/inplot. void MGL_EXPORT mgl_gridplot(HMGL gr, int nx, int ny, int m, double d); void MGL_EXPORT mgl_gridplot_(uintptr_t *gr, int *nx, int *ny, int *m, mreal *d); /// Put further plotting in cell of stick rotated on angles tet, phi. void MGL_EXPORT mgl_stickplot(HMGL gr, int num, int ind, double tet, double phi); void MGL_EXPORT mgl_stickplot_(uintptr_t *gr, int *num, int *i, mreal *tet, mreal *phi); /// Put further plotting in cell of stick sheared on sx, sy. void MGL_EXPORT mgl_shearplot(HMGL gr, int num, int ind, double sx, double sy, double xd, double yd); void MGL_EXPORT mgl_shearplot_(uintptr_t *gr, int *num, int *i, mreal *sy, mreal *sx, mreal *xd, mreal *yd); /// Add title for current subplot/inplot. /** Style '#' draw box around the title. */ void MGL_EXPORT mgl_title(HMGL gr, const char *title, const char *stl, double size); void MGL_EXPORT mgl_title_(uintptr_t *gr, const char *title, const char *stl, mreal *size, int,int); void MGL_EXPORT mgl_titlew(HMGL gr, const wchar_t *title, const char *stl, double size); /// Set factor of plot size void MGL_EXPORT mgl_set_plotfactor(HMGL gr, double val); void MGL_EXPORT mgl_set_plotfactor_(uintptr_t *gr, mreal *val); /// Set aspect ratio for further plotting. void MGL_EXPORT mgl_aspect(HMGL gr, double Ax,double Ay,double Az); void MGL_EXPORT mgl_aspect_(uintptr_t *gr, mreal *Ax, mreal *Ay, mreal *Az); /// Set aspect ratio for further plotting. void MGL_EXPORT mgl_shear(HMGL gr, double Sx,double Sz); void MGL_EXPORT mgl_shear_(uintptr_t *gr, mreal *Sx, mreal *Sy); /// Rotate a further plotting. void MGL_EXPORT mgl_rotate(HMGL gr, double TetX,double TetZ,double TetY); void MGL_EXPORT mgl_rotate_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY); /// Rotate a further plotting around vector {x,y,z}. void MGL_EXPORT mgl_rotate_vector(HMGL gr, double Tet,double x,double y,double z); void MGL_EXPORT mgl_rotate_vector_(uintptr_t *gr, mreal *Tet, mreal *x, mreal *y, mreal *z); /// Set perspective (in range [0,1)) for plot. Set to zero for switching off. void MGL_EXPORT mgl_perspective(HMGL gr, double val); void MGL_EXPORT mgl_perspective_(uintptr_t *gr, mreal *val); /// Ask to set perspective (in range [0,1)) for plot. Set to zero for switching off. void MGL_EXPORT mgl_ask_perspective(HMGL gr, double val); void MGL_EXPORT mgl_ask_perspective_(uintptr_t *gr, mreal *val); /// Set angle of view independently from Rotate(). void MGL_EXPORT mgl_view(HMGL gr, double TetX,double TetZ,double TetY); void MGL_EXPORT mgl_view_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY); /// Zoom in/out a part of picture (use mgl_zoom(0, 0, 1, 1) for restore default) void MGL_EXPORT mgl_zoom(HMGL gr, double x1, double y1, double x2, double y2); void MGL_EXPORT mgl_zoom_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *x2, mreal *y2); //----------------------------------------------------------------------------- /// Create HMPR object for parsing MGL scripts HMPR MGL_EXPORT mgl_create_parser(); uintptr_t MGL_EXPORT mgl_create_parser_(); /// Change counter of HMPR uses (for advanced users only). Non-zero counter prevent automatic object removing. long MGL_EXPORT mgl_use_parser(HMPR p, int inc); long MGL_EXPORT mgl_use_parser_(uintptr_t* , int *inc); /// Delete HMPR object void MGL_EXPORT mgl_delete_parser(HMPR p); void MGL_EXPORT mgl_delete_parser_(uintptr_t* p); /// Set value for parameter $N void MGL_EXPORT mgl_parser_add_param(HMPR p, int id, const char *str); void MGL_EXPORT mgl_parser_add_param_(uintptr_t* p, int *id, const char *str, int); void MGL_EXPORT mgl_parser_add_paramw(HMPR p, int id, const wchar_t *str); /// Find variable with given name or add a new one /// NOTE !!! You must not delete obtained data arrays !!! MGL_EXPORT mglDataA *mgl_parser_add_var(HMPR p, const char *name); uintptr_t MGL_EXPORT mgl_parser_add_var_(uintptr_t* p, const char *name, int); MGL_EXPORT mglDataA *mgl_parser_add_varw(HMPR p, const wchar_t *name); /// Find variable with given name or return NULL if no one /// NOTE !!! You must not delete obtained data arrays !!! MGL_EXPORT_PURE mglDataA *mgl_parser_find_var(HMPR p, const char *name); uintptr_t MGL_EXPORT mgl_parser_find_var_(uintptr_t* p, const char *name, int); MGL_EXPORT_PURE mglDataA *mgl_parser_find_varw(HMPR p, const wchar_t *name); /// Get variable with given id /// NOTE !!! You must not delete obtained data arrays !!! MGL_EXPORT_PURE mglDataA *mgl_parser_get_var(HMPR p, unsigned long id); uintptr_t MGL_EXPORT_PURE mgl_parser_get_var_(uintptr_t* p, unsigned long *id); /// Get number of variables long MGL_EXPORT_PURE mgl_parser_num_var(HMPR p); long MGL_EXPORT_PURE mgl_parser_num_var_(uintptr_t* p); /// Get constant with given id /// NOTE !!! You must not delete obtained data arrays !!! MGL_EXPORT_PURE mglNum *mgl_parser_get_const(HMPR p, unsigned long id); uintptr_t MGL_EXPORT_PURE mgl_parser_get_const_(uintptr_t* p, unsigned long *id); /// Get number of constants long MGL_EXPORT_PURE mgl_parser_num_const(HMPR p); long MGL_EXPORT_PURE mgl_parser_num_const_(uintptr_t* p); /// Delete variable with name void MGL_EXPORT mgl_parser_del_var(HMPR p, const char *name); void MGL_EXPORT mgl_parser_del_var_(uintptr_t* p, const char *name, int); void MGL_EXPORT mgl_parser_del_varw(HMPR p, const wchar_t *name); /// Delete all data variables void MGL_EXPORT mgl_parser_del_all(HMPR p); void MGL_EXPORT mgl_parser_del_all_(uintptr_t *p); /// Load new commands from external dynamic Library (must have "const mglCommand *mgl_cmd_extra" variable) void MGL_EXPORT mgl_parser_load(HMPR pr, const char *dll_name); void MGL_EXPORT mgl_parser_load_(uintptr_t *pr, const char *dll_name,int); /// Apply one step for equation d vars[i]/dt = eqs[i] using Runge-Kutta method void MGL_EXPORT mgl_rk_step(HMPR pr, const char *eqs, const char *vars, mreal dt); void MGL_EXPORT mgl_rk_step_w(HMPR pr, const wchar_t *eqs, const wchar_t *vars, mreal dt); void MGL_EXPORT mgl_rk_step_(uintptr_t *p, const char *eqs, const char *vars, double *dt, int,int); // Open all data arrays from HDF file and assign it as variables of parser p void MGL_EXPORT mgl_parser_openhdf(HMPR p, const char *fname); void MGL_EXPORT mgl_parser_openhdf_(uintptr_t *p, const char *fname,int l); /// Parse and draw single line of the MGL script int MGL_EXPORT mgl_parse_line(HMGL gr, HMPR p, const char *str, int pos); int MGL_EXPORT mgl_parse_line_(uintptr_t* gr, uintptr_t* p, const char *str, int *pos, int); int MGL_EXPORT mgl_parse_linew(HMGL gr, HMPR p, const wchar_t *str, int pos); /// Execute and draw script from the file void MGL_EXPORT mgl_parse_file(HMGL gr, HMPR p, FILE *fp, int print); /// Execute MGL script text with '\n' separated lines void MGL_EXPORT mgl_parse_text(HMGL gr, HMPR p, const char *str); void MGL_EXPORT mgl_parse_text_(uintptr_t* gr, uintptr_t* p, const char *str, int); void MGL_EXPORT mgl_parse_textw(HMGL gr, HMPR p, const wchar_t *str); /// Restore once flag void MGL_EXPORT mgl_parser_restore_once(HMPR p); void MGL_EXPORT mgl_parser_restore_once_(uintptr_t* p); /// Allow changing size of the picture void MGL_EXPORT mgl_parser_allow_setsize(HMPR p, int a); void MGL_EXPORT mgl_parser_allow_setsize_(uintptr_t* p, int *a); /// Allow reading/saving files void MGL_EXPORT mgl_parser_allow_file_io(HMPR p, int a); void MGL_EXPORT mgl_parser_allow_file_io_(uintptr_t* p, int *a); /// Allow loading commands from external libraries void MGL_EXPORT mgl_parser_allow_dll_call(HMPR p, int a); void MGL_EXPORT mgl_parser_allow_dll_call_(uintptr_t* p, int *a); /// Set flag to stop script parsing void MGL_EXPORT mgl_parser_stop(HMPR p); void MGL_EXPORT mgl_parser_stop_(uintptr_t* p); /// Set variant of argument(s) separated by '?' to be used void MGL_EXPORT mgl_parser_variant(HMPR p, int var); void MGL_EXPORT mgl_parser_variant_(uintptr_t* p, int *var); /// Set starting object ID void MGL_EXPORT mgl_parser_start_id(HMPR p, int id); void MGL_EXPORT mgl_parser_start_id_(uintptr_t* p, int *id); /// Return type of command: 0 - not found, 1 - data plot, 2 - other plot, /// 3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program /// 8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot /// 13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform int MGL_EXPORT_PURE mgl_parser_cmd_type(HMPR pr, const char *name); int MGL_EXPORT_PURE mgl_parser_cmd_type_(uintptr_t* p, const char *name, int); /// Return description of MGL command MGL_EXPORT_PURE const char *mgl_parser_cmd_desc(HMPR pr, const char *name); /// Return string of command format (command name and its argument[s]) MGL_EXPORT_PURE const char *mgl_parser_cmd_frmt(HMPR pr, const char *name); /// Get name of command with number n MGL_EXPORT_PURE const char *mgl_parser_cmd_name(HMPR pr, long id); /// Get number of defined commands long MGL_EXPORT_PURE mgl_parser_cmd_num(HMPR pr); /// Return result of formula evaluation HMDT MGL_EXPORT mgl_parser_calc(HMPR pr, const char *formula); uintptr_t MGL_EXPORT mgl_parser_calc_(uintptr_t *pr, const char *formula,int); HMDT MGL_EXPORT mgl_parser_calcw(HMPR pr, const wchar_t *formula); /// Return result of formula evaluation as complex data HADT MGL_EXPORT mgl_parser_calc_complex(HMPR pr, const char *formula); uintptr_t MGL_EXPORT mgl_parser_calc_complex_(uintptr_t *pr, const char *formula,int); HADT MGL_EXPORT mgl_parser_calc_complexw(HMPR pr, const wchar_t *formula); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/mpi.h���������������������������������������������������������������������0000644�0001750�0001750�00000005261�13513030041�016373� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * mpi.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_MPI_H_ #define _MGL_MPI_H_ #include "mgl2/mgl_cf.h" #ifdef __cplusplus extern "C" { #endif /// Send graphical information to node id using MPI void MGL_EXPORT mgl_mpi_send(HMGL gr, int id); void MGL_EXPORT mgl_mpi_send_(uintptr_t *gr, int *id); /// Receive graphical information from node id using MPI void MGL_EXPORT mgl_mpi_recv(HMGL gr, int id); void MGL_EXPORT mgl_mpi_recv_(uintptr_t *gr, int *id); #ifdef __cplusplus } #include "mgl2/mgl.h" //----------------------------------------------------------------------------- /// Wrapper class for all graphics class MGL_EXPORT mglGraphMPI:public mglGraph { mglGraphMPI(const mglGraphMPI &t) {} // copying is not allowed const mglGraphMPI &operator=(const mglGraphMPI &t) { return t; } public: inline mglGraphMPI(int kind=0, int width=600, int height=400):mglGraph(kind,width,height){} inline mglGraphMPI(HMGL graph):mglGraph(graph){} virtual ~mglGraphMPI(){} /// Send graphical information to node id using MPI inline void MPI_Send(int id) { mgl_mpi_send(gr,id); } /// Receive graphical information from node id using MPI inline void MPI_Recv(int id) { mgl_mpi_recv(gr,id); } }; #endif //----------------------------------------------------------------------------- #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/pde.h���������������������������������������������������������������������0000644�0001750�0001750�00000017545�13513030041�016366� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * pde.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_PDE_H_ #define _MGL_PDE_H_ //----------------------------------------------------------------------------- #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini HADT MGL_EXPORT mgl_pde_solve_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt); uintptr_t MGL_EXPORT mgl_pde_solve_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int); /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt); uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int); /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini. This function use more accurate but slow algorithm. HADT MGL_EXPORT mgl_pde_adv_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt); uintptr_t MGL_EXPORT mgl_pde_adv_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int); /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini. This function use more accurate but slow algorithm. HMDT MGL_EXPORT mgl_pde_adv(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt); uintptr_t MGL_EXPORT mgl_pde_adv_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int); /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) HADT MGL_EXPORT mgl_qo2d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy); HADT MGL_EXPORT mgl_qo2d_func_c(mdual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy); uintptr_t MGL_EXPORT mgl_qo2d_solve_c_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int); /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy); HMDT MGL_EXPORT mgl_qo2d_func(mdual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy); uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int); /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) HADT MGL_EXPORT mgl_qo3d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz); HADT MGL_EXPORT mgl_qo3d_func_c(mdual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz); uintptr_t MGL_EXPORT mgl_qo3d_solve_c_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int); /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) HMDT MGL_EXPORT mgl_qo3d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz); HMDT MGL_EXPORT mgl_qo3d_func(mdual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz); uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int); /// Saves result of ODE solving of n equations with right part func and initial conditions x0 over time interval [0,tmax] with time step dt HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par); /// Saves result of ODE solving for var variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt HMDT MGL_EXPORT mgl_ode_solve_str(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax); /// Saves result of ODE solving for var complex variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt HADT MGL_EXPORT mgl_ode_solve_str_c(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax); /// Saves result of ODE solving of n equations with right part func and initial conditions x0 over time interval [0,tmax] with time step dt. Function bord (if not NULL) is called each time step to apply border reflection. HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par, void (*bord)(mreal *x, const mreal *xp, void *par)); /// Finds ray with starting point r0, p0 (and prepares ray data for mgl_qo2d_solve) HMDT MGL_EXPORT mgl_ray_trace(const char *ham, mreal x0, mreal y0, mreal z0, mreal px, mreal py, mreal pz, mreal dt, mreal tmax); uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int); /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du HMDT MGL_EXPORT mgl_jacobian_2d(HCDT x, HCDT y); uintptr_t MGL_EXPORT mgl_jacobian_2d_(uintptr_t* x, uintptr_t* y); /// Calculate Jacobian determinant for D{x(u,v,w), y(u,v,w), z(u,v,w)} HMDT MGL_EXPORT mgl_jacobian_3d(HCDT x, HCDT y, HCDT z); uintptr_t MGL_EXPORT mgl_jacobian_3d_(uintptr_t* x, uintptr_t* y, uintptr_t* z); #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/mgl.h���������������������������������������������������������������������0000644�0001750�0001750�00000445277�13513030041�016404� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * mgl.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_H_ #define _MGL_H_ #include "mgl2/mgl_cf.h" #ifdef __cplusplus #include "mgl2/data.h" #include "mgl2/datac.h" #include //----------------------------------------------------------------------------- /// Wrapper class for all graphics class MGL_EXPORT mglGraph { mglGraph(const mglGraph &) {} // copying is not allowed const mglGraph &operator=(const mglGraph &t) { return t; } protected: HMGL gr; public: HMPR pr; ///< Pointer to associated MGL parser mglGraph(int kind=0, int width=600, int height=400) { pr = NULL; if(kind==-1) gr=NULL; #if MGL_HAVE_OPENGL else if(kind==1) gr=mgl_create_graph_gl(); #else else if(kind==1) { gr=mgl_create_graph(width, height); SetGlobalWarn("OpenGL support was disabled. Please, enable it and rebuild MathGL."); } #endif else gr=mgl_create_graph(width, height); } mglGraph(HMGL graph) { pr = NULL; gr = graph; mgl_use_graph(gr,1); } virtual ~mglGraph() { if(mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr); } /// Get pointer to internal HMGL object inline HMGL Self() { return gr; } /// Set default parameters for plotting inline void DefaultPlotParam() { mgl_set_def_param(gr); } /// Set name of plot for saving filename inline void SetPlotId(const char *id) { mgl_set_plotid(gr,id); } /// Get name of plot for saving filename inline const char *GetPlotId() { return mgl_get_plotid(gr); } /// Ask to stop drawing inline void Stop(bool stop=true) { mgl_ask_stop(gr, stop); } /// Check if plot termination is asked inline bool NeedStop() { return mgl_need_stop(gr); } /// Set callback function for event processing inline void SetEventFunc(void (*func)(void *), void *par=NULL) { mgl_set_event_func(gr, func, par); } /// Set the transparency on/off. inline void Alpha(bool enable) { mgl_set_alpha(gr, enable); } /// Set the gray-scale mode on/off. inline void Gray(bool enable) { mgl_set_gray(gr, enable); } /// Set default value of alpha-channel inline void SetAlphaDef(double alpha) { mgl_set_alpha_default(gr, alpha); } /// Set the transparency type (0 - usual, 1 - glass, 2 - lamp) inline void SetTranspType(int type) { mgl_set_transp_type(gr, type); } /// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1. inline void SetPenDelta(double d) { mgl_pen_delta(gr,d); } /// Set the using of light on/off. inline void Light(bool enable) { mgl_set_light(gr, enable); } /// Switch on/off the specified light source. inline void Light(int n,bool enable) { mgl_set_light_n(gr, n, enable); } /// Use diffusive light (only for local light sources) -- OBSOLETE inline void SetDifLight(bool dif) { mgl_set_light_dif(gr, dif); } /// Set to attach light settings to inplot. inline void AttachLight(bool enable) { mgl_set_attach_light(gr, enable); } /// Add a light source. inline void AddLight(int n, mglPoint p, char col='w', double bright=0.5, double ap=0) { mgl_add_light_ext(gr, n, p.x, p.y, p.z, col, bright, ap); } inline void AddLight(int n, mglPoint r, mglPoint p, char col='w', double bright=0.5, double ap=0) { mgl_add_light_loc(gr, n, r.x, r.y, r.z, p.x, p.y, p.z, col, bright, ap); } /// Set ambient light brightness inline void SetAmbient(double i) { mgl_set_ambbr(gr, i); } /// Set diffusive light brightness inline void SetDiffuse(double i) { mgl_set_difbr(gr, i); } /// Set the fog distance or switch it off (if d=0). inline void Fog(double d, double dz=0.25) { mgl_set_fog(gr, d, dz); } /// Set relative width of rectangles in Bars, Barh, BoxPlot, Candle, OHLC (default is 0.7) inline void SetBarWidth(double width) { mgl_set_bar_width(gr, width); } /// Set default size of marks (locally you can use "size" option) inline void SetMarkSize(double size) { mgl_set_mark_size(gr, size); } /// Set default size of arrows (locally you can use "size" option) inline void SetArrowSize(double size) { mgl_set_arrow_size(gr, size); } /// Set number of mesh lines (use 0 to draw all of them) inline void SetMeshNum(int num) { mgl_set_meshnum(gr, num); } /// Set number of visible faces (use 0 to draw all of them) inline void SetFaceNum(int num) { mgl_set_facenum(gr, num); } /// Set cutting for points outside of bounding box inline void SetCut(bool cut) { mgl_set_cut(gr, cut); } /// Set additional cutting box inline void SetCutBox(mglPoint p1, mglPoint p2) { mgl_set_cut_box(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z); } /// Set the cutting off condition (formula) inline void CutOff(const char *EqC) { mgl_set_cutoff(gr, EqC); } /// Set default font size inline void SetFontSize(double size) { mgl_set_font_size(gr, size); } /// Set default font style and color inline void SetFontDef(const char *fnt) { mgl_set_font_def(gr, fnt); } /// Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72) virtual void SetFontSizePT(double pt, int dpi=72) { SetFontSize(pt*27.f/dpi); } /// Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt) inline void SetFontSizeCM(double cm, int dpi=72) { SetFontSizePT(cm*28.45f,dpi); } /// Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt) inline void SetFontSizeIN(double in, int dpi=72) { SetFontSizePT(in*72.27f,dpi); } /// Load font from file inline void LoadFont(const char *name, const char *path=NULL) { mgl_load_font(gr, name, path); } /// Copy font from another mglGraph instance inline void CopyFont(const mglGraph *GR) { mgl_copy_font(gr, GR->gr);} /// Restore font (load default font for new HMGL objects) inline void RestoreFont() { mgl_restore_font(gr); } /// Set to use or not text rotation inline void SetRotatedText(bool enable) { mgl_set_rotated_text(gr, enable); } /// Set to scale text in relative subplots too inline void SetScaleText(bool enable) { mgl_set_scale_text(gr, enable); } /// Set default font for all new HMGL and mglGraph objects static inline void SetDefFont(const char *name, const char *path=NULL) { mgl_def_font(name,path); } /// Add user-defined glyph for symbol and set its optional id inline void DefineSymbol(char id, const mglDataA &x, const mglDataA &y) { mgl_define_symbol(gr, id, &x, &y); } /// Set default palette inline void SetPalette(const char *colors) { mgl_set_palette(gr, colors); } /// Set default color scheme inline void SetDefScheme(const char *sch) { mgl_set_def_sch(gr, sch); } /// Sets RGB values for color with given id static inline void SetColor(char id, double r, double g, double b) { mgl_set_color(id, r, g, b); } /// Set mask for face coloring as array of type 'unsigned char[8]' static inline void SetMask(char id, const char *mask) { mgl_set_mask(id, mask); } /// Set mask for face coloring as uint64_t number static inline void SetMask(char id, uint64_t mask) { mgl_set_mask_val(id, mask); } /// Set default mask rotation angle inline void SetMaskAngle(int angle) { mgl_set_mask_angle(gr, angle); } /// Get last warning code inline int GetWarn() { return mgl_get_warn(gr);} /// Set warning code ant fill message inline void SetWarn(int code, const char *info) { mgl_set_warn(gr,code,info); } /// Get text of warning message(s) inline const char *Message() { return mgl_get_mess(gr); } /// Set global warning message static inline void SetGlobalWarn(const char *text) { mgl_set_global_warn(text); } /// Get text of global warning message(s) static inline const char *GlobalWarn() { return mgl_get_global_warn(); } /// Suppress printing warnings to stderr static inline void SuppressWarn(bool on) { mgl_suppress_warn(on); } /// Check if MathGL version is valid (return false) or not (return true) static inline bool CheckVersion(const char *ver) { return mgl_check_version(ver); } /// Display progress of something. inline void Progress(int value, int maximal) { mgl_progress(value, maximal, gr); } /// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image! inline void ZoomAxis(mglPoint p1=mglPoint(0,0,0,0), mglPoint p2=mglPoint(1,1,1,1)) { mgl_zoom_axis(gr, p1.x,p1.y,p1.z,p1.c, p2.x,p2.y,p2.z,p2.c); } /// Add [v1, v2] to the current range in direction dir inline void AddRange(char dir, double v1, double v2) { mgl_add_range_val(gr, dir, v1, v2); } /// Set range in direction dir as [v1, v2] inline void SetRange(char dir, double v1, double v2) { mgl_set_range_val(gr, dir, v1, v2); } /// Set range in direction dir as minimal and maximal values of data a inline void SetRange(char dir, const mglDataA &dat, bool add=false) { mgl_set_range_dat(gr, dir, &dat, add); } /// Set values of axis range as minimal and maximal values of corresponding data inline void SetRanges(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz, const mglDataA &cc) { mgl_set_range_dat(gr,'x',&xx,0); mgl_set_range_dat(gr,'y',&yy,0); mgl_set_range_dat(gr,'z',&zz,0); mgl_set_range_dat(gr,'c',&cc,0); } /// Set values of axis range as minimal and maximal values of corresponding data inline void SetRanges(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) { mgl_set_range_dat(gr,'x',&xx,0); mgl_set_range_dat(gr,'y',&yy,0); mgl_set_range_dat(gr,'z',&zz,0); mgl_set_range_dat(gr,'c',&zz,0); } /// Set values of axis range as minimal and maximal values of corresponding data inline void SetRanges(const mglDataA &xx, const mglDataA &yy) { mgl_set_range_dat(gr,'x',&xx,0); mgl_set_range_dat(gr,'y',&yy,0); } /// Set values of axis ranges inline void SetRanges(double x1, double x2, double y1, double y2, double z1=0, double z2=0) { mgl_set_ranges(gr, x1, x2, y1, y2, z1, z2); } /// Set values of axis ranges inline void SetRanges(mglPoint p1, mglPoint p2) { mgl_set_ranges(gr, p1.x, p2.x, p1.y, p2.y, p1.z, p2.z); } /// Set ranges for automatic variables inline void SetAutoRanges(double x1, double x2, double y1=0, double y2=0, double z1=0, double z2=0, double c1=0, double c2=0) { mgl_set_auto_ranges(gr, x1, x2, y1, y2, z1, z2, c1, c2); } /// Set ranges for automatic variables inline void SetAutoRanges(mglPoint p1, mglPoint p2) { mgl_set_auto_ranges(gr, p1.x, p2.x, p1.y, p2.y, p1.z, p2.z, p1.c, p2.c); } /// Set axis origin inline void SetOrigin(mglPoint p) { mgl_set_origin(gr, p.x, p.y, p.z); } inline void SetOrigin(double x0, double y0, double z0=mglNaN) { mgl_set_origin(gr, x0, y0, z0); } /// Set the transformation formulas for coordinate. Use "" or NULL for built-in ones inline void SetFunc(const char *EqX, const char *EqY, const char *EqZ=NULL, const char *EqA=NULL) { mgl_set_func(gr, EqX, EqY, EqZ, EqA); } /// Set one of predefined transformation rule inline void SetCoor(int how) { mgl_set_coor(gr, how); } /// Set to draw Ternary axis (triangle like axis, grid and so on) /** val=1 for Ternary axis (a+b+c=1, z=z), * val=2 for Quaternary axis (a+b+c+d=1), * val|4 for projections. */ inline void Ternary(int val) { mgl_set_ternary(gr, val); } /// Set to use or not tick labels rotation inline void SetTickRotate(bool val) { mgl_set_tick_rotate(gr,val); } /// Set to use or not tick labels skipping inline void SetTickSkip(bool val) { mgl_set_tick_skip(gr,val); } /// Set tick length inline void SetTickLen(double len, double stt=1) { mgl_set_tick_len(gr, len, stt); } /// Set axis and ticks style inline void SetAxisStl(const char *stl="k", const char *tck=0, const char *sub=0) { mgl_set_axis_stl(gr, stl, tck, sub); } /// Set time templates for ticks inline void SetTicksTime(char dir, double d=0, const char *t="") { mgl_set_ticks_time(gr,dir,d,t); } /// Set ticks text (\n separated). Use "" to disable this feature. inline void SetTicksVal(char dir, const char *lbl, bool add=false) { mgl_set_ticks_str(gr,dir,lbl,add); } inline void SetTicksVal(char dir, const wchar_t *lbl, bool add=false) { mgl_set_ticks_wcs(gr,dir,lbl,add); } /// Set ticks position and text (\n separated). Use "" to disable this feature. inline void SetTicksVal(char dir, const mglDataA &v, const char *lbl, bool add=false) { mgl_set_ticks_val(gr,dir,&v,lbl,add); } inline void SetTicksVal(char dir, const mglDataA &v, const wchar_t *lbl, bool add=false) { mgl_set_ticks_valw(gr,dir,&v,lbl,add); } /// Add manual tick at given position. Use "" to disable this feature. inline void AddTick(char dir, double val, const char *lbl) { mgl_add_tick(gr,dir,val,lbl); } inline void AddTick(char dir, double val, const wchar_t *lbl) { mgl_add_tickw(gr,dir,val,lbl); } /// Set the ticks parameters and string for its factor inline void SetTicks(char dir, double d=0, int ns=0, double org=mglNaN, const char *factor="") { mgl_set_ticks_fact(gr, dir, d, ns, org, factor); } inline void SetTicks(char dir, double d, int ns, double org, const wchar_t *factor) { mgl_set_ticks_factw(gr, dir, d, ns, org, factor); } /// Auto adjust ticks inline void Adjust(const char *dir="xyzc") { mgl_adjust_ticks(gr, dir); } /// Set templates for ticks inline void SetTickTempl(char dir, const char *t) { mgl_set_tick_templ(gr,dir,t); } inline void SetTickTempl(char dir, const wchar_t *t) { mgl_set_tick_templw(gr,dir,t); } /// Tune ticks (tune|1 for common multiplier, tune|2 for common component) inline void SetTuneTicks(int tune, double fact_pos=1.15) { mgl_tune_ticks(gr, tune, fact_pos); } /// Set additional shift of tick labels inline void SetTickShift(mglPoint p) { mgl_set_tick_shift(gr,p.x,p.y,p.z,p.c); } /// Set to use UTC time instead of local time inline void SetTimeUTC(bool enable) { mgl_set_flag(gr,enable, MGL_USE_GMTIME); } /// Set to draw tick labels at axis origin inline void SetOriginTick(bool enable=true) { mgl_set_flag(gr,!enable, MGL_NO_ORIGIN); } /// Set bit-value flag of HMGL state (for advanced users only) inline void SetFlagAdv(int val, uint32_t flag) { mgl_set_flag(gr, val, flag); } /// Put further plotting in m-th cell of nx*ny grid of the image. /** String \a style may contain: * '<' for reserving space at left * '>' for reserving space at right * '^' for reserving space at top * '_' for reserving space at bottom * '#' for using whole region. */ inline void SubPlot(int nx,int ny,int m,const char *style="<>_^", double dx=0, double dy=0) { mgl_subplot_d(gr, nx, ny, m, style, dx, dy); } /// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image and shift it by distance {sx,sy}. /** String \a style may contain: * '<' for reserving space at left * '>' for reserving space at right * '^' for reserving space at top * '_' for reserving space at bottom * '#' for using whole region. */ inline void MultiPlot(int nx,int ny,int m, int dx, int dy, const char *style="<>_^", double sx=0, double sy=0) { mgl_multiplot_d(gr, nx, ny, m, dx, dy, style, sx, sy); } /// Put further plotting in a region [x1,x2]*[y1,y2] of the image or subplot (x1,x2,y1,y2 in range [0, 1]). inline void InPlot(double x1,double x2,double y1,double y2, bool rel=true) { if(rel) mgl_relplot(gr, x1, x2, y1, y2); else mgl_inplot(gr, x1, x2, y1, y2); } /// Put further plotting in column cell of previous subplot inline void ColumnPlot(int num, int ind, double d=0) { mgl_columnplot(gr,num,ind,d); } /// Put further plotting in matrix cell of previous subplot inline void GridPlot(int nx, int ny, int ind, double d=0) { mgl_gridplot(gr,nx,ny,ind,d); } /// Put further plotting in cell of stick rotated on angles tet, phi inline void StickPlot(int num, int i, double tet, double phi) { mgl_stickplot(gr,num,i,tet,phi); } /// Put further plotting in cell of stick sheared on sx, sy. inline void ShearPlot(int num, int i, mreal sx, mreal sy, mreal xd=1, mreal yd=0) { mgl_shearplot(gr,num,i,sx,sy,xd,yd); } /// Set factor of plot size inline void SetPlotFactor(double val) { mgl_set_plotfactor(gr,val); } /// Push transformation matrix into stack inline void Push() { mgl_mat_push(gr); } /// Pop transformation matrix from stack inline void Pop() { mgl_mat_pop(gr); } /// Add title for current subplot/inplot /** Style '#' draw box around the title. */ inline void Title(const char *title,const char *stl="",double size=-2) { mgl_title(gr,title,stl,size); } /// Add title for current subplot/inplot /** Style '#' draw box around the title. */ inline void Title(const wchar_t *title,const char *stl="",double size=-2) { mgl_titlew(gr,title,stl,size); } /// Set aspect ratio for further plotting. inline void Aspect(double Ax,double Ay,double Az=1) { mgl_aspect(gr, Ax, Ay, Az); } /// Shear a further plotting. inline void Shear(double Sx,double Sy) { mgl_shear(gr, Sx, Sy); } /// Rotate a further plotting. inline void Rotate(double TetX,double TetZ=0,double TetY=0) { mgl_rotate(gr, TetX, TetZ, TetY); } /// Rotate a further plotting around vector {x,y,z}. inline void RotateN(double Tet,double x,double y,double z) { mgl_rotate_vector(gr, Tet, x, y, z); } /// Set perspective (in range [0,1)) for plot. Set to zero for switching off. inline void Perspective(double val) { mgl_perspective(gr, val); } /// Set angle of view independently from Rotate(). inline void View(double TetX,double TetZ=0,double TetY=0) { mgl_view(gr, TetX, TetZ, TetY); } /// Set angle of view independently from Rotate(). inline void ViewAsRotate(double TetZ,double TetX,double TetY=0) { mgl_view(gr, -TetX, -TetZ, -TetY); } /// Zoom in/out a part of picture (use Zoom(0, 0, 1, 1) for restore default) inline void Zoom(double x1, double y1, double x2, double y2) { mgl_zoom(gr, x1, y1, x2, y2); } /// Set size of frame in pixels. Normally this function is called internally. inline void SetSize(int width, int height, bool clf=true) { if(clf) mgl_set_size(gr, width, height); else mgl_scale_size(gr, width, height); } /// Scaling for all further set size calls. static inline void SetSizeScl(double scl) { mgl_set_size_scl(scl); } /// Set plot quality /** qual=0 -- no face drawing (fastest), * qual=1 -- no color interpolation (fast), * qual=2 -- high quality (normal), * qual|4 -- direct bitmap drawing (low memory usage); * qual|8 for dots drawing instead of primitives (extremely fast). */ inline void SetQuality(int qual=MGL_DRAW_NORM) { mgl_set_quality(gr, qual); } /// Get plot quality inline int GetQuality() { return mgl_get_quality(gr); } /// Set drawing region for Quality&4 inline void SetDrawReg(long nx=1, long ny=1, long m=0) { mgl_set_draw_reg(gr,nx,ny,m); } /// Start group of objects inline void StartGroup(const char *name) { mgl_start_group(gr, name); } /// End group of objects inline void EndGroup() { mgl_end_group(gr); } /// Highlight objects with given id inline void Highlight(int id) { mgl_highlight(gr, id); } /// Set boundary box for export graphics into 2D file formats. /** If x2<0 (y2<0) then full width (height) will be used. * If x1<0 or y1<0 or x1>=x2|Width or y1>=y2|Height then cropping will be disabled. */ inline void SetBBox(int x1=0, int y1=0, int x2=-1, int y2=-1) { mgl_set_bbox(gr,x1,y1,x2,y2); } /// Show current image inline void ShowImage(const char *viewer, bool keep=0) { mgl_show_image(gr, viewer, keep); } /// Write the frame in file (depending extension, write current frame if fname is empty) inline void WriteFrame(const char *fname=0,const char *descr="") { mgl_write_frame(gr, fname, descr); } /// Write the frame in file using JPEG format inline void WriteJPEG(const char *fname,const char *descr="") { mgl_write_jpg(gr, fname, descr); } /// Write the frame in file using PNG format with transparency inline void WritePNG(const char *fname,const char *descr="", bool alpha=true) { if(alpha) mgl_write_png(gr, fname, descr); else mgl_write_png_solid(gr, fname, descr); } /// Write the frame in file using BMP format inline void WriteBMP(const char *fname,const char *descr="") { mgl_write_bmp(gr, fname, descr); } /// Write the frame in file using BMP format inline void WriteTGA(const char *fname,const char *descr="") { mgl_write_tga(gr, fname, descr); } /// Write the frame in file using PostScript format inline void WriteEPS(const char *fname,const char *descr="") { mgl_write_eps(gr, fname, descr); } /// Write the frame in file using LaTeX format inline void WriteTEX(const char *fname,const char *descr="") { mgl_write_tex(gr, fname, descr); } /// Write the frame in file using PostScript format as bitmap inline void WriteBPS(const char *fname,const char *descr="") { mgl_write_bps(gr, fname, descr); } /// Write the frame in file using SVG format inline void WriteSVG(const char *fname,const char *descr="") { mgl_write_svg(gr, fname, descr); } /// Write the frame in file using GIF format (only for current frame!) inline void WriteGIF(const char *fname,const char *descr="") { mgl_write_gif(gr, fname, descr); } /// Write the frame in file using OBJ format inline void WriteOBJ(const char *fname,const char *descr="",bool use_png=true) { mgl_write_obj(gr, fname, descr, use_png); } /// Write the frame in file using OBJ format - Balakin way inline void WriteOBJold(const char *fname,const char *descr="",bool use_png=true) { mgl_write_obj_old(gr, fname, descr, use_png); } /// Write the frame in file using XYZ format inline void WriteXYZ(const char *fname,const char *descr="") { mgl_write_xyz(gr, fname, descr); } /// Write the frame in file using STL format (faces only) inline void WriteSTL(const char *fname,const char *descr="") { mgl_write_stl(gr, fname, descr); } /// Write the frame in file using OFF format inline void WriteOFF(const char *fname,const char *descr="", bool colored=false) { mgl_write_off(gr, fname, descr,colored); } // /// Write the frame in file using X3D format // inline void WriteX3D(const char *fname,const char *descr="") // { mgl_write_x3d(gr, fname, descr); } /// Write the frame in file using PRC format inline void WritePRC(const char *fname,const char *descr="",bool make_pdf=true) { mgl_write_prc(gr, fname, descr, make_pdf); } /// Export in JSON format suitable for later drawing by JavaScript inline void WriteJSON(const char *fname,const char *descr="",bool force_z=false) { if(force_z) mgl_write_json_z(gr, fname, descr); else mgl_write_json(gr, fname, descr); } /// Return string of JSON data suitable for later drawing by JavaScript inline const char *GetJSON() { return mgl_get_json(gr); } /// Force preparing the image. It can be useful for OpenGL mode mostly. inline void Finish() { mgl_finish(gr); } /// Create new frame. inline void NewFrame() { mgl_new_frame(gr); } /// Finish frame drawing inline void EndFrame() { mgl_end_frame(gr); } /// Get the number of created frames inline int GetNumFrame() { return mgl_get_num_frame(gr); } /// Reset frames counter (start it from zero) inline void ResetFrames() { mgl_reset_frames(gr); } /// Delete primitives for i-th frame (work if MGL_VECT_FRAME is set on) inline void DelFrame(int i) { mgl_del_frame(gr, i); } /// Get drawing data for i-th frame (work if MGL_VECT_FRAME is set on) inline void GetFrame(int i) { mgl_get_frame(gr, i); } /// Set drawing data for i-th frame (work if MGL_VECT_FRAME is set on). Work as EndFrame() but don't add frame to GIF image. inline void SetFrame(int i) { mgl_set_frame(gr, i); } /// Append drawing data from i-th frame (work if MGL_VECT_FRAME is set on) inline void ShowFrame(int i){ mgl_show_frame(gr, i); } /// Clear list of primitives for current drawing inline void ClearFrame() { mgl_clear_frame(gr); } /// Start write frames to cinema using GIF format inline void StartGIF(const char *fname, int ms=100) { mgl_start_gif(gr, fname,ms); } /// Stop writing cinema using GIF format inline void CloseGIF() { mgl_close_gif(gr); } /// Export points and primitives in file using MGLD format inline void ExportMGLD(const char *fname, const char *descr=0) { mgl_export_mgld(gr, fname, descr); } /// Import points and primitives from file using MGLD format inline void ImportMGLD(const char *fname, bool add=false) { mgl_import_mgld(gr, fname, add); } /// Copy RGB values into array which is allocated by user /** Position of element {i,j} is [3*i + 3*Width*j]. */ inline bool GetRGB(char *imgdata, int imglen) { long w=mgl_get_width(gr), h=mgl_get_height(gr); if(imglen>=3*w*h) memcpy(imgdata, mgl_get_rgb(gr),3*w*h); return imglen>=3*w*h; } /// Get RGB values of current bitmap /** Position of element {i,j} is [3*i + 3*Width*j]. */ inline const unsigned char *GetRGB() { return mgl_get_rgb(gr); } /// Copy RGBA values into array which is allocated by user /** Position of element {i,j} is [4*i + 4*Width*j]. */ inline bool GetRGBA(char *imgdata, int imglen) { long w=mgl_get_width(gr), h=mgl_get_height(gr); if(imglen>=4*w*h) memcpy(imgdata, mgl_get_rgba(gr),4*w*h); return imglen>=4*w*h; } /// Get RGBA values of current bitmap /** Position of element {i,j} is [4*i + 4*Width*j]. */ inline const unsigned char *GetRGBA() { return mgl_get_rgba(gr); } /// Copy BGRN values into array which is allocated by user inline bool GetBGRN(unsigned char *imgdata, int imglen) { long w=mgl_get_width(gr), h=mgl_get_height(gr), i; const unsigned char *buf=mgl_get_rgb(gr); if(imglen>=4*w*h) for(i=0;i=4*w*h; } /// Copy RGBA values of background image into array which is allocated by user /** Position of element {i,j} is [4*i + 4*Width*j]. */ inline bool GetBackground(char *imgdata, int imglen) { long w=mgl_get_width(gr), h=mgl_get_height(gr); if(imglen>=4*w*h) memcpy(imgdata, mgl_get_background(gr),4*w*h); return imglen>=4*w*h; } /// Get RGBA values of background image /** Position of element {i,j} is [4*i + 4*Width*j]. */ inline const unsigned char *GetBackground() { return mgl_get_background(gr); } /// Get width of the image inline int GetWidth() { return mgl_get_width(gr); } /// Get height of the image inline int GetHeight() { return mgl_get_height(gr);} /// Calculate 3D coordinate {x,y,z} for screen point {xs,ys} inline mglPoint CalcXYZ(int xs, int ys) { mreal x,y,z; mgl_calc_xyz(gr,xs,ys,&x,&y,&z); return mglPoint(x,y,z); } /// Calculate screen point {xs,ys} for 3D coordinate {x,y,z} inline mglPoint CalcScr(mglPoint p) { int xs,ys; mgl_calc_scr(gr,p.x,p.y,p.z,&xs,&ys); return mglPoint(xs,ys); } /// Set object/subplot id inline void SetObjId(int id) { mgl_set_obj_id(gr,id); } /// Get object id inline int GetObjId(long x,long y) { return mgl_get_obj_id(gr,x,y); } /// Get subplot id inline int GetSplId(long x,long y) { return mgl_get_spl_id(gr,x,y); } /// Check if {\a xs,\a ys} is close to active point with accuracy d, and return its position or -1 inline long IsActive(int xs, int ys, int d=1) { return mgl_is_active(gr,xs,ys,d); } /// Combine plots from 2 canvases. Result will be saved into this inline void Combine(const mglGraph *g) { mgl_combine_gr(gr,g->gr); } /// Clear up the frame and fill background by specified color inline void Clf(double r, double g, double b) { mgl_clf_rgb(gr, r, g, b); } /// Clear up the frame and fill background by specified color with manual transparency inline void Clf(const char *col) { mgl_clf_str(gr, col); } /// Clear up the frame and fill background by specified color inline void Clf(char col) { mgl_clf_chr(gr, col); } /// Clear up the frame inline void Clf() { mgl_clf(gr); } /// Clear unused points and primitives. Useful only in combination with SetFaceNum(). inline void ClearUnused() { mgl_clear_unused(gr); } /// Load background image inline void LoadBackground(const char *fname, double alpha=1) { mgl_load_background(gr,fname,alpha); } /// Force drawing the image and use it as background one inline void Rasterize() { mgl_rasterize(gr); } /// Draws the point (ball) at position {x,y,z} with color c inline void Ball(mglPoint p, char c='r') { char s[3]={'.',c,0}; mgl_mark(gr, p.x, p.y, p.z, s); } /// Draws the mark at position p inline void Mark(mglPoint p, const char *mark) { mgl_mark(gr, p.x, p.y, p.z, mark); } /// Draws the line between points by specified pen /** Large \a n (for example, n=100) should be used for geodesic line in curved coordinates */ inline void Line(mglPoint p1, mglPoint p2, const char *pen="B",int n=2) { mgl_line(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, pen, n); } /// Draws the spline curve between points by specified pen inline void Curve(mglPoint p1, mglPoint d1, mglPoint p2, mglPoint d2, const char *pen="B", int n=100) { mgl_curve(gr, p1.x, p1.y, p1.z, d1.x, d1.y, d1.z, p2.x, p2.y, p2.z, d2.x, d2.y, d2.z, pen, n); } /// Draws the 3d error box e for point p inline void Error(mglPoint p, mglPoint e, const char *pen="k") { mgl_error_box(gr, p.x, p.y, p.z, e.x, e.y, e.z, pen); } /// Draws Lamerey diagram for mapping x_new = f(x_old) /** String \a stl may contain: ‘v’ for drawing arrows; ‘~’ for disable 1st segment. * Option value set the number of segments (default is 20).*/ inline void Lamerey(double x0, const mglDataA &f, const char *stl="", const char *opt="") { mgl_lamerey_dat(gr,x0,&f,stl,opt); } inline void Lamerey(double x0, const char *func, const char *stl="", const char *opt="") { mgl_lamerey_str(gr,x0,func,stl,opt); } /// Draws Bifurcation diagram for mapping x_new = f(x_old) in x-axis range /** Option value set the number of stationary points (default is 1024).*/ inline void Bifurcation(double dx, const mglDataA &f, const char *stl="", const char *opt="") { mgl_bifurcation_dat(gr,dx,&f,stl,opt); } inline void Bifurcation(double dx, const char *func, const char *stl="", const char *opt="") { mgl_bifurcation_str(gr,dx,func,stl,opt); } /// Draws Iris plots for determining cross-dependences of data arrays /** NOTE: using the same ranges and empty ids will not draw axis. This will add data to existing Iris plot. * Option value set the size of data labels ids, separated by ';'.*/ inline void Iris(mglDataA &dats, const char *ids, const char *stl="", const char *opt="") { mgl_iris_1(gr,&dats,ids,stl,opt); } inline void Iris(mglDataA &dats, const wchar_t *ids, const char *stl="", const char *opt="") { mgl_irisw_1(gr,&dats,ids,stl,opt); } inline void Iris(mglDataA &dats, mglDataA &ranges, const char *ids, const char *stl="", const char *opt="") { mgl_iris(gr,&dats,&ranges,ids,stl,opt); } inline void Iris(mglDataA &dats, mglDataA &ranges, const wchar_t *ids, const char *stl="", const char *opt="") { mgl_irisw(gr,&dats,&ranges,ids,stl,opt); } /// Draws the face between points with color stl (include interpolation up to 4 colors). inline void Face(mglPoint p1, mglPoint p2, mglPoint p3, mglPoint p4, const char *stl="r") { mgl_face(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, stl); } /// Draws the face in y-z plane at point p with color stl (include interpolation up to 4 colors). inline void FaceX(mglPoint p, double wy, double wz, const char *stl="w", double dx=0, double dy=0) { mgl_facex(gr, p.x, p.y, p.z, wy, wz, stl, dx, dy); } /// Draws the face in x-z plane at point p with color stl (include interpolation up to 4 colors). inline void FaceY(mglPoint p, double wx, double wz, const char *stl="w", double dx=0, double dy=0) { mgl_facey(gr, p.x, p.y, p.z, wx, wz, stl, dx, dy); } /// Draws the face in x-y plane at point p with color stl (include interpolation up to 4 colors). inline void FaceZ(mglPoint p, double wx, double wy, const char *stl="w", double dx=0, double dy=0) { mgl_facez(gr, p.x, p.y, p.z, wx, wy, stl, dx, dy); } /// Draws the drop at point p in direction d with color col and radius r /** Parameter \a shift set the degree of drop oblongness: ‘0’ is sphere, ‘1’ is maximally oblongness drop. Parameter \a ap set relative width of the drop (this is analogue of “ellipticity” for the sphere).*/ inline void Drop(mglPoint p, mglPoint d, double r, const char *col="r", double shift=1, double ap=1) { mgl_drop(gr, p.x, p.y, p.z, d.x, d.y, d.z, r, col, shift, ap); } /// Draws the sphere at point p with color col and radius r inline void Sphere(mglPoint p, double r, const char *col="r") { mgl_sphere(gr, p.x, p.y, p.z, r, col); } /// Draws the cone between points p1,p2 with radius r1,r2 and with style stl /** Parameter \a stl can contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinder instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones.*/ inline void Cone(mglPoint p1, mglPoint p2, double r1, double r2=-1, const char *stl="r@") { mgl_cone(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z,r1,r2,stl); } /// Draws the ellipse between points p1,p2 with color stl and width r /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ inline void Ellipse(mglPoint p1, mglPoint p2, double r, const char *stl="r") { mgl_ellipse(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl); } /// Draws the circle at point p with color stl and radius r /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ inline void Circle(mglPoint p, double r, const char *stl="r") { mgl_ellipse(gr, p.x, p.y, p.z, p.x, p.y, p.z, r,stl); } /// Draws the rhomb between points p1,p2 with color stl and width r /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ inline void Rhomb(mglPoint p1, mglPoint p2, double r, const char *stl="r") { mgl_rhomb(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl); } /// Draws the polygon based on points p1,p2 with color stl /** Parameter \a stl can contain: * ‘#’ for wired figure (boundary only); * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/ inline void Polygon(mglPoint p1, mglPoint p2, int n, const char *stl="r") { mgl_polygon(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, n,stl); } /// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees) inline void Arc(mglPoint p0, mglPoint pa, mglPoint p1, double a, const char *stl="r") { mgl_arc_ext(gr, p0.x,p0.y,p0.z, pa.x,pa.y,pa.z, p1.x,p1.y,p1.z, a,stl); } /// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees) inline void Arc(mglPoint p0, mglPoint p1, double a, const char *stl="r") { mgl_arc_ext(gr, p0.x,p0.y,p0.z, 0,0,1, p1.x,p1.y,p0.z, a,stl); } /// Draws bitmap (logo) which is stretched along whole axis range inline void Logo(long w, long h, const unsigned char *rgba, bool smooth=false, const char *opt="") { mgl_logo(gr, w, h, rgba, smooth, opt); } inline void Logo(const char *fname, bool smooth=false, const char *opt="") { mgl_logo_file(gr, fname, smooth, opt); } /// Draw user-defined symbol in position p inline void Symbol(mglPoint p, char id, const char *how="", double size=-1) { mgl_symbol(gr, p.x, p.y, p.z, id, how, size); } /// Draw user-defined symbol in position p along direction d inline void Symbol(mglPoint p, mglPoint d, char id, const char *how="", double size=-1) { mgl_symbol_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, id, how, size); } /// Print text in position p with specified font inline void Putsw(mglPoint p,const wchar_t *text,const char *font=":C",double size=-1) { mgl_putsw(gr, p.x, p.y, p.z, text, font, size); } /// Print text in position p with specified font inline void Puts(mglPoint p,const char *text,const char *font=":C",double size=-1) { mgl_puts(gr, p.x, p.y, p.z, text, font, size); } /// Print text in position p with specified font inline void Putsw(double x, double y,const wchar_t *text,const char *font=":AC",double size=-1) { mgl_putsw(gr, x, y, 0, text, font, size); } /// Print text in position p with specified font inline void Puts(double x, double y,const char *text,const char *font=":AC",double size=-1) { mgl_puts(gr, x, y, 0, text, font, size); } /// Print text in position p along direction d with specified font inline void Putsw(mglPoint p, mglPoint d, const wchar_t *text, const char *font=":L", double size=-1) { mgl_putsw_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, text, font, size); } /// Print text in position p along direction d with specified font inline void Puts(mglPoint p, mglPoint d, const char *text, const char *font=":L", double size=-1) { mgl_puts_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, text, font, size); } /// Print text along the curve inline void Text(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *text, const char *font="", const char *opt="") { mgl_text_xyz(gr, &x, &y, &z, text, font, opt); } /// Print text along the curve inline void Text(const mglDataA &x, const mglDataA &y, const char *text, const char *font="", const char *opt="") { mgl_text_xy(gr, &x, &y, text, font, opt); } /// Print text along the curve inline void Text(const mglDataA &y, const char *text, const char *font="", const char *opt="") { mgl_text_y(gr, &y, text, font, opt); } /// Print text along the curve inline void Text(const mglDataA &x, const mglDataA &y, const mglDataA &z, const wchar_t *text, const char *font="", const char *opt="") { mgl_textw_xyz(gr, &x, &y, &z, text, font, opt); } /// Print text along the curve inline void Text(const mglDataA &x, const mglDataA &y, const wchar_t *text, const char *font="", const char *opt="") { mgl_textw_xy(gr, &x, &y, text, font, opt); } /// Print text along the curve inline void Text(const mglDataA &y, const wchar_t *text, const char *font="", const char *opt="") { mgl_textw_y(gr, &y, text, font, opt); } /// Draws bounding box outside the plotting volume with color c. /** Style ‘@’ produce filled back faces. */ inline void Box(const char *col="", bool ticks=true) { mgl_box_str(gr, col, ticks); } /// Draw axises with ticks in direction(s) dir. /** Parameter \a dir may contain: * ‘xyzt’for drawing axis in corresponding direction; * ‘XYZT’ for drawing axis in corresponding direction but with inverted positions of labels; * ‘~’, ‘_’ for disabling tick labels; * ‘U’ for disabling rotation of tick labels; * ‘^’ for inverting default axis origin; * ‘!’ for disabling ticks tuning; * ‘AKDTVISO’ for drawing arrow at the end of axis; * ‘a’ for forced adjusting of axis ticks; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels. * Option "value" set the manual rotation angle for the ticks. */ inline void Axis(const char *dir="xyzt", const char *stl="", const char *opt="") { mgl_axis(gr, dir,stl,opt); } /// Draw grid lines perpendicular to direction(s) dir. inline void Grid(const char *dir="xyzt",const char *pen="B", const char *opt="") { mgl_axis_grid(gr, dir, pen, opt); } /// Print the label text for axis dir. /** Option "value" set additional shifting of the label. */ inline void Label(char dir, const char *text, double pos=+1, const char *opt="") { mgl_label(gr, dir, text, pos, opt); } /// Print the label text for axis dir. /** Option "value" set additional shifting of the label. */ inline void Label(char dir, const wchar_t *text, double pos=+1, const char *opt="") { mgl_labelw(gr, dir, text, pos, opt); } /// Draw colorbar at edge of axis /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ inline void Colorbar(const char *sch="") { mgl_colorbar(gr, sch); } /// Draw colorbar at manual position /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ inline void Colorbar(const char *sch,double x,double y,double w=1,double h=1) { mgl_colorbar_ext(gr, sch, x,y,w,h); } /// Draw colorbar with manual colors at edge of axis /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ inline void Colorbar(const mglDataA &val, const char *sch="") { mgl_colorbar_val(gr, &val, sch); } /// Draw colorbar with manual colors at manual position /** Parameter \a sch may contain: * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly; * ‘I’ for positioning near bounding (by default, at edges of subplot); * ‘A’ for using absolute coordinates; * ‘~’ for disabling tick labels. * ‘!’ for disabling ticks tuning; * ‘f’ for printing ticks labels in fixed format; * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels; * ‘F’ for printing ticks labels in LaTeX format; * ‘+’ for printing ‘+’ for positive ticks; * ‘-’ for printing usual ‘-’ in ticks labels; * ‘0123456789’ for precision at printing ticks labels.*/ inline void Colorbar(const mglDataA &val, const char *sch,double x,double y,double w=1,double h=1) { mgl_colorbar_val_ext(gr, &val, sch, x,y,w,h); } /// Add string to legend inline void AddLegend(const char *text,const char *style) { mgl_add_legend(gr, text, style); } inline void AddLegend(const wchar_t *text,const char *style) { mgl_add_legendw(gr, text, style); } /// Clear saved legend string inline void ClearLegend() { mgl_clear_legend(gr); } /// Draw legend of accumulated strings at position {x,y} /** Parameter fnt may contain: * font style for legend text; * colors for background (first one), border (second one) and text (last one); * ‘A’ for positioning in absolute coordinates; * ‘^’ for positioning outside of specified point; * ‘-’ for arranging entries horizontally; * ‘#’ for drawing box around legend. * Option value set the space between line samples and text (default is 0.1).*/ inline void Legend(double x, double y, const char *font="#", const char *opt="") { mgl_legend_pos(gr, x, y, font, opt); } /// Draw legend of accumulated strings /** Parameter fnt may contain: * font style for legend text; * colors for background (first one), border (second one) and text (last one); * ‘A’ for positioning in absolute coordinates; * ‘^’ for positioning outside of specified point; * ‘-’ for arranging entries horizontally; * ‘#’ for drawing box around legend. * Option value set the space between line samples and text (default is 0.1). * Parameter \a where sets position: 0 at bottom-left, 1 at bottom-right, 2 at top-left, 3 at top-right (default).*/ inline void Legend(int where=3, const char *font="#", const char *opt="") { mgl_legend(gr, where, font, opt); } /// Set number of marks in legend sample inline void SetLegendMarks(int num) { mgl_set_legend_marks(gr, num); } /// Draw usual curve {x,y,z} inline void Plot(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="") { mgl_plot_xyz(gr, &x, &y, &z, pen, opt); } /// Draw usual curve {x,y} inline void Plot(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_plot_xy(gr, &x, &y, pen,opt); } /// Draw usual curve {x,y} with x in x-axis range inline void Plot(const mglDataA &y, const char *pen="", const char *opt="") { mgl_plot(gr, &y, pen,opt); } /// Draw tapes which rotates as (bi-)normales of curve {x,y,z} /** The width of tape is proportional to barwidth and can be changed by option "value".*/ inline void Tape(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="") { mgl_tape_xyz(gr, &x, &y, &z, pen, opt); } /// Draw tapes which rotates as (bi-)normales of curve {x,y} /** The width of tape is proportional to barwidth and can be changed by option "value".*/ inline void Tape(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_tape_xy(gr, &x, &y, pen,opt); } /// Draw tapes which rotates as (bi-)normales of curve {x,y} with x in x-axis range /** The width of tape is proportional to barwidth and can be changed by option "value".*/ inline void Tape(const mglDataA &y, const char *pen="", const char *opt="") { mgl_tape(gr, &y, pen,opt); } /// Draw radar chart (plot in curved coordinates) /** Option "value" set the additional shift of data (i.e. the data a+value is used instead of a).*/ inline void Radar(const mglDataA &a, const char *pen="", const char *opt="") { mgl_radar(gr, &a, pen, opt); } /// Draw stairs for points in arrays {x,y,z} inline void Step(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="") { mgl_step_xyz(gr, &x, &y, &z, pen, opt); } /// Draw stairs for points in arrays {x,y} inline void Step(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_step_xy(gr, &x, &y, pen, opt); } /// Draw stairs for points in arrays {x,y} with x in x-axis range inline void Step(const mglDataA &y, const char *pen="", const char *opt="") { mgl_step(gr, &y, pen, opt); } /// Draw curve {x,y,z} which is colored by c (like tension plot) inline void Tens(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *pen="", const char *opt="") { mgl_tens_xyz(gr, &x, &y, &z, &c, pen, opt); } /// Draw curve {x,y} which is colored by c (like tension plot) inline void Tens(const mglDataA &x, const mglDataA &y, const mglDataA &c, const char *pen="", const char *opt="") { mgl_tens_xy(gr, &x, &y, &c, pen, opt); } /// Draw curve {x,y} with x in x-axis range which is colored by c (like tension plot) inline void Tens(const mglDataA &y, const mglDataA &c, const char *pen="", const char *opt="") { mgl_tens(gr, &y, &c, pen, opt); } /// Fill area between curve {x,y,z} and axis plane /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Area(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="") { mgl_area_xyz(gr, &x, &y, &z, pen, opt); } /// Fill area between curve {x,y} and axis plane /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Area(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_area_xy(gr, &x, &y, pen, opt); } /// Fill area between curve {x,y} with x in x-axis range and axis plane /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Area(const mglDataA &y, const char *pen="", const char *opt="") { mgl_area(gr, &y, pen, opt); } /// Fill area between curves {x,y1} and {x,y2} with x in x-axis range /** Style 'i' will fill area only if y1 < y2. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Region(const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="") { mgl_region(gr, &y1, &y2, pen, opt); } /// Fill area between curves {x,y1} and {x,y2} /** Style 'i' will fill area only if y1 < y2. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Region(const mglDataA &x, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="") { mgl_region_xy(gr, &x, &y1, &y2, pen, opt); } /// Fill area (draw ribbon) between curves {x1,y1,z1} and {x2,y2,z2} /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Region(const mglDataA &x1, const mglDataA &y1, const mglDataA &z1, const mglDataA &x2, const mglDataA &y2, const mglDataA &z2, const char *pen="", const char *opt="") { mgl_region_3d(gr, &x1, &y1, &z1, &x2, &y2, &z2, pen, opt); } /// Fill area (draw ribbon) between curves {x1,y1} and {x2,y2} /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Region(const mglDataA &x1, const mglDataA &y1, const mglDataA &x2, const mglDataA &y2, const char *pen="", const char *opt="") { mgl_region_3d(gr, &x1, &y1, NULL, &x2, &y2, NULL, pen, opt); } /// Draw vertical lines from points {x,y,z} to axis plane inline void Stem(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="") { mgl_stem_xyz(gr, &x, &y, &z, pen, opt); } /// Draw vertical lines from points {x,y} to axis plane inline void Stem(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_stem_xy(gr, &x, &y, pen, opt); } /// Draw vertical lines from points {x,y} with x in x-axis range to axis plane inline void Stem(const mglDataA &y, const char *pen="", const char *opt="") { mgl_stem(gr, &y, pen, opt); } /// Draw vertical bars from points {x,y,z} to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Bars(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="") { mgl_bars_xyz(gr, &x, &y, &z, pen, opt); } /// Draw vertical bars from points {x,y} to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Bars(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_bars_xy(gr, &x, &y, pen, opt); } /// Draw vertical bars from points {x,y} with x in x-axis range to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Bars(const mglDataA &y, const char *pen="", const char *opt="") { mgl_bars(gr, &y, pen, opt); } /// Draw horizontal bars from points {x,y} to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Barh(const mglDataA &y, const mglDataA &v, const char *pen="", const char *opt="") { mgl_barh_yx(gr, &y, &v, pen, opt); } /// Draw horizontal bars from points {x,y} with y in y-axis range to axis plane /** String \a pen may contain: * ‘a’ for drawing boxes one above another (like summation); * ‘f’ for waterfall chart; * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Barh(const mglDataA &v, const char *pen="", const char *opt="") { mgl_barh(gr, &v, pen, opt); } /// Draw chart for data a /** Space denote transparent color. Style '#' draw black borders. */ inline void Chart(const mglDataA &a, const char *colors="", const char *opt="") { mgl_chart(gr, &a, colors,opt); } /// Draw Open-High-Low-Close (OHLC) diagram /** Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */ inline void OHLC(const mglDataA &x, const mglDataA &open, const mglDataA &high, const mglDataA &low, const mglDataA &close, const char *pen="", const char *opt="") { mgl_ohlc_x(gr, &x, &open,&high,&low,&close,pen,opt); } /// Draw Open-High-Low-Close (OHLC) diagram with x in x-axis range /** Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */ inline void OHLC(const mglDataA &open, const mglDataA &high, const mglDataA &low, const mglDataA &close, const char *pen="", const char *opt="") { mgl_ohlc(gr, &open,&high,&low,&close,pen,opt); } /// Draw box-plot (special 5-value plot used in statistic) /** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/ inline void BoxPlot(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="") { mgl_boxplot_xy(gr, &x, &y, pen,opt); } /// Draw box-plot (special 5-value plot used in statistic) with x in x-axis range /** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/ inline void BoxPlot(const mglDataA &y, const char *pen="", const char *opt="") { mgl_boxplot(gr, &y, pen,opt); } /// Draw candle plot /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ inline void Candle(const mglDataA &x, const mglDataA &v1, const mglDataA &v2, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="") { mgl_candle_xyv(gr, &x, &v1, &v2, &y1, &y2, pen, opt); } /// Draw candle plot with x in x-axis range /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ inline void Candle(const mglDataA &v1, const mglDataA &v2, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="") { mgl_candle_yv(gr, &v1, &v2, &y1, &y2, pen, opt); } inline void Candle(const mglDataA &v1, const mglDataA &v2, const char *pen="", const char *opt="") { mgl_candle_yv(gr, &v1, &v2, NULL, NULL, pen, opt); } /// Draw candle plot with v1=v[i], v2=v[i+1] /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ inline void Candle(const mglDataA &y, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="") { mgl_candle(gr, &y, &y1, &y2, pen, opt); } /// Draw candle plot with v1=v[i], v2=v[i+1] /** Different colors are used for up and down values if 2 colors are specified. * Style ‘#’ force drawing wire candle even for 2-color scheme. */ inline void Candle(const mglDataA &y, const char *pen="", const char *opt="") { mgl_candle(gr, &y, NULL, NULL, pen, opt); } /// Draw cones from points {x,y,z} to axis plane /** String \a pen may contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinders instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones; * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Cones(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="@", const char *opt="") { mgl_cones_xyz(gr, &x, &y, &z, pen, opt); } /// Draw cones from points {x,z} to axis plane /** String \a pen may contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinders instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones; * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Cones(const mglDataA &x, const mglDataA &z, const char *pen="@", const char *opt="") { mgl_cones_xz(gr, &x, &z, pen, opt); } /// Draw cones from points {x,z} with x in x-axis range to axis plane /** String \a pen may contain: * ‘@’ for drawing edges; * ‘#’ for wired cones; * ‘t’ for drawing tubes/cylinders instead of cones/prisms; * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones; * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates. * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/ inline void Cones(const mglDataA &z, const char *pen="@", const char *opt="") { mgl_cones(gr, &z, pen, opt); } /// Draw error boxes {ey} at points {x,y} with x in x-axis range /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/ inline void Error(const mglDataA &y, const mglDataA &ey, const char *pen="", const char *opt="") { mgl_error(gr, &y, &ey, pen, opt); } /// Draw error boxes {ey} at points {x,y} /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/ inline void Error(const mglDataA &x, const mglDataA &y, const mglDataA &ey, const char *pen="", const char *opt="") { mgl_error_xy(gr, &x, &y, &ey, pen, opt); } /// Draw error boxes {ex,ey} at points {x,y} /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/ inline void Error(const mglDataA &x, const mglDataA &y, const mglDataA &ex, const mglDataA &ey, const char *pen="", const char *opt="") { mgl_error_exy(gr, &x, &y, &ex, &ey, pen, opt); } /// Draw marks with size r at points {x,y,z} inline void Mark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *pen, const char *opt="") { mgl_mark_xyz(gr, &x, &y, &z, &r, pen, opt); } /// Draw marks with size r at points {x,y} inline void Mark(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="") { mgl_mark_xy(gr, &x, &y, &r, pen, opt); } /// Draw marks with size r at points {x,y} with x in x-axis range inline void Mark(const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="") { mgl_mark_y(gr, &y, &r, pen, opt); } /// Draw Poincare map at condition s==0 for curve {x,y,z} inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *pen, const char *opt="") { mgl_pmap_xyz(gr, &x, &y, &z, &s, pen, opt); } /// Draw Poincare map at condition s==0 for curve {x,y} inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *pen, const char *opt="") { mgl_pmap_xy(gr, &x, &y, &s, pen, opt); } /// Draw Poincare map at condition s==0 for curve {x,y} with x in x-axis range inline void Pmap(const mglDataA &y, const mglDataA &s, const char *pen, const char *opt="") { mgl_pmap(gr, &y, &s, pen, opt); } /// Draw textual marks with size r at points {x,y,z} inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *text, const char *fnt="", const char *opt="") { mgl_textmark_xyzr(gr, &x, &y, &z, &r, text, fnt, opt); } /// Draw textual marks with size r at points {x,y} inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *text, const char *fnt="", const char *opt="") { mgl_textmark_xyr(gr, &x, &y, &r, text, fnt, opt); } /// Draw textual marks with size r at points {x,y} with x in x-axis range inline void TextMark(const mglDataA &y, const mglDataA &r, const char *text, const char *fnt="", const char *opt="") { mgl_textmark_yr(gr, &y, &r, text, fnt, opt); } /// Draw textual marks at points {x,y} with x in x-axis range inline void TextMark(const mglDataA &y, const char *text, const char *fnt="", const char *opt="") { mgl_textmark(gr, &y, text, fnt, opt); } /// Draw textual marks with size r at points {x,y,z} inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_textmarkw_xyzr(gr, &x, &y, &z, &r, text, fnt, opt); } /// Draw textual marks with size r at points {x,y} inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &r, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_textmarkw_xyr(gr, &x, &y, &r, text, fnt, opt); } /// Draw textual marks with size r at points {x,y} with x in x-axis range inline void TextMark(const mglDataA &y, const mglDataA &r, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_textmarkw_yr(gr, &y, &r, text, fnt, opt); } /// Draw textual marks at points {x,y} with x in x-axis range inline void TextMark(const mglDataA &y, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_textmarkw(gr, &y, text, fnt, opt); } /// Draw labels for points coordinate(s) at points {x,y,z} /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ inline void Label(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *text, const char *fnt="", const char *opt="") { mgl_label_xyz(gr, &x, &y, &z, text, fnt, opt); } /// Draw labels for points coordinate(s) at points {x,y} /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ inline void Label(const mglDataA &x, const mglDataA &y, const char *text, const char *fnt="", const char *opt="") { mgl_label_xy(gr, &x, &y, text, fnt, opt); } /// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ inline void Label(const mglDataA &y, const char *text, const char *fnt="", const char *opt="") { mgl_label_y(gr, &y, text, fnt, opt); } /// Draw labels for points coordinate(s) at points {x,y,z} /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ inline void Label(const mglDataA &x, const mglDataA &y, const mglDataA &z, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_labelw_xyz(gr, &x, &y, &z, text, fnt, opt); } /// Draw labels for points coordinate(s) at points {x,y} /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ inline void Label(const mglDataA &x, const mglDataA &y, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_labelw_xy(gr, &x, &y, text, fnt, opt); } /// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range /** String \a fnt may contain: * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers.*/ inline void Label(const mglDataA &y, const wchar_t *text, const char *fnt="", const char *opt="") { mgl_labelw_y(gr, &y, text, fnt, opt); } /// Draw table for values val along given direction with row labels text /** String \a fnt may contain: * ‘#’ for drawing cell borders; * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’); * ‘=’ for equal width of all cells; * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers. * Option value set the width of the table (default is 1).*/ inline void Table(const mglDataA &val, const char *text, const char *fnt="#|", const char *opt="") { mgl_table(gr, 0, 0, &val, text, fnt, opt); } /// Draw table for values val along given direction with row labels text /** String \a fnt may contain: * ‘#’ for drawing cell borders; * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’); * ‘=’ for equal width of all cells; * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers. * Option value set the width of the table (default is 1).*/ inline void Table(const mglDataA &val, const wchar_t *text, const char *fnt="#|", const char *opt="") { mgl_tablew(gr, 0, 0, &val, text, fnt, opt); } /// Draw table for values val along given direction with row labels text at given position /** String \a fnt may contain: * ‘#’ for drawing cell borders; * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’); * ‘=’ for equal width of all cells; * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers. * Option value set the width of the table (default is 1).*/ inline void Table(double x, double y, const mglDataA &val, const char *text, const char *fnt="#|", const char *opt="") { mgl_table(gr, x, y, &val, text, fnt, opt); } /// Draw table for values val along given direction with row labels text at given position /** String \a fnt may contain: * ‘#’ for drawing cell borders; * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’); * ‘=’ for equal width of all cells; * ‘f’ for fixed format of printed numbers; * ‘E’ for using ‘E’ instead of ‘e’; * ‘F’ for printing in LaTeX format; * ‘+’ for printing ‘+’ for positive numbers; * ‘-’ for printing usual ‘-’; * ‘0123456789’ for precision at printing numbers. * Option value set the width of the table (default is 1).*/ inline void Table(double x, double y, const mglDataA &val, const wchar_t *text, const char *fnt="#|", const char *opt="") { mgl_tablew(gr, x, y, &val, text, fnt, opt); } /// Draw tube with radius r around curve {x,y,z} inline void Tube(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *pen="", const char *opt="") { mgl_tube_xyzr(gr, &x, &y, &z, &r, pen, opt); } /// Draw tube with radius r around curve {x,y,z} inline void Tube(const mglDataA &x, const mglDataA &y, const mglDataA &z, double r, const char *pen="", const char *opt="") { mgl_tube_xyz(gr, &x, &y, &z, r, pen, opt); } /// Draw tube with radius r around curve {x,y} inline void Tube(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *pen="", const char *opt="") { mgl_tube_xyr(gr, &x, &y, &r, pen, opt); } /// Draw tube with radius r around curve {x,y} inline void Tube(const mglDataA &x, const mglDataA &y, double r, const char *pen="", const char *opt="") { mgl_tube_xy(gr, &x, &y, r, pen, opt); } /// Draw tube with radius r around curve {x,y} with x in x-axis range inline void Tube(const mglDataA &y, const mglDataA &r, const char *pen="", const char *opt="") { mgl_tube_r(gr, &y, &r, pen, opt); } /// Draw tube with radius r around curve {x,y} with x in x-axis range inline void Tube(const mglDataA &y, double r, const char *pen="", const char *opt="") { mgl_tube(gr, &y, r, pen, opt); } /// Draw surface of curve {r,z} rotation around axis /** Style ‘#’ produce wire plot. Style ‘.’ produce plot by dots.*/ inline void Torus(const mglDataA &r, const mglDataA &z, const char *pen="", const char *opt="") { mgl_torus(gr, &r, &z, pen,opt); } /// Draw mesh lines for 2d data specified parametrically inline void Mesh(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_mesh_xy(gr, &x, &y, &z, stl, opt); } /// Draw mesh lines for 2d data inline void Mesh(const mglDataA &z, const char *stl="", const char *opt="") { mgl_mesh(gr, &z, stl, opt); } /// Draw waterfall plot for 2d data specified parametrically /** Style 'x' draw lines in x-direction. */ inline void Fall(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_fall_xy(gr, &x, &y, &z, stl, opt); } /// Draw waterfall plot for 2d data /** Style 'x' draw lines in x-direction. */ inline void Fall(const mglDataA &z, const char *stl="", const char *opt="") { mgl_fall(gr, &z, stl, opt); } /// Draw belts for 2d data specified parametrically /** Style 'x' draw belts in x-direction. */ inline void Belt(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_belt_xy(gr, &x, &y, &z, stl, opt); } /// Draw belts for 2d data /** Style 'x' draw belts in x-direction. */ inline void Belt(const mglDataA &z, const char *stl="", const char *opt="") { mgl_belt(gr, &z, stl, opt); } /// Draw belts for 2d data specified parametrically with color proportional to c /** Style 'x' draw belts in x-direction. */ inline void BeltC(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *stl="", const char *opt="") { mgl_beltc_xy(gr, &x, &y, &z, &c, stl, opt); } /// Draw belts for 2d data with color proportional to c /** Style 'x' draw belts in x-direction. */ inline void BeltC(const mglDataA &z, const mglDataA &c, const char *stl="", const char *opt="") { mgl_beltc(gr, &z, &c, stl, opt); } /// Draw surface for 2d data specified parametrically with color proportional to z /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void Surf(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_surf_xy(gr, &x, &y, &z, stl, opt); } /// Draw surface for 2d data with color proportional to z /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void Surf(const mglDataA &z, const char *stl="", const char *opt="") { mgl_surf(gr, &z, stl, opt); } /// Draw grid lines for density plot of 2d data specified parametrically inline void Grid(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_grid_xy(gr, &x, &y, &z, stl, opt); } /// Draw grid lines for density plot of 2d data inline void Grid(const mglDataA &z, const char *stl="", const char *opt="") { mgl_grid(gr, &z, stl, opt); } /// Draw vertical tiles with manual colors c for 2d data specified parametrically inline void Tile(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *stl="", const char *opt="") { mgl_tile_xyc(gr, &x, &y, &z, &c, stl, opt); } /// Draw vertical tiles for 2d data specified parametrically inline void Tile(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_tile_xy(gr, &x, &y, &z, stl, opt); } /// Draw vertical tiles for 2d data inline void Tile(const mglDataA &z, const char *stl="", const char *opt="") { mgl_tile(gr, &z, stl, opt); } /// Draw density plot for 2d data specified parametrically /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void Dens(const mglDataA &x, const mglDataA &y, const mglDataA &c, const char *stl="", const char *opt="") { mgl_dens_xy(gr, &x, &y, &c, stl, opt); } /// Draw density plot for 2d data /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void Dens(const mglDataA &c, const char *stl="", const char *opt="") { mgl_dens(gr, &c, stl, opt); } /// Draw vertical boxes for 2d data specified parametrically /** Style ‘#’ draw filled boxes. */ inline void Boxs(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="") { mgl_boxs_xy(gr, &x, &y, &z, stl, opt); } /// Draw vertical boxes for 2d data /** Style ‘#’ draw filled boxes. */ inline void Boxs(const mglDataA &z, const char *stl="", const char *opt="") { mgl_boxs(gr, &z, stl, opt); } /// Draw contour lines on parametric surface at manual levels for 2d data specified parametrically /** Style ‘f’ to draw solid contours. * Style 't'/'T' draw contour labels below/above contours.*/ inline void ContP(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_contp_val(gr, &v, &x, &y, &z, &a, sch, opt); } /// Draw contour lines on parametric surface at manual levels for 2d data specified parametrically /** Style ‘f’ to draw solid contours. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void ContP(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_contp(gr, &x, &y, &z, &a, sch, opt); } /// Draw contour lines at manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Style 't'/'T' draw contour labels below/above contours.*/ inline void Cont(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_cont_xy_val(gr, &v, &x, &y, &z, sch, opt); } /// Draw contour lines for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Style 't'/'T' draw contour labels below/above contours.*/ inline void Cont(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="") { mgl_cont_val(gr, &v, &z, sch, opt); } /// Draw contour lines at manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void Cont(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_cont_xy(gr, &x, &y, &z, sch, opt); } /// Draw contour lines for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void Cont(const mglDataA &z, const char *sch="", const char *opt="") { mgl_cont(gr, &z, sch, opt); } /// Draw contour lines at a[i,j]=val specified parametrically /** Style 't'/'T' draw contour labels below/above contours.*/ inline void ContGen(mreal val, const mglDataA &a, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_cont_gen(gr, val, &a, &x, &y, &z, sch, opt); } /// Draw solid contours at manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. */ inline void ContF(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contf_xy_val(gr, &v, &x, &y, &z, sch, opt); } /// Draw solid contours at manual levels for 2d data /** Style ‘_’ to draw contours at bottom of axis box. */ inline void ContF(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contf_val(gr, &v, &z, sch, opt); } /// Draw solid contours for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ inline void ContF(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contf_xy(gr, &x, &y, &z, sch, opt); } /// Draw solid contours for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ inline void ContF(const mglDataA &z, const char *sch="", const char *opt="") { mgl_contf(gr, &z, sch, opt); } /// Draw solid contours between a[i,j]=v1 and a[i,j]=v2 specified parametrically */ inline void ContFGen(mreal v1, mreal v2, const mglDataA &a, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contf_gen(gr, v1,v2, &a, &x, &y, &z, sch, opt); } /// Draw solid contours at manual levels for 2d data specified parametrically with specified colors /** Style ‘_’ to draw contours at bottom of axis box. */ inline void ContD(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contd_xy_val(gr, &v, &x, &y, &z, sch, opt); } /// Draw solid contours at manual levels for 2d data with specified colors /** Style ‘_’ to draw contours at bottom of axis box. */ inline void ContD(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contd_val(gr, &v, &z, sch, opt); } /// Draw solid contours for 2d data specified parametrically with specified colors /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ inline void ContD(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contd_xy(gr, &x, &y, &z, sch, opt); } /// Draw solid contours for 2d data with specified colors /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ inline void ContD(const mglDataA &z, const char *sch="", const char *opt="") { mgl_contd(gr, &z, sch, opt); } /// Draw contour tubes between manual levels for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. */ inline void ContV(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contv_xy_val(gr, &v, &x, &y, &z, sch, opt); } /// Draw contour tubes between manual levels for 2d data /** Style ‘_’ to draw contours at bottom of axis box. */ inline void ContV(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contv_val(gr, &v, &z, sch, opt); } /// Draw contour tubes for 2d data specified parametrically /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ inline void ContV(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_contv_xy(gr, &x, &y, &z, sch, opt); } /// Draw contour tubes for 2d data /** Style ‘_’ to draw contours at bottom of axis box. * Option "value" set the number of contour levels (default is 7). */ inline void ContV(const mglDataA &z, const char *sch="", const char *opt="") { mgl_contv(gr, &z, sch, opt); } /// Draw axial-symmetric isosurfaces at manual levels for 2d data specified parametrically /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */ inline void Axial(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_axial_xy_val(gr, &v, &x, &y, &z, sch,opt); } /// Draw axial-symmetric isosurfaces at manual levels for 2d data /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */ inline void Axial(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="") { mgl_axial_val(gr, &v, &z, sch, opt); } /// Draw axial-symmetric isosurfaces for 2d data specified parametrically /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). * Option "value" set the number of isosurfaces (default is 3). */ inline void Axial(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_axial_xy(gr, &x, &y, &z, sch, opt); } /// Draw axial-symmetric isosurfaces for 2d data /** String \a sch may contain: * ‘#’ for wired plot; * ‘.’ for plot by dots; * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). * Option "value" set the number of isosurfaces (default is 3). */ inline void Axial(const mglDataA &z, const char *sch="", const char *opt="") { mgl_axial(gr, &z, sch, opt); } /// Draw grid lines for density plot at slice for 3d data specified parametrically /** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ inline void Grid3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="") { mgl_grid3_xyz(gr, &x, &y, &z, &a, stl, sVal, opt); } /// Draw grid lines for density plot at slice for 3d data /** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ inline void Grid3(const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="") { mgl_grid3(gr, &a, stl, sVal, opt); } /// Draw density plot at slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ inline void Dens3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="") { mgl_dens3_xyz(gr, &x, &y, &z, &a, stl, sVal, opt); } /// Draw density plot at slice for 3d data /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/ inline void Dens3(const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="") { mgl_dens3(gr, &a, stl, sVal, opt); } /// Draw isosurface for 3d data specified parametrically /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/ inline void Surf3(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", const char *opt="") { mgl_surf3_xyz_val(gr, Val, &x, &y, &z, &a, stl, opt); } /// Draw isosurface for 3d data /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/ inline void Surf3(double Val, const mglDataA &a, const char *stl="", const char *opt="") { mgl_surf3_val(gr, Val, &a, stl, opt); } /// Draw isosurfaces for 3d data specified parametrically /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", const char *opt="") { mgl_surf3_xyz(gr, &x, &y, &z, &a, stl, opt); } /// Draw isosurfaces for 3d data /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3(const mglDataA &a, const char *stl="", const char *opt="") { mgl_surf3(gr, &a, stl, opt); } /// Draw a semi-transparent cloud for 3d data specified parametrically /** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */ inline void Cloud(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", const char *opt="") { mgl_cloud_xyz(gr, &x, &y, &z, &a, stl, opt); } /// Draw a semi-transparent cloud for 3d data /** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */ inline void Cloud(const mglDataA &a, const char *stl="", const char *opt="") { mgl_cloud(gr, &a, stl, opt); } /// Draw contour lines at manual levels along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. */ inline void Cont3(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_cont3_xyz_val(gr, &v, &x, &y, &z, &a, sch, sVal, opt); } /// Draw contour lines at manual levels along slice for 3d data /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. */ inline void Cont3(const mglDataA &v, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_cont3_val(gr, &v, &a, sch, sVal, opt); } /// Draw contour lines along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void Cont3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_cont3_xyz(gr, &x, &y, &z, &a, sch, sVal, opt); } /// Draw contour lines along slice for 3d data /** Style ‘#’ draw grid lines. * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void Cont3(const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_cont3(gr, &a, sch, sVal, opt); } /// Draw solid contours at manual levels along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */ inline void ContF3(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_contf3_xyz_val(gr, &v, &x, &y, &z, &a, sch, sVal, opt); } /// Draw solid contours at manual levels along slice for 3d data /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */ inline void ContF3(const mglDataA &v, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_contf3_val(gr, &v, &a, sch, sVal, opt); } /// Draw solid contours along slice for 3d data specified parametrically /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Option "value" set the number of contour levels (default is 7).*/ inline void ContF3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_contf3_xyz(gr, &x, &y, &z, &a, sch, sVal, opt); } /// Draw solid contours along slice for 3d data /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. * Option "value" set the number of contour levels (default is 7).*/ inline void ContF3(const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="") { mgl_contf3(gr, &a, sch, sVal, opt); } /// Draw several isosurfaces for 3d beam in curvilinear coordinates /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots. * Variable \a flag is bitwise: * ‘0x1’ - draw in accompanied (not laboratory) coordinates; * ‘0x2’ - draw projection to \rho-z plane; * ‘0x4’ - draw normalized in each slice field.*/ inline void Beam(const mglDataA &tr, const mglDataA &g1, const mglDataA &g2, const mglDataA &a, double r, const char *stl=0, int flag=0, int num=3) { mgl_beam(gr, &tr,&g1,&g2,&a,r,stl,flag,num); } /// Draw isosurface at value \a val for 3d beam in curvilinear coordinates /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots. * Variable \a flag is bitwise: * ‘0x1’ - draw in accompanied (not laboratory) coordinates; * ‘0x2’ - draw projection to \rho-z plane; * ‘0x4’ - draw normalized in each slice field.*/ inline void Beam(double val, const mglDataA &tr, const mglDataA &g1, const mglDataA &g2, const mglDataA &a, double r, const char *stl=NULL, int flag=0) { mgl_beam_val(gr,val,&tr,&g1,&g2,&a,r,stl,flag); } /// Draw vertical tiles with variable size r and manual colors c for 2d data specified parametrically inline void TileS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const mglDataA &c, const char *stl="", const char *opt="") { mgl_tiles_xyc(gr, &x, &y, &z, &r, &c, stl, opt); } /// Draw vertical tiles with variable size r for 2d data specified parametrically inline void TileS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *stl="", const char *opt="") { mgl_tiles_xy(gr, &x, &y, &z, &r, stl, opt); } /// Draw vertical tiles with variable size r for 2d data inline void TileS(const mglDataA &z, const mglDataA &r, const char *stl="", const char *opt="") { mgl_tiles(gr, &z, &r, stl, opt); } /// Draw surface for 2d data specified parametrically with color proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void SurfC(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="") { mgl_surfc_xy(gr, &x, &y, &z, &c, sch,opt); } /// Draw surface for 2d data with color proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void SurfC(const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="") { mgl_surfc(gr, &z, &c, sch,opt); } /// Draw surface for 2d data specified parametrically with alpha proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void SurfA(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="") { mgl_surfa_xy(gr, &x, &y, &z, &c, sch,opt); } /// Draw surface for 2d data with alpha proportional to c /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void SurfA(const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="") { mgl_surfa(gr, &z, &c, sch,opt); } /// Draw surface for 2d data specified parametrically with color proportional to c and alpha proportional to a /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void SurfCA(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const mglDataA &a, const char *sch="", const char *opt="") { mgl_surfca_xy(gr, &x, &y, &z, &c, &a, sch,opt); } /// Draw surface for 2d data with color proportional to c and alpha proportional to a /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void SurfCA(const mglDataA &z, const mglDataA &c, const mglDataA &a, const char *sch="", const char *opt="") { mgl_surfca(gr, &z, &c, &a, sch,opt); } /// Color map of matrix a to matrix b, both matrix can parametrically depend on coordinates /** Style ‘.’ produce plot by dots. */ inline void Map(const mglDataA &x, const mglDataA &y, const mglDataA &a, const mglDataA &b, const char *sch="", const char *opt="") { mgl_map_xy(gr, &x, &y, &a, &b, sch, opt); } /// Color map of matrix a to matrix b /** Style ‘.’ produce plot by dots. */ inline void Map(const mglDataA &a, const mglDataA &b, const char *sch="", const char *opt="") { mgl_map(gr, &a, &b, sch, opt); } /// Draw density plot for spectra-gramm specified parametrically /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void STFA(const mglDataA &x, const mglDataA &y, const mglDataA &re, const mglDataA &im, int dn, const char *sch="", const char *opt="") { mgl_stfa_xy(gr, &x, &y, &re, &im, dn, sch, opt); } /// Draw density plot for spectra-gramm /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void STFA(const mglDataA &re, const mglDataA &im, int dn, const char *sch="", const char *opt="") { mgl_stfa(gr, &re, &im, dn, sch, opt); } /// Draw isosurface for 3d data specified parametrically with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ inline void Surf3A(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3a_xyz_val(gr, Val, &x, &y, &z, &a, &b, stl, opt); } /// Draw isosurface for 3d data with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ inline void Surf3A(double Val, const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3a_val(gr, Val, &a, &b, stl, opt); } /// Draw isosurfaces for 3d data specified parametrically with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3A(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3a_xyz(gr, &x, &y, &z, &a, &b, stl, opt); } /// Draw isosurfaces for 3d data with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3A(const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3a(gr, &a, &b, stl, opt); } /// Draw isosurface for 3d data specified parametrically with color proportional to c /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ inline void Surf3C(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="") { mgl_surf3c_xyz_val(gr, Val, &x, &y, &z, &a, &c, stl,opt); } /// Draw isosurface for 3d data with color proportional to c /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ inline void Surf3C(double Val, const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="") { mgl_surf3c_val(gr, Val, &a, &c, stl, opt); } /// Draw isosurfaces for 3d data specified parametrically with color proportional to c /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3C(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="") { mgl_surf3c_xyz(gr, &x, &y, &z, &a, &c, stl, opt); } /// Draw isosurfaces for 3d data specified parametrically with color proportional to c /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3C(const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="") { mgl_surf3c(gr, &a, &c, stl, opt); } /// Draw isosurface for 3d data specified parametrically with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ inline void Surf3CA(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3ca_xyz_val(gr, Val, &x, &y, &z, &a, &c, &b, stl,opt); } /// Draw isosurface for 3d data with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ inline void Surf3CA(double Val, const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3ca_val(gr, Val, &a, &c, &b, stl, opt); } /// Draw isosurfaces for 3d data specified parametrically with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3CA(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3ca_xyz(gr, &x, &y, &z, &a, &c, &b, stl, opt); } /// Draw isosurfaces for 3d data with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ inline void Surf3CA(const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="") { mgl_surf3ca(gr, &a, &c, &b, stl, opt); } /// Plot dew drops for vector field {ax,ay} parametrically depended on coordinate {x,y} inline void Dew(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_dew_xy(gr, &x, &y, &ax, &ay, sch, opt); } /// Plot dew drops for vector field {ax,ay} inline void Dew(const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_dew_2d(gr, &ax, &ay, sch, opt); } /// Plot vectors at position {x,y} along {ax,ay} with length/color proportional to |a| /** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */ inline void Traj(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_traj_xy(gr, &x, &y, &ax, &ay, sch, opt); } /// Plot vectors at position {x,y,z} along {ax,ay,az} with length/color proportional to |a| /** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */ inline void Traj(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_traj_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt); } /// Plot vector field {ax,ay} parametrically depended on coordinate {x,y} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ inline void Vect(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_vect_xy(gr, &x, &y, &ax, &ay, sch, opt); } /// Plot vector field {ax,ay} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ inline void Vect(const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_vect_2d(gr, &ax, &ay, sch, opt); } /// Plot vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ inline void Vect(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_vect_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt); } /// Plot vector field {ax,ay,az} with length/color proportional to |a| /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows. */ inline void Vect(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_vect_3d(gr, &ax, &ay, &az, sch, opt); } /// Draw vector plot along slice for 3d data specified parametrically /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows, * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */ inline void Vect3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *stl="", double sVal=-1, const char *opt="") { mgl_vect3_xyz(gr, &x, &y, &z, &ax,&ay,&az, stl, sVal, opt); } /// Draw vector plot along slice for 3d data /** String \a sch may contain: * ‘f’ for drawing arrows with fixed lengths, * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering), * ‘.’ for drawing hachures with dots instead of arrows, * ‘=’ for enabling color gradient along arrows, * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */ inline void Vect3(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *stl="", double sVal=-1, const char *opt="") { mgl_vect3(gr, &ax,&ay,&az, stl, sVal, opt); } /// Plot flows for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Flow(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_flow_xy(gr, &x, &y, &ax, &ay, sch, opt); } /// Plot flows for vector field {ax,ay} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Flow(const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_flow_2d(gr, &ax, &ay, sch, opt); } /// Plot flows for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Flow(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_flow_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt); } /// Plot flows for vector field {ax,ay,az} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Flow(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_flow_3d(gr, &ax, &ay, &az, sch, opt); } /// Plot flow from point p for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads. */ inline void FlowP(mglPoint p, const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_flowp_xy(gr, p.x, p.y, p.z, &x, &y, &ax, &ay, sch, opt); } /// Plot flow from point p for vector field {ax,ay} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads. */ inline void FlowP(mglPoint p, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="") { mgl_flowp_2d(gr, p.x, p.y, p.z, &ax, &ay, sch, opt); } /// Plot flow from point p for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */ inline void FlowP(mglPoint p, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_flowp_xyz(gr, p.x, p.y, p.z, &x, &y, &z, &ax, &ay, &az, sch, opt); } /// Plot flow from point p for vector field {ax,ay,az} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */ inline void FlowP(mglPoint p, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="") { mgl_flowp_3d(gr, p.x, p.y, p.z, &ax, &ay, &az, sch, opt); } /// Plot flows from given plain for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * 'v' for drawing arrows on the threads; * 't' for drawing tapes of normals in x-y and y-z planes. * Option "value" sets the number of threads (default is 5). */ inline void Flow3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", double sVal=-1, const char *opt="") { mgl_flow3_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, sVal, opt); } /// Plot flows from given plain for vector field {ax,ay,az} with color proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * 'v' for drawing arrows on the threads; * 't' for drawing tapes of normals in x-y and y-z planes. * Option "value" sets the number of threads (default is 5). */ inline void Flow3(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", double sVal=-1, const char *opt="") { mgl_flow3(gr, &ax, &ay, &az, sch, sVal, opt); } /// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y,z} /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Grad(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &phi, const char *sch="", const char *opt="") { mgl_grad_xyz(gr,&x,&y,&z,&phi,sch,opt); } /// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y} /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Grad(const mglDataA &x, const mglDataA &y, const mglDataA &phi, const char *sch="", const char *opt="") { mgl_grad_xy(gr,&x,&y,&phi,sch,opt); } /// Plot flows for gradient of scalar field phi /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘v’ for drawing arrows on the threads; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Grad(const mglDataA &phi, const char *sch="", const char *opt="") { mgl_grad(gr,&phi,sch,opt); } /// Plot flow pipes for vector field {ax,ay} parametrically depended on coordinate {x,y} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude. * Option "value" sets the number of threads (default is 5). */ inline void Pipe(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", double r0=0.05, const char *opt="") { mgl_pipe_xy(gr, &x, &y, &ax, &ay, sch, r0, opt); } /// Plot flow pipes for vector field {ax,ay} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude. * Option "value" sets the number of threads (default is 5). */ inline void Pipe(const mglDataA &ax, const mglDataA &ay, const char *sch="", double r0=0.05, const char *opt="") { mgl_pipe_2d(gr, &ax, &ay, sch, r0, opt); } /// Plot flow pipes for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Pipe(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", double r0=0.05, const char *opt="") { mgl_pipe_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, r0, opt); } /// Plot flow pipes for vector field {ax,ay,az} with color and radius proportional to |a| /** String \a sch may contain: * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source); * ‘#’ for starting threads from edges only; * ‘i’ for pipe radius to be inverse proportional to amplitude; * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. * Option "value" sets the number of threads (default is 5). */ inline void Pipe(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", double r0=0.05, const char *opt="") { mgl_pipe_3d(gr, &ax, &ay, &az, sch, r0, opt); } /// Draw density plot for data at x = sVal /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void DensX(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_dens_x(gr, &a, stl, sVal, opt); } /// Draw density plot for data at y = sVal /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void DensY(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_dens_y(gr, &a, stl, sVal, opt); } /// Draw density plot for data at z = sVal /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/ inline void DensZ(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_dens_z(gr, &a, stl, sVal, opt); } /// Draw contour lines for data at x = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void ContX(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_cont_x(gr, &a, stl, sVal, opt); } /// Draw contour lines at manual levels for data at x = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. */ inline void ContX(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_cont_x_val(gr, &v, &a, stl, sVal, opt); } /// Draw contour lines for data at y = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void ContY(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_cont_y(gr, &a, stl, sVal, opt); } /// Draw contour lines at manual levels for data at y = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. */ inline void ContY(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_cont_y_val(gr, &v, &a, stl, sVal, opt); } /// Draw contour lines for data at z = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. * Option "value" set the number of contour levels (default is 7). */ inline void ContZ(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_cont_z(gr, &a, stl, sVal, opt); } /// Draw contour lines at manual levels for data at z = sVal /** Style ‘t’/‘T’ draw contour labels below/above contours. */ inline void ContZ(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_cont_z_val(gr, &v, &a, stl, sVal, opt); } /// Draw solid contours for data at x = sVal /** Option "value" set the number of contour levels (default is 7). */ inline void ContFX(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_contf_x(gr, &a, stl, sVal, opt); } /// Draw solid contours at manual levels for data at x = sVal inline void ContFX(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_contf_x_val(gr, &v, &a, stl, sVal, opt); } /// Draw solid contours for data at y = sVal /** Option "value" set the number of contour levels (default is 7). */ inline void ContFY(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_contf_y(gr, &a, stl, sVal, opt); } /// Draw solid contours at manual levels for data at y = sVal inline void ContFY(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_contf_y_val(gr, &v, &a, stl, sVal, opt); } /// Draw solid contours for data at z = sVal /** Option "value" set the number of contour levels (default is 7). */ inline void ContFZ(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_contf_z(gr, &a, stl, sVal, opt); } /// Draw solid contours at manual levels for data at z = sVal inline void ContFZ(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="") { mgl_contf_z_val(gr, &v, &a, stl, sVal, opt); } /// Draw curve for formula with x in x-axis range /** Option "value" set initial number of points. */ inline void FPlot(const char *fy, const char *stl="", const char *opt="") { mgl_fplot(gr, fy, stl, opt); } /// Draw curve for formulas parametrically depended on t in range [0,1] /** Option "value" set initial number of points. */ inline void FPlot(const char *fx, const char *fy, const char *fz, const char *stl, const char *opt="") { mgl_fplot_xyz(gr, fx, fy, fz, stl, opt); } /// Draw surface by formula with x,y in axis range /** Option "value" set initial number of points. */ inline void FSurf(const char *fz, const char *stl="", const char *opt="") { mgl_fsurf(gr, fz, stl, opt); } /// Draw surface by formulas parametrically depended on u,v in range [0,1] /** Option "value" set initial number of points. */ inline void FSurf(const char *fx, const char *fy, const char *fz, const char *stl, const char *opt="") { mgl_fsurf_xyz(gr, fx, fy, fz, stl, opt); } /// Draw triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the triangle colors, else vertex colors. */ inline void TriPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="") { mgl_triplot_xyzc(gr, &nums, &x, &y, &z, &c, sch, opt); } /// Draw triangle mesh for points in arrays {x,y,z} /** Style ‘#’ produce wire plot. */ inline void TriPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_triplot_xyz(gr, &nums, &x, &y, &z, sch, opt); } /// Draw triangle mesh for points in arrays {x,y} /** Style ‘#’ produce wire plot. */ inline void TriPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const char *sch="", const char *opt="") { mgl_triplot_xy(gr, &nums, &x, &y, sch, opt); } /// Draw quad mesh for points in arrays {x,y,z} with specified color c /** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ inline void QuadPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="") { mgl_quadplot_xyzc(gr, &nums, &x, &y, &z, &c, sch, opt); } /// Draw quad mesh for points in arrays {x,y,z} /** Style ‘#’ produce wire plot. */ inline void QuadPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_quadplot_xyz(gr, &nums, &x, &y, &z, sch, opt); } /// Draw quad mesh for points in arrays {x,y} /** Style ‘#’ produce wire plot. */ inline void QuadPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const char *sch="", const char *opt="") { mgl_quadplot_xy(gr, &nums, &x, &y, sch, opt); } /// Draw contour lines for triangle mesh for points in arrays {x,y,z} /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ inline void TriCont(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_tricont_xyc(gr, &nums, &x, &y, &z, sch, opt); } /// Draw contour lines for triangle mesh for points in arrays {x,y,z} /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. * Option "value" set the number of contour levels (default is 7). */ inline void TriContV(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_tricont_xycv(gr, &v, &nums, &x, &y, &z, sch, opt); } /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ inline void TriCont(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_tricont_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt); } /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ inline void TriContV(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt); } /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c. /** Style ‘_’ to draw contours at bottom of axis box. * Style ‘t’/‘T’ draw contour labels below/above contours. * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ inline void TriCont(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt); } /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} /** Option "value" set the number of contour levels (default is 7). */ inline void TriContVt(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_tricontv_xyc(gr, &nums, &x, &y, &z, sch, opt); } /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c /** Option "value" set the number of contour levels (default is 7). */ inline void TriContVt(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_tricontv_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt); } /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c /** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */ inline void TriContVt(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_tricontv_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt); } /// Draw dots in points {x,y,z}. inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_dots(gr, &x, &y, &z, sch, opt); } /// Draw semitransparent dots in points {x,y,z} with specified alpha a. inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="") { mgl_dots_a(gr, &x, &y, &z, &a, sch, opt); } /// Draw semitransparent dots in points {x,y,z} with specified color c and alpha a. inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const mglDataA &a, const char *sch="", const char *opt="") { mgl_dots_ca(gr, &x, &y, &z, &c, &a, sch, opt); } /// Draw surface reconstructed for points in arrays {x,y,z}. /** Style ‘#’ produce wired plot. */ inline void Crust(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="") { mgl_crust(gr, &x, &y, &z, sch, opt); } /// Fit data along x-direction for each data row. Return array with values for found formula. inline mglData Fit(const mglDataA &y, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_1(gr, &y, eq,vars,0, opt)); } /// Fit data along x-direction for each data row starting from \a ini values. Return array with values for found formula. inline mglData Fit(const mglDataA &y, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_1(gr, &y, eq, vars, &ini, opt)); } /// Fit data along x-, y-directions for each data slice. Return array with values for found formula. inline mglData Fit2(const mglDataA &z, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_2(gr, &z, eq, vars,0, opt)); } /// Fit data along x-, y-direction for each data slice starting from \a ini values. Return array with values for found formula. inline mglData Fit2(const mglDataA &z, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_2(gr, &z, eq, vars, &ini, opt)); } /// Fit data along along all directions. Return array with values for found formula. inline mglData Fit3(const mglDataA &a, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_3(gr, &a, eq, vars,0, opt)); } /// Fit data along all directions starting from \a ini values. Return array with values for found formula. inline mglData Fit3(const mglDataA &a, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_3(gr, &a, eq, vars, &ini, opt)); } /// Fit data along x-direction for each data row. Return array with values for found formula. inline mglData Fit(const mglDataA &x, const mglDataA &y, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_xy(gr, &x, &y, eq, vars,0, opt)); } /// Fit data along x-direction for each data row starting from \a ini values. Return array with values for found formula. inline mglData Fit(const mglDataA &x, const mglDataA &y, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_xy(gr, &x, &y, eq, vars, &ini, opt)); } /// Fit data along x-, y-directions for each data slice. Return array with values for found formula. inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, vars,0, opt)); } /// Fit data along x-, y-directions for each data slice starting from \a ini values. Return array with values for found formula. inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, vars, &ini, opt)); } /// Fit data along along all directions. Return array with values for found formula. inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq, vars,0, opt)); } /// Fit data along along all directions starting from \a ini values. Return array with values for found formula. inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq,vars, &ini, opt)); } /// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula. inline mglData FitS(const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_ys(gr, &y, &s, eq, vars,0, opt)); } /// Fit data with dispersion s along x-direction for each data row starting from \a ini values. Return array with values for found formula. inline mglData FitS(const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_ys(gr, &y, &s, eq, vars, &ini, opt)); } /// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula. inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, vars,0, opt)); } /// Fit data with dispersion s along x-direction for each data row starting from \a ini values. Return array with values for found formula. inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, vars, &ini, opt)); } /// Fit data with dispersion s along x-, y-directions for each data slice. Return array with values for found formula. inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, vars,0, opt)); } /// Fit data with dispersion s along x-, y-directions for each data slice starting from \a ini values. Return array with values for found formula. inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, vars, &ini, opt)); } /// Fit data with dispersion s along all directions. Return array with values for found formula. inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &s, const char *eq, const char *vars, const char *opt="") { return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, vars,0, opt)); } /// Fit data with dispersion s along all directions starting from \a ini values. Return array with values for found formula. inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="") { return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, vars, &ini, opt)); } /// Print fitted last formula (with coefficients) inline void PutsFit(mglPoint p, const char *prefix=0, const char *font="", double size=-1) { mgl_puts_fit(gr, p.x, p.y, p.z, prefix, font, size); } /// Get last fitted formula inline const char *GetFit() const { return mgl_get_fit(gr); } /// Get chi for last fitted formula static inline mreal GetFitChi() { return mgl_get_fit_chi(); } /// Get covariance matrix for last fitted formula static inline mglData GetFitCovar() { return mglData(mgl_get_fit_covar()); } /// Solve PDE with x,y,z in range axis range inline mglData PDE(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="") { return mglData(true,mgl_pde_solve(gr,ham,&ini_re,&ini_im,dz,k0, opt)); } /// Solve PDE with x,y,z in range axis range inline mglDataC PDEc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="") { return mglDataC(true,mgl_pde_solve_c(gr,ham,&ini_re,&ini_im,dz,k0, opt)); } /// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only) inline mglData APDE(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="") { return mglData(true,mgl_pde_adv(gr,ham,&ini_re,&ini_im,dz,k0, opt)); } /// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only) inline mglDataC APDEc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="") { return mglDataC(true,mgl_pde_adv_c(gr,ham,&ini_re,&ini_im,dz,k0, opt)); } /// Fill data by formula with x,y,z in range axis range inline void Fill(mglData &u, const char *eq, const char *opt="") { mgl_data_fill_eq(gr, &u, eq, 0, 0, opt); } inline void Fill(mglData &u, const char *eq, const mglDataA &v, const char *opt="") { mgl_data_fill_eq(gr, &u, eq, &v, 0, opt); } inline void Fill(mglData &u, const char *eq, const mglDataA &v, const mglDataA &w, const char *opt="") { mgl_data_fill_eq(gr, &u, eq, &v, &w, opt); } /// Fill data by formula with x,y,z in range axis range inline void Fill(mglDataC &u, const char *eq, const char *opt="") { mgl_datac_fill_eq(gr, &u, eq, 0, 0, opt); } inline void Fill(mglDataC &u, const char *eq, const mglDataA &v, const char *opt="") { mgl_datac_fill_eq(gr, &u, eq, &v, 0, opt); } inline void Fill(mglDataC &u, const char *eq, const mglDataA &v, const mglDataA &w, const char *opt="") { mgl_datac_fill_eq(gr, &u, eq, &v, &w, opt); } /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in axis range inline void Refill(mglData &dat, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="") { mgl_data_refill_gr(gr,&dat,&xdat,0,0,&vdat,sl,opt); } /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in axis range inline void Refill(mglData &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="") { mgl_data_refill_gr(gr,&dat,&xdat,&ydat,0,&vdat,sl,opt); } /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range inline void Refill(mglData &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="") { mgl_data_refill_gr(gr,&dat,&xdat,&ydat,&zdat,&vdat,-1,opt); } /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in axis range inline void Refill(mglDataC &dat, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="") { mgl_datac_refill_gr(gr,&dat,&xdat,0,0,&vdat,sl,opt); } /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in axis range inline void Refill(mglDataC &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="") { mgl_datac_refill_gr(gr,&dat,&xdat,&ydat,0,&vdat,sl,opt); } /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range inline void Refill(mglDataC &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="") { mgl_datac_refill_gr(gr,&dat,&xdat,&ydat,&zdat,&vdat,-1,opt); } /// Set the data by triangulated surface values assuming x,y,z in range axis range inline void DataGrid(mglData &d, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *opt="") { mgl_data_grid(gr,&d,&x,&y,&z,opt); } /// Make histogram (distribution) of data. This function do not plot data. /** Option "value" sets the size of output array (default is mglFitPnts=100). */ inline mglData Hist(const mglDataA &x, const mglDataA &a, const char *opt="") { return mglData(true, mgl_hist_x(gr, &x, &a, opt)); } /// Make histogram (distribution) of data. This function do not plot data. /** Option "value" sets the size of output array (default is mglFitPnts=100). */ inline mglData Hist(const mglDataA &x, const mglDataA &y, const mglDataA &a, const char *opt="") { return mglData(true, mgl_hist_xy(gr, &x, &y, &a, opt)); } /// Make histogram (distribution) of data. This function do not plot data. /** Option "value" sets the size of output array (default is mglFitPnts=100). */ inline mglData Hist(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *opt="") { return mglData(true, mgl_hist_xyz(gr, &x, &y, &z, &a, opt)); } inline void Compression(bool){} // NOTE: Add later -- IDTF /// Set the preference for vertex color on/off (for formats that support it, now only PRC does). inline void VertexColor(bool enable) { mgl_set_flag(gr,enable, MGL_PREFERVC); } /// Render only front side of surfaces for dubugging purposes (for formats that support it, now only PRC does). inline void DoubleSided(bool enable) { mgl_set_flag(gr,!enable, MGL_ONESIDED); } // inline void TextureColor(bool){} // NOTE: Add later -- IDTF }; //----------------------------------------------------------------------------- /// Wrapper class for MGL parsing class MGL_EXPORT mglParse { HMPR pr; mglParse &operator=(mglParse &p) { pr = p.pr; mgl_use_parser(pr,1); return p; } public: mglParse(HMPR p) { pr = p; mgl_use_parser(pr,1); } mglParse(mglParse &p) { pr = p.pr; mgl_use_parser(pr,1); } mglParse(bool setsize=false) { pr=mgl_create_parser(); mgl_parser_allow_setsize(pr, setsize); } virtual ~mglParse() { #pragma omp critical if(mgl_use_parser(pr,-1)<1) mgl_delete_parser(pr); } /// Get pointer to internal mglParser object inline HMPR Self() { return pr; } /// Parse and draw single line of the MGL script inline int Parse(mglGraph *gr, const char *str, int pos) { return mgl_parse_line(gr->Self(), pr, str, pos); } inline int Parse(mglGraph *gr, const wchar_t *str, int pos) { return mgl_parse_linew(gr->Self(), pr, str, pos); } /// Execute MGL script text with '\n' separated lines inline void Execute(mglGraph *gr, const char *str) { mgl_parse_text(gr->Self(), pr, str); } inline void Execute(mglGraph *gr, const wchar_t *str) { mgl_parse_textw(gr->Self(), pr, str); } /// Execute and draw script from the file inline void Execute(mglGraph *gr, FILE *fp, bool print=false) { mgl_parse_file(gr->Self(), pr, fp, print); } /// Return type of command: 0 - not found, 1 - other data plot, 2 - func plot, /// 3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program /// 8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot /// 13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform inline int CmdType(const char *name) { return mgl_parser_cmd_type(pr, name); } /// Return string of command format (command name and its argument[s]) inline const char *CmdFormat(const char *name) { return mgl_parser_cmd_frmt(pr, name); } /// Return description of MGL command inline const char *CmdDesc(const char *name) { return mgl_parser_cmd_desc(pr, name); } /// Get name of command with number n inline const char *GetCmdName(long n) { return mgl_parser_cmd_name(pr,n); } /// Get number of defined commands inline long GetCmdNum() { return mgl_parser_cmd_num(pr); } /// Load new commands from external dynamic Library (must have "const mglCommand *mgl_cmd_extra" variable) inline void LoadDLL(const char *fname) { mgl_parser_load(pr, fname); } /// Apply one step for equation d vars[i]/dt = eqs[i] using Runge-Kutta method inline void RK_Step(const char *eqs, const char *vars, mreal dt=1) { mgl_rk_step(pr, eqs, vars, dt); } inline void RK_Step(const wchar_t *eqs, const wchar_t *vars, mreal dt=1) { mgl_rk_step_w(pr, eqs, vars, dt); } // Open all data arrays from HDF file and assign it as variables of parser p inline void OpenHDF(const char *fname) { mgl_parser_openhdf(pr, fname); } /// Set value for parameter $N inline void AddParam(int id, const char *str) { mgl_parser_add_param(pr, id, str); } inline void AddParam(int id, const wchar_t *str) { mgl_parser_add_paramw(pr, id, str); } /// Restore once flag inline void RestoreOnce() { mgl_parser_restore_once(pr); } /// Allow changing size of the picture inline void AllowSetSize(bool allow) { mgl_parser_allow_setsize(pr, allow); } /// Allow reading/saving files inline void AllowFileIO(bool allow) { mgl_parser_allow_file_io(pr, allow); } /// Allow loading commands from external libraries inline void AllowDllCall(bool allow) { mgl_parser_allow_dll_call(pr, allow); } /// Set flag to stop script parsing inline void Stop() { mgl_parser_stop(pr); } /// Set variant of argument(s) separated by '?' to be used in further commands inline void SetVariant(int var=0) { mgl_parser_variant(pr, var); } /// Set starting object ID inline void StartID(int id=0) { mgl_parser_start_id(pr, id); } /// Return result of formula evaluation inline mglData Calc(const char *formula) { return mglData(true,mgl_parser_calc(pr,formula)); } inline mglData Calc(const wchar_t *formula) { return mglData(true,mgl_parser_calcw(pr,formula)); } /// Return result of formula evaluation as complex data inline mglDataC CalcComplex(const char *formula) { return mglDataC(true,mgl_parser_calc_complex(pr,formula)); } inline mglDataC CalcComplex(const wchar_t *formula) { return mglDataC(true,mgl_parser_calc_complexw(pr,formula)); } /// Find variable with given name or add a new one /// NOTE !!! You must not delete obtained data arrays !!! inline mglDataA *AddVar(const char *name) { return mgl_parser_add_var(pr, name); } inline mglDataA *AddVar(const wchar_t *name) { return mgl_parser_add_varw(pr, name); } /// Find variable with given name or return NULL if no one /// NOTE !!! You must not delete obtained data arrays !!! inline mglDataA *FindVar(const char *name) { return mgl_parser_find_var(pr, name); } inline mglDataA *FindVar(const wchar_t *name) { return mgl_parser_find_varw(pr, name); } /// Get variable with given id. Can be NULL for temporary ones. /// NOTE !!! You must not delete obtained data arrays !!! inline mglDataA *GetVar(unsigned long id) { return mgl_parser_get_var(pr,id); } /// Get number of variables inline long GetNumVar() { return mgl_parser_num_var(pr); } /// Delete variable with name inline void DeleteVar(const char *name) { mgl_parser_del_var(pr, name); } inline void DeleteVar(const wchar_t *name) { mgl_parser_del_varw(pr, name); } /// Delete all data variables void DeleteAll() { mgl_parser_del_all(pr); } /// Get constant with given id. Can be NULL if not found. /// NOTE !!! You must not delete obtained data arrays !!! inline mglNum *GetConst(unsigned long id) { return mgl_parser_get_const(pr,id); } /// Get number of constants inline long GetNumConst() { return mgl_parser_num_const(pr); } }; //----------------------------------------------------------------------------- #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/volume.h������������������������������������������������������������������0000644�0001750�0001750�00000025543�13513030041�017122� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * volume.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_VOL_H_ #define _MGL_VOL_H_ #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------- /// Draw isosurface for 3d data specified parametrically /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surf3_xyz_val(HMGL graph, double Val, HCDT x, HCDT y, HCDT z, HCDT a, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3_xyz_val_(uintptr_t *graph, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/ void MGL_EXPORT mgl_surf3_val(HMGL graph, double Val, HCDT a, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3_val_(uintptr_t *graph, mreal *Val, uintptr_t *a, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data specified parametrically /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT a, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3(HMGL graph, HCDT a, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3_(uintptr_t *graph, uintptr_t *a, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data specified parametrically with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_surf3a_xyz_val(HMGL graph, double Val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3a_xyz_val_(uintptr_t *graph, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_surf3a_val(HMGL graph, double Val, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3a_val_(uintptr_t *graph, mreal *Val, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data specified parametrically with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3a_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3a_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data with alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3a(HMGL graph, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3a_(uintptr_t *graph, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data specified parametrically with color proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_surf3c_xyz_val(HMGL graph, double Val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3c_xyz_val_(uintptr_t *graph, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data with color proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_surf3c_val(HMGL graph, double Val, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3c_val_(uintptr_t *graph, mreal *Val, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data specified parametrically with color proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3c_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3c_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data with color proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3c(HMGL graph, HCDT a, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3c_(uintptr_t *graph, uintptr_t *a, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data specified parametrically with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_surf3ca_xyz_val(HMGL graph, double Val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3ca_xyz_val_(uintptr_t *graph, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d data with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */ void MGL_EXPORT mgl_surf3ca_val(HMGL graph, double Val, HCDT a, HCDT c, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3ca_val_(uintptr_t *graph, mreal *Val, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data specified parametrically with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3ca_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3ca_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw isosurfaces for 3d data with color proportional to c and alpha proportional to b /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). */ void MGL_EXPORT mgl_surf3ca(HMGL graph, HCDT a, HCDT c, HCDT b, const char *stl, const char *opt); void MGL_EXPORT mgl_surf3ca_(uintptr_t *graph, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *stl, const char *opt,int,int); /// Draw a semi-transparent cloud for 3d data specified parametrically /** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */ void MGL_EXPORT mgl_cloud_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT a, const char *stl, const char *opt); void MGL_EXPORT mgl_cloud_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *stl, const char *opt,int,int); /// Draw a semi-transparent cloud for 3d data /** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */ void MGL_EXPORT mgl_cloud(HMGL graph, HCDT a, const char *stl, const char *opt); void MGL_EXPORT mgl_cloud_(uintptr_t *graph, uintptr_t *a, const char *stl, const char *opt,int,int); /// Draw isosurface for 3d beam in curvilinear coordinates /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots. * Variable \a flag is bitwise: * ‘0x1’ - draw in accompanied (not laboratory) coordinates; * ‘0x2’ - draw projection to \rho-z plane; * ‘0x4’ - draw normalized in each slice field.*/ void MGL_EXPORT mgl_beam_val(HMGL graph, double Val, HCDT tr, HCDT g1, HCDT g2, HCDT a, double r, const char *stl, int norm); void MGL_EXPORT mgl_beam_val_(uintptr_t *gr, mreal *val, uintptr_t *tr, uintptr_t *g1, uintptr_t *g2, uintptr_t *a, mreal *r, const char *sch, int *norm,int l); /// Draw several isosurfaces for 3d beam in curvilinear coordinates /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots. * Option "value" set the number of isosurfaces (default is 3). * Variable \a flag is bitwise: * ‘0x1’ - draw in accompanied (not laboratory) coordinates; * ‘0x2’ - draw projection to \rho-z plane; * ‘0x4’ - draw normalized in each slice field.*/ void MGL_EXPORT mgl_beam(HMGL graph, HCDT tr, HCDT g1, HCDT g2, HCDT a, double r, const char *stl, int norm, int num); void MGL_EXPORT mgl_beam_(uintptr_t *gr, uintptr_t *tr, uintptr_t *g1, uintptr_t *g2, uintptr_t *a, mreal *r, const char *sch, int *norm, int *num,int l); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif //----------------------------------------------------------------------------- #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/canvas_wnd.h��������������������������������������������������������������0000644�0001750�0001750�00000012330�13513030041�017724� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * canvas_wnd.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_CANVAS_WND_H_ #define _MGL_CANVAS_WND_H_ #include "mgl2/canvas.h" #include "mgl2/wnd.h" //----------------------------------------------------------------------------- /// Base class for windows containing MathGL graphics class MGL_EXPORT mglCanvasWnd : public mglCanvas { public: mglPoint LastMousePos; ///< Last mouse position void (*ClickFunc)(void *par); ///< Callback function on click #if MGL_HAVE_PTHR_WIDGET pthread_mutex_t *mutex; #endif mglCanvasWnd(); virtual ~mglCanvasWnd(); void SetSize(int w,int h,bool clf=true); void EndFrame(); void SetFrame(long i); void DelFrame(long i); const unsigned char *GetBits(); inline int GetNumFig() const { return NumFig; } inline int GetCurFig() const { return CurFig; } void SetCurFig(int c); void ResetFrames(); inline mglPoint GetMousePos() const { return LastMousePos;} inline void SetMousePos(mglPoint p) { LastMousePos=p; } inline void Setup(bool clf_upd=true, bool showpos=false) { set(showpos,MGL_SHOW_POS); set(clf_upd,MGL_CLF_ON_UPD); if(!clf_upd) ResetFrames(); } virtual void ToggleAlpha()=0; ///< Switch on/off transparency (do not overwrite user settings) virtual void ToggleLight()=0; ///< Switch on/off lighting (do not overwrite user settings) virtual void ToggleZoom()=0; ///< Switch on/off zooming by mouse virtual void ToggleRotate()=0; ///< Switch on/off rotation by mouse virtual void ToggleNo()=0; ///< Switch off all zooming and rotation virtual void Update()=0; ///< Update picture by calling user drawing function virtual void Adjust()=0; ///< Adjust size of bitmap to window size virtual void GotoFrame(int d)=0;///< Show arbitrary frame (use relative step) virtual void NextFrame() {GotoFrame(+1);} ///< Show next frame (if one) virtual void PrevFrame() {GotoFrame(-1);} ///< Show previous frame (if one) virtual void Animation()=0; ///< Run slideshow (animation) of frames virtual void *Window()=0; ///< Return pointer to widget (Fl_Window* or QMainWindow*) used for plotting virtual void *Widget()=0; ///< Return pointer to widget (Fl_MGLView* or QMathGL*) used for plotting virtual void WndSize(int w, int h)=0; ///< Resize window virtual void WndMove(int x, int y)=0; ///< Move window void ReLoad(); ///< Reload user data and update picture /// Create a window for plotting based on callback function (can be NULL). virtual void Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title, void *par=NULL, void (*reload)(void *p)=NULL, bool maximize=false)=0; void SetDrawFunc(int (*draw)(mglBase *gr, void *p), void *par=NULL, void (*reload)(void *p)=NULL); /// Set callback function for properties setup void SetPropFunc(void (*prop)(char id, const char *val, void *p), void *par=NULL) { PropFunc = prop; PropPar = par; } inline void SetParam(char id, const char *val) ///< Set parameter (usually from custom dialog) { if(PropFunc) { PropFunc(id,val,PropPar); Update(); } } ///< Make custom dialog virtual void MakeDialog(const char *ids, char const * const *args, const char *title="")=0; private: int CurFig; ///< Current figure in the list. unsigned char *GG; ///< images for all frames (may be too LARGE !!!) int NumFig; ///< Number of figures in the list. If 0 then no list and mglCanvas::DrawFunc will called for each drawing. void (*LoadFunc)(void *par); void *FuncPar; ///< Parameters for drawing function mglCanvas::DrawFunc. /// Drawing function for window procedure. It should return the number of frames. int (*DrawFunc)(mglBase *gr, void *par); void *PropPar; ///< Parameters for prop_func(). /// Function for setting properties. void (*PropFunc)(char id, const char *val, void *par); }; //----------------------------------------------------------------------------- #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/opengl.h������������������������������������������������������������������0000644�0001750�0001750�00000006454�13513030041�017077� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * opengl.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MGL_CANVAS_GL_H #define MGL_CANVAS_GL_H //----------------------------------------------------------------------------- #include "mgl2/canvas.h" //----------------------------------------------------------------------------- class MGL_EXPORT mglCanvasGL : public mglCanvas { public: mglCanvasGL(); virtual ~mglCanvasGL(); void SetQuality(int =0) { Quality=2; } void Finish(); void SetSize(int ,int ,bool clf=true) { if(clf) Clf(); } void View(mreal tetX,mreal tetY,mreal tetZ); void Zoom(mreal x1, mreal y1, mreal x2, mreal y2); /* int NewFrame(); void EndFrame(); void DelFrame(long ){}*/ bool Alpha(bool enable); void Fog(mreal d, mreal dz=0.25); bool Light(bool enable); void Light(int n, bool enable); void AddLight(int n,mglPoint r,mglPoint d, char c='w', mreal bright=0.5, mreal ap=0); void Clf(mglColor Back=NC); void Clf(const char *col); protected: // provide fastest variant for usual points (not glyphs or marks) void line_draw(long n1, long n2); void trig_draw(long n1, long n2, long n3); void quad_draw(long n1, long n2, long n3, long n4); // variant for glyphs or marks void line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d); void trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d); void quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d); void pnt_draw(const mglPnt &p, const mglDrawReg *d); void mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d); void glyph_fill(mreal phi, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d); unsigned char **GetRGBLines(long &w, long &h, unsigned char *&f, bool solid=true); void LightScale(const mglMatrix *M); void gl_clf(mglColor Back=WC); }; //----------------------------------------------------------------------------- #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/data_cf.h�����������������������������������������������������������������0000644�0001750�0001750�00000107345�13513030041�017175� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * data_cf.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_DATA_CF_H_ #define _MGL_DATA_CF_H_ //----------------------------------------------------------------------------- #include "mgl2/abstract.h" //----------------------------------------------------------------------------- #if MGL_HAVE_GSL #include #include #else #ifdef __cplusplus struct gsl_vector; struct gsl_matrix; #else typedef void gsl_vector; typedef void gsl_matrix; #endif #endif //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Get integer power of x double MGL_EXPORT_CONST mgl_ipow(double x,int n); double MGL_EXPORT_PURE mgl_ipow_(mreal *x,int *n); /// Get number of seconds since 1970 for given string double MGL_EXPORT mgl_get_time(const char *time, const char *fmt); double MGL_EXPORT mgl_get_time_(const char *time, const char *fmt,int,int); /// Create HMDT object HMDT MGL_EXPORT mgl_create_data(); uintptr_t MGL_EXPORT mgl_create_data_(); /// Create HMDT object with specified sizes HMDT MGL_EXPORT mgl_create_data_size(long nx, long ny, long nz); uintptr_t MGL_EXPORT mgl_create_data_size_(int *nx, int *ny, int *nz); /// Create HMDT object with data from file HMDT MGL_EXPORT mgl_create_data_file(const char *fname); uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname, int len); /// Delete HMDT object void MGL_EXPORT mgl_delete_data(HMDT dat); void MGL_EXPORT mgl_delete_data_(uintptr_t *dat); /// Rearange data dimensions void MGL_EXPORT mgl_data_rearrange(HMDT dat, long mx,long my,long mz); void MGL_EXPORT mgl_data_rearrange_(uintptr_t *dat, int *mx, int *my, int *mz); /// Link external data array (don't delete it at exit) void MGL_EXPORT mgl_data_link(HMDT dat, mreal *A,long mx,long my,long mz); void MGL_EXPORT mgl_data_link_(uintptr_t *d, mreal *A, int *nx,int *ny,int *nz); /// Allocate memory and copy the data from the (float *) array void MGL_EXPORT mgl_data_set_float(HMDT dat, const float *A,long mx,long my,long mz); void MGL_EXPORT mgl_data_set_float_(uintptr_t *dat, const float *A,int *NX,int *NY,int *NZ); void MGL_EXPORT mgl_data_set_float1_(uintptr_t *d, const float *A,int *N1); /// Allocate memory and copy the data from the (double *) array void MGL_EXPORT mgl_data_set_double(HMDT dat, const double *A,long mx,long my,long mz); void MGL_EXPORT mgl_data_set_double_(uintptr_t *dat, const double *A,int *NX,int *NY,int *NZ); void MGL_EXPORT mgl_data_set_double1_(uintptr_t *d, const double *A,int *N1); /// Allocate memory and copy the data from the (float **) array void MGL_EXPORT mgl_data_set_float2(HMDT d, float const * const *A,long N1,long N2); void MGL_EXPORT mgl_data_set_float2_(uintptr_t *d, const float *A,int *N1,int *N2); /// Allocate memory and copy the data from the (double **) array void MGL_EXPORT mgl_data_set_double2(HMDT d, double const * const *A,long N1,long N2); void MGL_EXPORT mgl_data_set_double2_(uintptr_t *d, const double *A,int *N1,int *N2); /// Allocate memory and copy the data from the (float ***) array void MGL_EXPORT mgl_data_set_float3(HMDT d, float const * const * const *A,long N1,long N2,long N3); void MGL_EXPORT mgl_data_set_float3_(uintptr_t *d, const float *A,int *N1,int *N2,int *N3); /// Allocate memory and copy the data from the (double ***) array void MGL_EXPORT mgl_data_set_double3(HMDT d, double const * const * const *A,long N1,long N2,long N3); void MGL_EXPORT mgl_data_set_double3_(uintptr_t *d, const double *A,int *N1,int *N2,int *N3); /// Import data from abstract type void MGL_EXPORT mgl_data_set(HMDT dat, HCDT a); void MGL_EXPORT mgl_data_set_(uintptr_t *dat, uintptr_t *a); /// Allocate memory and copy the data from the gsl_vector void MGL_EXPORT mgl_data_set_vector(HMDT dat, gsl_vector *v); /// Allocate memory and copy the data from the gsl_matrix void MGL_EXPORT mgl_data_set_matrix(HMDT dat, gsl_matrix *m); /// Set value of data element [i,j,k] void MGL_EXPORT mgl_data_set_value(HMDT dat, mreal v, long i, long j, long k); void MGL_EXPORT mgl_data_set_value_(uintptr_t *d, mreal *v, int *i, int *j, int *k); /// Get value of data element [i,j,k] mreal MGL_EXPORT mgl_data_get_value(HCDT dat, long i, long j, long k); mreal MGL_EXPORT mgl_data_get_value_(uintptr_t *d, int *i, int *j, int *k); /// Allocate memory and scanf the data from the string void MGL_EXPORT mgl_data_set_values(HMDT dat, const char *val, long nx, long ny, long nz); void MGL_EXPORT mgl_data_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l); /// Read data array from HDF file (parse HDF4 and HDF5 files) int MGL_EXPORT mgl_data_read_hdf(HMDT d,const char *fname,const char *data); int MGL_EXPORT mgl_data_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n); /// Read data from tab-separated text file with auto determining size int MGL_EXPORT mgl_data_read(HMDT dat, const char *fname); int MGL_EXPORT mgl_data_read_(uintptr_t *d, const char *fname,int l); /// Read data from text file with size specified at beginning of the file int MGL_EXPORT mgl_data_read_mat(HMDT dat, const char *fname, long dim); int MGL_EXPORT mgl_data_read_mat_(uintptr_t *dat, const char *fname, int *dim, int); /// Read data from text file with specifeid size int MGL_EXPORT mgl_data_read_dim(HMDT dat, const char *fname,long mx,long my,long mz); int MGL_EXPORT mgl_data_read_dim_(uintptr_t *dat, const char *fname,int *mx,int *my,int *mz,int); /// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to int MGL_EXPORT mgl_data_read_range(HMDT d, const char *templ, double n1, double n2, double step, int as_slice); int MGL_EXPORT mgl_data_read_range_(uintptr_t *d, const char *fname, mreal *n1, mreal *n2, mreal *step, int *as_slice,int l); /// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat") int MGL_EXPORT mgl_data_read_all(HMDT dat, const char *templ, int as_slice); int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l); /// Import data array from PNG file according color scheme void MGL_EXPORT mgl_data_import(HMDT dat, const char *fname, const char *scheme,mreal v1,mreal v2); void MGL_EXPORT mgl_data_import_(uintptr_t *dat, const char *fname, const char *scheme,mreal *v1,mreal *v2,int,int); /// Scan textual file for template and fill data array int MGL_EXPORT mgl_data_scan_file(HMDT dat,const char *fname, const char *templ); int MGL_EXPORT mgl_data_scan_file_(uintptr_t *dat,const char *fname, const char *templ,int,int); /// Read data array from Tektronix WFM file /** Parse Tektronix TDS5000/B, TDS6000/B/C, TDS/CSA7000/B, MSO70000/C, DSA70000/B/C DPO70000/B/C DPO7000/ MSO/DPO5000. */ int MGL_EXPORT mgl_data_read_wfm(HMDT d,const char *fname, long num, long step, long start); int MGL_EXPORT mgl_data_read_wfm_(uintptr_t *d, const char *fname, long *num, long *step, long *start,int l); /// Read data array from Matlab MAT file (parse versions 4 and 5) int MGL_EXPORT mgl_data_read_matlab(HMDT d,const char *fname,const char *data); int MGL_EXPORT mgl_data_read_matlab_(uintptr_t *d, const char *fname, const char *data,int l,int n); /// Create or recreate the array with specified size and fill it by zero void MGL_EXPORT mgl_data_create(HMDT dat, long nx,long ny,long nz); void MGL_EXPORT mgl_data_create_(uintptr_t *dat, int *nx,int *ny,int *nz); /// Transpose dimensions of the data (generalization of Transpose) void MGL_EXPORT mgl_data_transpose(HMDT dat, const char *dim); void MGL_EXPORT mgl_data_transpose_(uintptr_t *dat, const char *dim,int); /// Normalize the data to range [v1,v2] void MGL_EXPORT mgl_data_norm(HMDT dat, mreal v1,mreal v2,int sym,long dim); void MGL_EXPORT mgl_data_norm_(uintptr_t *dat, mreal *v1,mreal *v2,int *sym,int *dim); /// Normalize the data to range [v1,v2] slice by slice void MGL_EXPORT mgl_data_norm_slice(HMDT dat, mreal v1,mreal v2,char dir,long keep_en,long sym); void MGL_EXPORT mgl_data_norm_slice_(uintptr_t *dat, mreal *v1,mreal *v2,char *dir,int *keep_en,int *sym,int l); /// Limit the data to be inside [-v,v], keeping the original sign void MGL_EXPORT mgl_data_limit(HMDT dat, mreal v); void MGL_EXPORT mgl_data_limit_(uintptr_t *dat, mreal *v); /// Project the periodical data to range [v1,v2] (like mod() function). Separate branches by NAN if sep=true. void MGL_EXPORT mgl_data_coil(HMDT dat, mreal v1, mreal v2, int sep); void MGL_EXPORT mgl_data_coil_(uintptr_t *dat, mreal *v1, mreal *v2, int *sep); /// Get sub-array of the data with given fixed indexes HMDT MGL_EXPORT mgl_data_subdata(HCDT dat, long xx,long yy,long zz); uintptr_t MGL_EXPORT mgl_data_subdata_(uintptr_t *dat, int *xx,int *yy,int *zz); /// Get sub-array of the data with given fixed indexes (like indirect access) HMDT MGL_EXPORT mgl_data_subdata_ext(HCDT dat, HCDT xx, HCDT yy, HCDT zz); uintptr_t MGL_EXPORT mgl_data_subdata_ext_(uintptr_t *dat, uintptr_t *xx,uintptr_t *yy,uintptr_t *zz); /// Get column (or slice) of the data filled by formulas of named columns HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq); uintptr_t MGL_EXPORT mgl_data_column_(uintptr_t *dat, const char *eq,int l); /// Get data from sections ids, separated by value val along specified direction. /** If section id is negative then reverse order is used (i.e. -1 give last section). */ HMDT MGL_EXPORT mgl_data_section(HCDT dat, HCDT ids, char dir, mreal val); uintptr_t MGL_EXPORT mgl_data_section_(uintptr_t *d, uintptr_t *ids, const char *dir, mreal *val,int); /// Get data from section id, separated by value val along specified direction. /** If section id is negative then reverse order is used (i.e. -1 give last section). */ HMDT MGL_EXPORT mgl_data_section_val(HCDT dat, long id, char dir, mreal val); uintptr_t MGL_EXPORT mgl_data_section_val_(uintptr_t *d, int *id, const char *dir, mreal *val,int); /// Get contour lines for dat[i,j]=val. NAN values separate the the curves HMDT mgl_data_conts(mreal val, HCDT dat); /// Equidistantly fill the data to range [x1,x2] in direction dir void MGL_EXPORT mgl_data_fill(HMDT dat, mreal x1,mreal x2,char dir); void MGL_EXPORT mgl_data_fill_(uintptr_t *dat, mreal *x1,mreal *x2,const char *dir,int); /// Modify the data by specified formula assuming x,y,z in range [r1,r2] void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT dat, const char *eq, HCDT vdat, HCDT wdat,const char *opt); void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,const char *opt, int, int); /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] using global spline void MGL_EXPORT mgl_data_refill_gs(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl); void MGL_EXPORT mgl_data_refill_gs_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl); /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] void MGL_EXPORT mgl_data_refill_x(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl); void MGL_EXPORT mgl_data_refill_x_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl); /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in range [x1,x2]*[y1,y2] void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl); void MGL_EXPORT mgl_data_refill_xy_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, long *sl); /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [x1,x2]*[y1,y2]*[z1,z2] void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2); void MGL_EXPORT mgl_data_refill_xyz_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2); /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range void MGL_EXPORT mgl_data_refill_gr(HMGL gr, HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, long sl, const char *opt); void MGL_EXPORT mgl_data_refill_gr_(uintptr_t *gr, uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, long *sl, const char *opt,int); /// Set the data by triangulated surface values assuming x,y,z in range [r1,r2] void MGL_EXPORT mgl_data_grid(HMGL gr, HMDT d, HCDT xdat, HCDT ydat, HCDT zdat,const char *opt); void MGL_EXPORT mgl_data_grid_(uintptr_t *gr, uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, const char *opt,int); /// Set the data by triangulated surface values assuming x,y,z in range [x1,x2]*[y1,y2] void MGL_EXPORT mgl_data_grid_xy(HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, mreal x1, mreal x2, mreal y1, mreal y2); void MGL_EXPORT mgl_data_grid_xy_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2); /// Put value to data element(s) void MGL_EXPORT mgl_data_put_val(HMDT dat, mreal val, long i, long j, long k); void MGL_EXPORT mgl_data_put_val_(uintptr_t *dat, mreal *val, int *i, int *j, int *k); /// Put array to data element(s) void MGL_EXPORT mgl_data_put_dat(HMDT dat, HCDT val, long i, long j, long k); void MGL_EXPORT mgl_data_put_dat_(uintptr_t *dat, uintptr_t *val, int *i, int *j, int *k); /// Modify the data by specified formula void MGL_EXPORT mgl_data_modify(HMDT dat, const char *eq,long dim); void MGL_EXPORT mgl_data_modify_(uintptr_t *dat, const char *eq,int *dim,int); /// Modify the data by specified formula void MGL_EXPORT mgl_data_modify_vw(HMDT dat, const char *eq,HCDT vdat,HCDT wdat); void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,int); /// Reduce size of the data void MGL_EXPORT mgl_data_squeeze(HMDT dat, long rx,long ry,long rz,long smooth); void MGL_EXPORT mgl_data_squeeze_(uintptr_t *dat, int *rx,int *ry,int *rz,int *smooth); /// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A /** NOTE: A.nx must be >= 7. */ HMDT MGL_EXPORT mgl_data_ifs_2d(HCDT A, long n, long skip); uintptr_t MGL_EXPORT mgl_data_ifs_2d_(uintptr_t *A, long *n, long *skip); /// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A /** NOTE: A.nx must be >= 13. */ HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip); uintptr_t MGL_EXPORT mgl_data_ifs_3d_(uintptr_t *A, long *n, long *skip); /// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) defined in *.ifs file 'fname' and named as 'name' HMDT MGL_EXPORT mgl_data_ifs_file(const char *fname, const char *name, long n, long skip); uintptr_t mgl_data_ifs_file_(const char *fname, const char *name, long *n, long *skip,int l,int m); /// Codes for flame fractal functions enum { mglFlame2d_linear=0, mglFlame2d_sinusoidal, mglFlame2d_spherical, mglFlame2d_swirl, mglFlame2d_horseshoe, mglFlame2d_polar, mglFlame2d_handkerchief,mglFlame2d_heart, mglFlame2d_disc, mglFlame2d_spiral, mglFlame2d_hyperbolic, mglFlame2d_diamond, mglFlame2d_ex, mglFlame2d_julia, mglFlame2d_bent, mglFlame2d_waves, mglFlame2d_fisheye, mglFlame2d_popcorn, mglFlame2d_exponential, mglFlame2d_power, mglFlame2d_cosine, mglFlame2d_rings, mglFlame2d_fan, mglFlame2d_blob, mglFlame2d_pdj, mglFlame2d_fan2, mglFlame2d_rings2, mglFlame2d_eyefish, mglFlame2d_bubble, mglFlame2d_cylinder, mglFlame2d_perspective, mglFlame2d_noise, mglFlame2d_juliaN, mglFlame2d_juliaScope, mglFlame2d_blur, mglFlame2d_gaussian, mglFlame2d_radialBlur, mglFlame2d_pie, mglFlame2d_ngon, mglFlame2d_curl, mglFlame2d_rectangles, mglFlame2d_arch, mglFlame2d_tangent, mglFlame2d_square, mglFlame2d_blade, mglFlame2d_secant, mglFlame2d_rays, mglFlame2d_twintrian, mglFlame2d_cross, mglFlame2d_disc2, mglFlame2d_supershape, mglFlame2d_flower, mglFlame2d_conic, mglFlame2d_parabola, mglFlame2d_bent2, mglFlame2d_bipolar, mglFlame2d_boarders, mglFlame2d_butterfly, mglFlame2d_cell, mglFlame2d_cpow, mglFlame2d_curve, mglFlame2d_edisc, mglFlame2d_elliptic, mglFlame2d_escher, mglFlame2d_foci, mglFlame2d_lazySusan, mglFlame2d_loonie, mglFlame2d_preBlur, mglFlame2d_modulus, mglFlame2d_oscope, mglFlame2d_polar2, mglFlame2d_popcorn2, mglFlame2d_scry, mglFlame2d_separation, mglFlame2d_split, mglFlame2d_splits, mglFlame2d_stripes, mglFlame2d_wedge, mglFlame2d_wedgeJulia, mglFlame2d_wedgeSph, mglFlame2d_whorl, mglFlame2d_waves2, mglFlame2d_exp, mglFlame2d_log, mglFlame2d_sin, mglFlame2d_cos, mglFlame2d_tan, mglFlame2d_sec, mglFlame2d_csc, mglFlame2d_cot, mglFlame2d_sinh, mglFlame2d_cosh, mglFlame2d_tanh, mglFlame2d_sech, mglFlame2d_csch, mglFlame2d_coth, mglFlame2d_auger, mglFlame2d_flux, mglFlame2dLAST }; /// Get array which is n-th pairs {x[i],y[i]} for Flame fractal generated by A with functions F /** NOTE: A.nx must be >= 7 and F.nx >= 2 and F.nz=A.ny. * F[0,i,j] denote function id. F[1,i,j] give function weight. F(2:5,i,j) provide function parameters. * Resulting point is {xnew,ynew} = sum_i F[1,i,j]*F[0,i,j]{IFS2d(A[j]){x,y}}. */ HMDT MGL_EXPORT mgl_data_flame_2d(HCDT A, HCDT F, long n, long skip); uintptr_t MGL_EXPORT mgl_data_flame_2d_(uintptr_t *A, uintptr_t *F, long *n, long *skip); /// Get curves, separated by NAN, for maximal values of array d as function of x coordinate. /** Noises below lvl amplitude are ignored. * Parameter dy \in [0,ny] set the "attraction" distance of points to curve. */ HMDT MGL_EXPORT mgl_data_detect(HCDT d, mreal lvl, mreal dj, mreal di, mreal min_len); uintptr_t MGL_EXPORT mgl_data_detect_(uintptr_t *d, mreal *lvl, mreal *dj, mreal *di, mreal *min_len); /// Get array as solution of tridiagonal matrix solution a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i] /** String \a how may contain: * 'x', 'y', 'z' for solving along x-,y-,z-directions, or * 'h' for solving along hexagonal direction at x-y plain (need nx=ny), * 'c' for using periodical boundary conditions, * 'd' for diffraction/diffuse calculation. * NOTE: It work for flat data model only (i.e. for a[i,j]==a[i+nx*j]) */ HMDT MGL_EXPORT mgl_data_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how); uintptr_t MGL_EXPORT mgl_data_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int); /// Returns pointer to data element [i,j,k] MGL_EXPORT mreal *mgl_data_value(HMDT dat, long i,long j,long k); /// Returns pointer to internal data array MGL_EXPORT_PURE mreal *mgl_data_data(HMDT dat); /// Gets the x-size of the data. long MGL_EXPORT mgl_data_get_nx(HCDT d); long MGL_EXPORT mgl_data_get_nx_(uintptr_t *d); /// Gets the y-size of the data. long MGL_EXPORT mgl_data_get_ny(HCDT d); long MGL_EXPORT mgl_data_get_ny_(uintptr_t *d); /// Gets the z-size of the data. long MGL_EXPORT mgl_data_get_nz(HCDT d); long MGL_EXPORT mgl_data_get_nz_(uintptr_t *d); /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on) HMDT MGL_EXPORT mgl_data_combine(HCDT dat1, HCDT dat2); uintptr_t MGL_EXPORT mgl_data_combine_(uintptr_t *dat1, uintptr_t *dat2); /// Extend data dimensions void MGL_EXPORT mgl_data_extend(HMDT dat, long n1, long n2); void MGL_EXPORT mgl_data_extend_(uintptr_t *dat, int *n1, int *n2); /// Insert data rows/columns/slices void MGL_EXPORT mgl_data_insert(HMDT dat, char dir, long at, long num); void MGL_EXPORT mgl_data_insert_(uintptr_t *dat, const char *dir, int *at, int *num, int); /// Delete data rows/columns/slices void MGL_EXPORT mgl_data_delete(HMDT dat, char dir, long at, long num); void MGL_EXPORT mgl_data_delete_(uintptr_t *dat, const char *dir, int *at, int *num, int); /// Joind another data array void MGL_EXPORT mgl_data_join(HMDT dat, HCDT d); void MGL_EXPORT mgl_data_join_(uintptr_t *dat, uintptr_t *d); /// Smooth the data on specified direction or directions /** String \a dir may contain: * ‘x’, ‘y’, ‘z’ for 1st, 2nd or 3d dimension; * ‘dN’ for linear averaging over N points; * ‘3’ for linear averaging over 3 points; * ‘5’ for linear averaging over 5 points. * By default quadratic averaging over 5 points is used. */ void MGL_EXPORT mgl_data_smooth(HMDT d, const char *dirs, mreal delta); void MGL_EXPORT mgl_data_smooth_(uintptr_t *dat, const char *dirs, mreal *delta,int); /// Get array which is result of summation in given direction or directions HMDT MGL_EXPORT mgl_data_sum(HCDT dat, const char *dir); uintptr_t MGL_EXPORT mgl_data_sum_(uintptr_t *dat, const char *dir,int); /// Get array which is result of maximal values in given direction or directions HMDT MGL_EXPORT mgl_data_max_dir(HCDT dat, const char *dir); uintptr_t MGL_EXPORT mgl_data_max_dir_(uintptr_t *dat, const char *dir,int); /// Get array which is result of minimal values in given direction or directions HMDT MGL_EXPORT mgl_data_min_dir(HCDT dat, const char *dir); uintptr_t MGL_EXPORT mgl_data_min_dir_(uintptr_t *dat, const char *dir,int); /// Get positions of local maximums and minimums HMDT MGL_EXPORT mgl_data_minmax(HCDT dat); uintptr_t MGL_EXPORT mgl_data_minmax_(uintptr_t *dat); /// Get indexes of a set of connected surfaces for set of values {a_ijk,b_ijk} as dependent on j,k /** NOTE: not optimized for general case!!! */ HMDT MGL_EXPORT mgl_data_connect(HCDT a, HCDT b); uintptr_t MGL_EXPORT mgl_data_connect_(uintptr_t *a, uintptr_t *b); /// Resort data values according found connected surfaces for set of values {a_ijk,b_ijk} as dependent on j,k /** NOTE: not optimized for general case!!! */ void MGL_EXPORT mgl_data_connect_r(HMDT a, HMDT b); void MGL_EXPORT mgl_data_connect_r_(uintptr_t *a, uintptr_t *b); /// Cumulative summation the data in given direction or directions void MGL_EXPORT mgl_data_cumsum(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_cumsum_(uintptr_t *dat, const char *dir,int); /// Integrate (cumulative summation) the data in given direction or directions void MGL_EXPORT mgl_data_integral(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_integral_(uintptr_t *dat, const char *dir,int); /// Differentiate the data in given direction or directions void MGL_EXPORT mgl_data_diff(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_diff_(uintptr_t *dat, const char *dir,int); /// Differentiate the parametrically specified data along direction v1 with v2,v3=const (v3 can be NULL) void MGL_EXPORT mgl_data_diff_par(HMDT dat, HCDT v1, HCDT v2, HCDT v3); void MGL_EXPORT mgl_data_diff_par_(uintptr_t *dat, uintptr_t *v1, uintptr_t *v2, uintptr_t *v3); /// Double-differentiate (like Laplace operator) the data in given direction void MGL_EXPORT mgl_data_diff2(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_diff2_(uintptr_t *dat, const char *dir,int); /// Swap left and right part of the data in given direction (useful for Fourier spectrum) void MGL_EXPORT mgl_data_swap(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_swap_(uintptr_t *dat, const char *dir,int); /// Roll data along direction dir by num slices void MGL_EXPORT mgl_data_roll(HMDT dat, char dir, long num); void MGL_EXPORT mgl_data_roll_(uintptr_t *dat, const char *dir, int *num, int); /// Mirror the data in given direction (useful for Fourier spectrum) void MGL_EXPORT mgl_data_mirror(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_mirror_(uintptr_t *dat, const char *dir,int); /// Sort rows (or slices) by values of specified column void MGL_EXPORT mgl_data_sort(HMDT dat, long idx, long idy); void MGL_EXPORT mgl_data_sort_(uintptr_t *dat, int *idx, int *idy); /// Return dilated array of 0 or 1 for data values larger val void MGL_EXPORT mgl_data_dilate(HMDT dat, mreal val, long step); void MGL_EXPORT mgl_data_dilate_(uintptr_t *dat, mreal *val, int *step); /// Return eroded array of 0 or 1 for data values larger val void MGL_EXPORT mgl_data_erode(HMDT dat, mreal val, long step); void MGL_EXPORT mgl_data_erode_(uintptr_t *dat, mreal *val, int *step); /// Apply Hankel transform void MGL_EXPORT mgl_data_hankel(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_hankel_(uintptr_t *dat, const char *dir,int); /// Apply Sin-Fourier transform void MGL_EXPORT mgl_data_sinfft(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_sinfft_(uintptr_t *dat, const char *dir,int); /// Apply Cos-Fourier transform void MGL_EXPORT mgl_data_cosfft(HMDT dat, const char *dir); void MGL_EXPORT mgl_data_cosfft_(uintptr_t *dat, const char *dir,int); /// Fill data by coordinates/momenta samples for Hankel ('h') or Fourier ('f') transform /** Parameter \a how may contain: * ‘x‘,‘y‘,‘z‘ for direction (only one will be used), * ‘k‘ for momenta samples, * ‘h‘ for Hankel samples, * ‘f‘ for Cartesian/Fourier samples (default). */ void MGL_EXPORT mgl_data_fill_sample(HMDT dat, const char *how); void MGL_EXPORT mgl_data_fill_sample_(uintptr_t *dat, const char *how,int); /// Find correlation between 2 data arrays HMDT MGL_EXPORT mgl_data_correl(HCDT dat1, HCDT dat2, const char *dir); uintptr_t MGL_EXPORT mgl_data_correl_(uintptr_t *dat1, uintptr_t *dat2, const char *dir,int); /// Apply wavelet transform /** Parameter \a dir may contain: * ‘x‘,‘y‘,‘z‘ for directions, * ‘d‘ for daubechies, ‘D‘ for centered daubechies, * ‘h‘ for haar, ‘H‘ for centered haar, * ‘b‘ for bspline, ‘B‘ for centered bspline, * ‘i‘ for applying inverse transform. */ void MGL_EXPORT mgl_data_wavelet(HMDT dat, const char *how, int k); void MGL_EXPORT mgl_data_wavelet_(uintptr_t *d, const char *dir, int *k,int); /// Allocate and prepare data for Fourier transform by nthr threads MGL_EXPORT void *mgl_fft_alloc(long n, void **space, long nthr); MGL_EXPORT void *mgl_fft_alloc_thr(long n); /// Free data for Fourier transform void MGL_EXPORT mgl_fft_free(void *wt, void **ws, long nthr); void MGL_EXPORT mgl_fft_free_thr(void *wt); /// Make Fourier transform of data x of size n and step s between points void MGL_EXPORT mgl_fft(double *x, long s, long n, const void *wt, void *ws, int inv); /// Clear internal data for speeding up FFT and Hankel transforms void MGL_EXPORT mgl_clear_fft(); /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] mreal MGL_EXPORT mgl_data_spline(HCDT dat, mreal x,mreal y,mreal z); mreal MGL_EXPORT mgl_data_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z); /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] mreal MGL_EXPORT mgl_data_spline_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz); mreal MGL_EXPORT mgl_data_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz); /// Prepare coefficients for global spline interpolation HMDT MGL_EXPORT mgl_gspline_init(HCDT x, HCDT v); uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v); /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef mreal MGL_EXPORT mgl_gspline(HCDT coef, mreal dx, mreal *d1, mreal *d2); mreal MGL_EXPORT mgl_gspline_(uintptr_t *c, mreal *dx, mreal *d1, mreal *d2); /// Return an approximated x-value (root) when dat(x) = val mreal MGL_EXPORT mgl_data_solve_1d(HCDT dat, mreal val, int spl, long i0); mreal MGL_EXPORT mgl_data_solve_1d_(uintptr_t *dat, mreal *val, int *spl, int *i0); /// Return an approximated value (root) when dat(x) = val HMDT MGL_EXPORT mgl_data_solve(HCDT dat, mreal val, char dir, HCDT i0, int norm); uintptr_t MGL_EXPORT mgl_data_solve_(uintptr_t *dat, mreal *val, const char *dir, uintptr_t *i0, int *norm,int); /// Get trace of the data array HMDT MGL_EXPORT mgl_data_trace(HCDT d); uintptr_t MGL_EXPORT mgl_data_trace_(uintptr_t *d); /// Resize the data to new sizes HMDT MGL_EXPORT mgl_data_resize(HCDT dat, long mx,long my,long mz); uintptr_t MGL_EXPORT mgl_data_resize_(uintptr_t *dat, int *mx,int *my,int *mz); /// Resize the data to new sizes of box [x1,x2]*[y1,y2]*[z1,z2] HMDT MGL_EXPORT mgl_data_resize_box(HCDT dat, long mx,long my,long mz,mreal x1,mreal x2,mreal y1,mreal y2,mreal z1,mreal z2); uintptr_t MGL_EXPORT mgl_data_resize_box_(uintptr_t *dat, int *mx,int *my,int *mz,mreal *x1,mreal *x2,mreal *y1,mreal *y2,mreal *z1,mreal *z2); /// Create n-th points distribution of this data values in range [v1, v2] HMDT MGL_EXPORT mgl_data_hist(HCDT dat, long n, mreal v1, mreal v2, long nsub); uintptr_t MGL_EXPORT mgl_data_hist_(uintptr_t *dat, int *n, mreal *v1, mreal *v2, int *nsub); /// Create n-th points distribution of this data values in range [v1, v2] with weight w HMDT MGL_EXPORT mgl_data_hist_w(HCDT dat, HCDT weight, long n, mreal v1, mreal v2, long nsub); uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *dat, uintptr_t *weight, int *n, mreal *v1, mreal *v2, int *nsub); /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on. HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how); uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *dat, char *dir, const char *how, int,int); /// Get pulse properties: pulse maximum and its position, pulse duration near maximum and by half height. HMDT MGL_EXPORT mgl_data_pulse(HCDT dat, char dir); uintptr_t MGL_EXPORT mgl_data_pulse_(uintptr_t *dat, char *dir,int); /// Get array which values is result of interpolation this for coordinates from other arrays HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm); uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *dat, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm); /// Set as the data envelop void MGL_EXPORT mgl_data_envelop(HMDT dat, char dir); void MGL_EXPORT mgl_data_envelop_(uintptr_t *dat, const char *dir, int); /// Remove phase jump void MGL_EXPORT mgl_data_sew(HMDT dat, const char *dirs, mreal da); void MGL_EXPORT mgl_data_sew_(uintptr_t *dat, const char *dirs, mreal *da, int); /// Crop the data void MGL_EXPORT mgl_data_crop(HMDT dat, long n1, long n2, char dir); void MGL_EXPORT mgl_data_crop_(uintptr_t *dat, int *n1, int *n2, const char *dir,int); /// Crop the data to be most optimal for FFT (i.e. to closest value of 2^n*3^m*5^l) void MGL_EXPORT mgl_data_crop_opt(HMDT dat, const char *how); void MGL_EXPORT mgl_data_crop_opt_(uintptr_t *dat, const char *how,int); /// Remove rows with duplicate values in column id void MGL_EXPORT mgl_data_clean(HMDT dat, long id); void MGL_EXPORT mgl_data_clean_(uintptr_t *dat, int *id); /// Multiply the data by other one for each element void MGL_EXPORT mgl_data_mul_dat(HMDT dat, HCDT d); void MGL_EXPORT mgl_data_mul_dat_(uintptr_t *dat, uintptr_t *d); /// Divide the data by other one for each element void MGL_EXPORT mgl_data_div_dat(HMDT dat, HCDT d); void MGL_EXPORT mgl_data_div_dat_(uintptr_t *dat, uintptr_t *d); /// Add the other data void MGL_EXPORT mgl_data_add_dat(HMDT dat, HCDT d); void MGL_EXPORT mgl_data_add_dat_(uintptr_t *dat, uintptr_t *d); /// Subtract the other data void MGL_EXPORT mgl_data_sub_dat(HMDT dat, HCDT d); void MGL_EXPORT mgl_data_sub_dat_(uintptr_t *dat, uintptr_t *d); /// Multiply each element by the number void MGL_EXPORT mgl_data_mul_num(HMDT dat, mreal d); void MGL_EXPORT mgl_data_mul_num_(uintptr_t *dat, mreal *d); /// Divide each element by the number void MGL_EXPORT mgl_data_div_num(HMDT dat, mreal d); void MGL_EXPORT mgl_data_div_num_(uintptr_t *dat, mreal *d); /// Add the number void MGL_EXPORT mgl_data_add_num(HMDT dat, mreal d); void MGL_EXPORT mgl_data_add_num_(uintptr_t *dat, mreal *d); /// Subtract the number void MGL_EXPORT mgl_data_sub_num(HMDT dat, mreal d); void MGL_EXPORT mgl_data_sub_num_(uintptr_t *dat, mreal *d); /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase HMDT MGL_EXPORT mgl_transform_a(HCDT am, HCDT ph, const char *tr); uintptr_t MGL_EXPORT mgl_transform_a_(uintptr_t *am, uintptr_t *ph, const char *tr, int); /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for real and imaginary parts HMDT MGL_EXPORT mgl_transform(HCDT re, HCDT im, const char *tr); uintptr_t MGL_EXPORT mgl_transform_(uintptr_t *re, uintptr_t *im, const char *tr, int); /// Apply Fourier transform for the data and save result into it void MGL_EXPORT mgl_data_fourier(HMDT re, HMDT im, const char *dir); void MGL_EXPORT mgl_data_fourier_(uintptr_t *re, uintptr_t *im, const char *dir, int l); /// Short time Fourier analysis for real and imaginary parts. Output is amplitude of partial Fourier (result will have size {dn, floor(nx/dn), ny} for dir='x' HMDT MGL_EXPORT mgl_data_stfa(HCDT re, HCDT im, long dn, char dir); uintptr_t MGL_EXPORT mgl_data_stfa_(uintptr_t *re, uintptr_t *im, int *dn, char *dir, int); /// Do something like Delone triangulation for 3d points HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z); uintptr_t MGL_EXPORT mgl_triangulation_3d_(uintptr_t *x, uintptr_t *y, uintptr_t *z); /// Do Delone triangulation for 2d points HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y); uintptr_t MGL_EXPORT mgl_triangulation_2d_(uintptr_t *x, uintptr_t *y); /// Find root for nonlinear equation mreal MGL_EXPORT mgl_find_root(mreal (*func)(mreal val, void *par), mreal ini, void *par); /// Find root for nonlinear equation defined by textual formula mreal MGL_EXPORT mgl_find_root_txt(const char *func, mreal ini, char var_id); mreal MGL_EXPORT mgl_find_root_txt_(const char *func, mreal *ini, const char *var_id,int,int); /// Find roots for nonlinear equation defined by textual formula HMDT MGL_EXPORT mgl_data_roots(const char *func, HCDT ini, char var_id); uintptr_t MGL_EXPORT mgl_data_roots_(const char *func, uintptr_t *ini, const char *var_id,int,int); /// Find roots for set of nonlinear equations defined by textual formulas HMDT MGL_EXPORT mgl_find_roots_txt(const char *func, const char *vars, HCDT ini); uintptr_t MGL_EXPORT mgl_find_roots_txt_(const char *func, const char *vars, uintptr_t *ini,int,int); /// Find roots for set of nonlinear equations defined by function bool MGL_EXPORT mgl_find_roots(size_t n, void (*func)(const mreal *x, mreal *f, void *par), mreal *x0, void *par); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif #endif //----------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/window.h������������������������������������������������������������������0000644�0001750�0001750�00000006223�13513030041�017114� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * window.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_WINDOW_H_ #define _MGL_WINDOW_H_ #include "mgl2/qt.h" #include "mgl2/fltk.h" //#include "mgl2/wx.h" //----------------------------------------------------------------------------- /// Wrapper class for all windows displaying graphics class MGL_EXPORT mglWindow : public mglWnd { mglWindow(const mglWindow &t) {} // copying is not allowed const mglWindow &operator=(const mglWindow &t) { return t; } int wnd; ///< Type of window public: mglWindow(const char *title="MathGL") : mglWnd() { wnd=1; gr = mgl_create_graph_fltk(0,title,0,0); } mglWindow(int (*draw)(HMGL gr, void *p), const char *title="MathGL", void *par=NULL, int kind=0, void (*load)(void *p)=0) : mglWnd() { wnd=kind; if(wnd==1) gr = mgl_create_graph_qt(draw,title,par,load); else gr = mgl_create_graph_fltk(draw,title,par,load); } mglWindow(int (*draw)(mglGraph *gr), const char *title="MathGL", int kind=0) : mglWnd() { wnd=kind; if(wnd==1) gr = mgl_create_graph_qt(draw?mgl_draw_graph:0,title,(void*)draw,0); else gr = mgl_create_graph_fltk(draw?mgl_draw_graph:0,title,(void*)draw,0); } mglWindow(mglDraw *draw, const char *title="MathGL", int kind=0) : mglWnd() { wnd=kind; if(wnd==1) gr = mgl_create_graph_qt(draw?mgl_draw_class:0,title,draw,mgl_reload_class); else gr = mgl_create_graph_fltk(draw?mgl_draw_class:0,title,draw,mgl_reload_class); mgl_set_click_func(gr, mgl_click_class); } /// Run main loop for event handling int Run() { return wnd==0? mgl_fltk_run():mgl_qt_run(); } /// Run main loop for event handling in separate thread (for FLTK only) inline int RunThr() { return wnd==0 ? mgl_fltk_thr():0; } }; //----------------------------------------------------------------------------- #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/qmathgl.h�����������������������������������������������������������������0000644�0001750�0001750�00000030104�13513030041�017235� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * qmathgl.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_QMATHGL_H_ #define _MGL_QMATHGL_H_ //----------------------------------------------------------------------------- #include #include #include //----------------------------------------------------------------------------- class QTextEdit; class QMenu; class QMainWindow; class QScrollArea; class QSpinBox; class QTimer; class mglCanvas; class mglTask; //----------------------------------------------------------------------------- /// Class is Qt widget which display MathGL graphics class MGL_EXPORT QMathGL : public QWidget { Q_OBJECT public: QString appName; ///< Application name for message boxes bool autoResize; ///< Allow auto resizing (default is false) bool enableMouse; ///< Enable mouse handlers bool enableWheel; ///< Enable mouse wheel handlers QString primitives; ///< Manual primitives, defined by user mglCanvas *gr; ///< Built-in mglCanvas instance (mglCanvasQT is used by default) QMathGL(QWidget *parent = 0, Qt::WindowFlags f = 0); virtual ~QMathGL(); double getRatio(); void setPopup(QMenu *p) { popup = p; } ///< Set popup menu pointer void setSize(int w, int h); ///< Set window/picture sizes void setGraph(HMGL GR); ///< Set grapher object inline void setGraph(mglGraph *GR) { setGraph(GR->Self()); } inline HMGL getGraph() { return (HMGL)gr; } /// Set drawing functions and its parameter void setDraw(int (*func)(mglBase *gr, void *par), void *par); void setDraw(mglDraw *dr); inline void setDraw(int (*func)(mglGraph *gr)) { setDraw(func?mgl_draw_graph:0,(void*)func); } inline void zoomRegion(mreal xx1,mreal xx2,mreal yy1, mreal yy2) { x1=xx1; y1=yy1; x2=xx2; y2=yy2; } /// Get mglDraw pointer or NULL inline mglDraw *getClass() { mglDraw *d=0; if(draw_func==mgl_draw_class) d = (mglDraw*)draw_par; if(draw) d = draw; return d; } int getPer() const {return int(per);} ///< Get perspective value int getPhi() const {return int(phi);} ///< Get Phi-angle value int getTet() const {return int(tet);} ///< Get Theta-angle value bool getAlpha() const {return alpha;} ///< Get transparency state bool getLight() const {return light;} ///< Get lightning state bool getZoom() const {return zoom;} ///< Get mouse zooming state bool getRotate() const {return rotate;}///< Get mouse rotation state bool getViewYZ() const {return viewYZ;}///< Get mouse rotation axis bool getPause() const {return pause;} ///< Get calculation pause state bool isActive(int xs,int ys); ///< Check if active point is pressed public slots: void refresh(); ///< Redraw image with new zoom and view parameters void refreshHQ(); ///< Redraw image with HQ (can be slower than refresh()) void update(); ///< Update picture void copy(); ///< copy graphics to clipboard void copyClickCoor(); ///< copy click coordinates to clipboard void print(); ///< Print plot void stop(); ///< Stop execution void setPer(int p); ///< Set perspective value void setPhi(int p); ///< Set Phi-angle value void setTet(int t); ///< Set Theta-angle value void setAlpha(bool a); ///< Switch on/off transparency void setLight(bool l); ///< Switch on/off lightning void setGrid(bool r); ///< Switch on/off grid drawing void imgSize(int w, int h); ///< Set image size void setViewYZ(bool v); ///< Switch on/off rotation around Y and Z axis void setDotsPreview(bool d=true); ///< Set to use dots for image preview/rotation void setCustZoom(bool a); ///< Switch on/off using custom zoom void setCustDraw(bool a); ///< Switch on/off using custom draw void setZoom(bool z); ///< Switch on/off mouse zooming void setRotate(bool r); ///< Switch on/off mouse rotation void setPause(bool p); ///< Switch on/off calculation pause void zoomIn(); ///< Zoom in graphics void zoomOut(); ///< Zoom out graphics void restore(); ///< Restore zoom and rotation to default values void setZoomScl(double s=0.5); ///< Set factor for zooming (must be s>0) void setShiftScl(double s=0.25); ///< Set factor for shifting (must be s!=0) // void reload(); ///< Reload data and execute script void shiftLeft(); ///< Shift graphics to left direction void shiftRight(); ///< Shift graphics to right direction void shiftUp(); ///< Shift graphics to up direction void shiftDown(); ///< Shift graphics to down direction void exportPNG(QString fname=""); ///< export to PNG file void exportPNGs(QString fname=""); ///< export to PNG file (no transparency) void exportGIF(QString fname=""); ///< export to GIF file void exportJPG(QString fname=""); ///< export to JPEG file void exportBPS(QString fname=""); ///< export to bitmap EPS file void exportEPS(QString fname=""); ///< export to vector EPS file void exportSVG(QString fname=""); ///< export to SVG file void exportTEX(QString fname=""); ///< export to SVG file void exportTGA(QString fname=""); ///< export to TGA file void exportXYZ(QString fname=""); ///< export to XYZ file void exportOBJ(QString fname=""); ///< export to OBJ file void exportSTL(QString fname=""); ///< export to STL file void exportOFF(QString fname=""); ///< export to OFF file // void exportX3D(QString fname=""); ///< export to XYZ file void exportPRC(QString fname=""); ///< export to PRC file void exportMGLD(QString fname=""); ///< export to MGLD file void setMGLFont(QString path); ///< restore/load font for graphics void addMark(); ///< add marker into primitives void addLine(); ///< add line into primitives void addRect(); ///< add rectangle into primitives void addCurve(); ///< add curve into primitives void addRhomb(); ///< add rhombus into primitives void addEllipse(); ///< add ellipse into primitives void addArc(); ///< add arc into primitives void addPolygon(int n=-1); ///< add polygon into primitives void addText(QString txt=""); ///< add text into primitives void setStyle(int id, QString stl);///< set style for primitive with id void adjust(); ///< Adjust plot size to fill entire window void nextSlide(); ///< Show next slide void prevSlide(); ///< Show previous slide void animation(bool st=true); ///< Start animation void about(); ///< Show about information void aboutQt(); ///< Show information about Qt version signals: void gridChanged(int); ///< Grid drawing changed (by mouse or by toolbar) void phiChanged(int); ///< Phi angle changed (by mouse or by toolbar) void tetChanged(int); ///< Tet angle changed (by mouse or by toolbar) void perChanged(int); ///< Perspective changed (by mouse or by toolbar) void alphaChanged(bool); ///< Transparency changed (by toolbar) void lightChanged(bool); ///< Lighting changed (by toolbar) void zoomChanged(bool); ///< Zooming changed (by toolbar) void rotateChanged(bool); ///< Rotation changed (by toolbar) void pauseChanged(bool); ///< Pause changed (by toolbar) void usePrimChanged(bool); ///< Use primitive changed (i.e. have or not drawing function) void viewYZChanged(bool); ///< Rotation axis changed (by toolbar) void mouseClick(mreal,mreal,mreal); ///< Position of mouse click void frameChanged(int); ///< Need another frame to show void showWarn(QString); ///< Show warnings void posChanged(QString message); ///< user click to show mouse position void objChanged(int objId); ///< User click to select object/line void refreshData(); void doubleClick(int id); ///< Double mouse click by object with id void askStyle(int id); ///< Update style /// user can define its own zooming function void customZoom(double x1, double y1, double x2, double y2, double tet, double phi, double per); /// user can define its own drawing/setting function which will be called before main drawing void customDraw(double x1, double y1, double x2, double y2, bool draw); protected: void paintEvent(QPaintEvent *); void resizeEvent(QResizeEvent *); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void wheelEvent(QWheelEvent *); void mouseDoubleClickEvent(QMouseEvent *); void *draw_par; ///< Parameters for drawing function mglCanvasWnd::DrawFunc. /// Drawing function for window procedure. It should return the number of frames. int (*draw_func)(mglBase *gr, void *par); mglDraw *draw; ///< Class for drawing -- need to call directly due to inheritance mechanism QString mousePos; ///< Last mouse position QPixmap pic; ///< Pixmap for drawing (changed by update) QImage img; ///< Last used HQ image double tet, phi; ///< Rotation angles double per; ///< Value of perspective ( must be in [0,1) ) bool alpha; ///< Transparency state bool light; ///< Lightning state bool pause; ///< Pause state bool custZoom; ///< Use custom zoom instead of built in bool custDraw; ///< Use custom draw before main drawing bool zoom; ///< Mouse zoom state bool grid; ///< Grid drawing state bool rotate; ///< Mouse rotation state bool viewYZ; ///< Set mouse rotation around Y and Z axis (instead of X and Z) bool dotsRefr; ///< Set dots for image preview/rotation mreal x1,x2,y1,y2; ///< Zoom in region mreal ax1,ax2,ay1,ay2; ///< Axis range zoom QMenu *popup; ///< Pointer to pop-up menu QTimer *timer; ///< Timer for animation QTimer *timerRefr; ///< Timer for redrawing private slots: void afterPlot(); ///< minor tuning after plot was done private: int x0, y0, xe, ye; ///< Temporary variables for mouse double sclZ; ///< Scale factor for zooming double sclS; ///< Scale factor for shifting uchar *grBuf; void drawPrim(); int prevQuality; // QThread *thread; // mglTask *task; }; //----------------------------------------------------------------------------- /// Class for drawing the MGL script class MGL_EXPORT mglDrawScript : public mglDraw { public: HMPR par; ///< Parser to be used QString text; ///< Script to be drawn long line; ///< Line which will be highlighted mglDrawScript(HMPR p):mglDraw() { par=p; line=-1; } virtual ~mglDrawScript() {} int Draw(mglGraph *gr) { wchar_t *wtext; wtext = new wchar_t[text.size()+1]; text.toWCharArray(wtext); wtext[text.size()] = 0; gr->Highlight(line + 1); mgl_parse_textw(gr->Self(), par, wtext); delete[] wtext; return 0; } }; //----------------------------------------------------------------------------- /// Convert bitmap from mglCanvasWnd to QPixmap void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf, QImage *out=NULL); /// Make menu, toolbars and return popup menu for MainWindow MGL_EXPORT QMenu *mglMakeMenu(QMainWindow* Wnd, QMathGL* QMGL, QSpinBox*& tet, QSpinBox*& phi); //----------------------------------------------------------------------------- #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/thread.h������������������������������������������������������������������0000644�0001750�0001750�00000010354�13513030041�017054� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * thread.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_THREAD_H_ #define _MGL_THREAD_H_ #include "mgl2/define.h" //----------------------------------------------------------------------------- #if MGL_HAVE_PTHREAD #include #endif //----------------------------------------------------------------------------- struct mglThreadD { mreal *a; // float* array with parameters or results const mreal *b,*c,*d,*e; // float* arrays with parameters const long *p; // long* array with parameters const void *v; // pointer to data/grapher int id; // thread id long n; // total number of iteration const char *s; }; struct mglThreadC { dual *a; // dual* array with parameters or results const dual *b,*c,*d,*e; // dual* arrays with parameters const long *p; // long* array with parameters const void *v; // pointer to data/grapher int id; // thread id long n; // total number of iteration const char *s; }; struct mglThreadV { mreal *a; // float* array with parameters or results dual *aa; // dual* array with parameters or results const void *b,*c; // float* arrays with parameters const mreal *d; // float* arrays with parameters const long *p; // long* array with parameters const void *v; // pointer to data/grapher int id; // thread id long n; // total number of iteration }; struct mglThreadT { void *a; // dual* or mreal* array with input or results double *b; // dual* array with input or results const long *p; // long* array with parameters const void *v; // pointer to table/parameter void **w; // pointer to workspace int id; // thread id long n; // total number of iteration const void *re,*im; }; /// Start several thread for the task void MGL_EXPORT mglStartThread(void *(*func)(void *), void (*post)(mglThreadD *,mreal *), long n, mreal *a=0, const mreal *b=0, const mreal *c=0, const long *p=0, const void *v=0, const mreal *d=0, const mreal *e=0, const char *s=0); void MGL_EXPORT mglStartThreadV(void *(*func)(void *), long n, mreal *a, const void *b=0, const void *c=0, const long *p=0, const void *v=0, const mreal *d=0); void MGL_EXPORT mglStartThreadV(void *(*func)(void *), long n, dual *a, const void *b=0, const void *c=0, const long *p=0, const void *v=0, const mreal *d=0); void MGL_EXPORT mglStartThreadC(void *(*func)(void *), void (*post)(mglThreadC *,dual *), long n, dual *a=0, const dual *b=0, const dual *c=0, const long *p=0, const void *v=0, const dual *d=0, const dual *e=0, const char *s=0); void MGL_EXPORT mglStartThreadT(void *(*func)(void *), long n, void *a, double *b, const void *v=0, void **w=0, const long *p=0, const void *re=0, const void *im=0); MGL_EXPORT extern int mglNumThr; ///< Number of thread for plotting and data handling //----------------------------------------------------------------------------- #endif //----------------------------------------------------------------------------- ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/fltk.h��������������������������������������������������������������������0000644�0001750�0001750�00000007407�13513030041�016552� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * fltk.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_FLTK_H_ #define _MGL_FLTK_H_ #include //----------------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif /// Creates FLTK window for plotting HMGL MGL_EXPORT mgl_create_graph_fltk(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p)); uintptr_t MGL_EXPORT mgl_create_graph_fltk_(const char *title, int); /// Run main FLTK loop for event handling. int MGL_EXPORT mgl_fltk_run(); int MGL_EXPORT mgl_fltk_run_(); /// Run main FLTK loop for event handling in separate thread. int MGL_EXPORT mgl_fltk_thr(); /// FLTK function for asking user. void MGL_EXPORT mgl_ask_fltk(const wchar_t *quest, wchar_t *res); /// FLTK function for displaying progress of something. void MGL_EXPORT mgl_progress_fltk(int value, int maximal, HMGL gr); /// Return pointer to widget (Fl_MGLView*) used for plotting MGL_EXPORT_PURE void *mgl_fltk_widget(HMGL gr); #ifdef __cplusplus } //----------------------------------------------------------------------------- #include //----------------------------------------------------------------------------- /// Wrapper class for windows displaying graphics class MGL_EXPORT mglFLTK : public mglWnd { mglFLTK(const mglFLTK &) {} // copying is not allowed const mglFLTK &operator=(const mglFLTK &t) { return t; } public: mglFLTK(const char *title="MathGL") : mglWnd() { gr = mgl_create_graph_fltk(0,title,0,0); } mglFLTK(int (*draw)(HMGL gr, void *p), const char *title="MathGL", void *par=NULL, void (*load)(void *p)=0) : mglWnd() { gr = mgl_create_graph_fltk(draw,title,par,load); } mglFLTK(int (*draw)(mglGraph *gr), const char *title="MathGL") : mglWnd() { gr = mgl_create_graph_fltk(draw?mgl_draw_graph:0,title,(void*)draw,0); } mglFLTK(mglDraw *draw, const char *title="MathGL") : mglWnd() { gr = mgl_create_graph_fltk(draw?mgl_draw_class:0,title,draw,mgl_reload_class); #if MGL_HAVE_PTHR_WIDGET mgl_wnd_set_mutex(gr, &(draw->mutex)); #endif mgl_set_click_func(gr, mgl_click_class); } virtual ~mglFLTK() {} int Run() { return mgl_fltk_run(); } ///< Run main loop for event handling int RunThr() { return mgl_fltk_thr(); } ///< Run main loop for event handling in separate thread }; //----------------------------------------------------------------------------- #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/addon.h�������������������������������������������������������������������0000644�0001750�0001750�00000007041�13513030041�016671� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * addon.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_ADDON_H_ #define _MGL_ADDON_H_ //----------------------------------------------------------------------------- #include "mgl2/define.h" #ifdef __cplusplus //----------------------------------------------------------------------------- /// Explicit scheme for 1 step of axial diffraction void MGL_EXPORT mgl_difr_axial(dual *a,int n,int step,dual q,int Border,dual *tmp,int kk, double di); void MGL_EXPORT mgl_difr_axial_old(dual *a,int n,int step,dual q,int Border,dual *tmp1,dual *tmp2,int kk, double di); // restore for backward compatibility /// Explicit scheme for 1 step of plane diffraction void MGL_EXPORT mgl_difr_grid(dual *a,int n,int step,dual q,int Border,dual *tmp,int kk); void MGL_EXPORT mgl_difr_grid_old(dual *a,int n,int step,dual q,int Border,dual *tmp1,dual *tmp2,int kk); // restore for backward compatibility //----------------------------------------------------------------------------- extern "C" { #endif /// Get random number with Gaussian distribution double MGL_EXPORT mgl_gauss_rnd(); /// Fill frequencies for FFT void MGL_EXPORT mgl_fft_freq(double *freq,long nn); /// Remove double spaces from the string void MGL_EXPORT mgl_strcls(char *str); /// Get position of substring or return -1 if not found long MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd); /// Get position of symbol or return -1 if not found long MGL_EXPORT_PURE mgl_chrpos(const char *str,char fnd); /// Get uncommented string from file (NOTE: it is not thread safe!!!) MGL_EXPORT char *mgl_fgetstr(FILE *fp); /// Get parameters from uncommented strings of file (NOTE: it is not thread safe!!!) void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...); /// Check if symbol denote true int MGL_EXPORT_CONST mgl_istrue(char ch); /// Print test message void MGL_EXPORT mgl_test(const char *str, ...); /// Print info message void MGL_EXPORT mgl_info(const char *str, ...); /// Locate next data block (block started by -----) MGL_EXPORT FILE *mgl_next_data(const char *fname,int p); /// Enable executing MGL script if mgl_fgetstr() meet '#MGL fname.mgl [args]. Default value is 0 (false). void MGL_EXPORT mgl_fgetstr_mgl(int enable); #ifdef __cplusplus } #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/mgl2/mathgl.fs�����������������������������������������������������������������0000644�0001750�0001750�00000136136�13513030041�017251� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Module mathgl also dos library libmgl libmgl.so library libmgl-glut libmgl-glut.so library libmgl-fltk libmgl-fltk.so library libmgl-qt libmgl-qt.so library libmgl-wx libmgl-wx.so legacy off libmgl mgl_create_graph_gl (ptr) mgl_create_graph_gl libmgl mgl_create_graph_zb int int (ptr) mgl_create_graph_zb libmgl mgl_create_graph_ps int int (ptr) mgl_create_graph_ps libmgl mgl_fortran_func ptr ptr (int) mgl_fortran_func libmgl-glut mgl_create_graph_glut ptr ptr ptr (ptr) mgl_create_graph_glut libmgl-fltk mgl_create_graph_fltk ptr ptr ptr (ptr) mgl_create_graph_fltk libmgl-qt mgl_create_graph_qt ptr ptr ptr (ptr) mgl_create_graph_qt \ libmgl-glut mgl_create_graph_glut_dr ptr ptr (ptr) mgl_create_graph_glut_dr \ libmgl-fltk mgl_create_graph_fltk_dr ptr ptr (ptr) mgl_create_graph_fltk_dr \ libmgl-qt mgl_create_graph_qt_dr ptr ptr (ptr) mgl_create_graph_qt_dr libmgl mgl_create_graph_idtf (ptr) mgl_create_graph_idtf libmgl-fltk mgl_fltk_run (void) mgl_fltk_run libmgl-qt mgl_qt_run (void) mgl_qt_run libmgl mgl_set_show_mouse_pos int ptr (void) mgl_set_show_mouse_pos libmgl mgl_get_last_mouse_pos sf sf sf ptr (void) mgl_get_last_mouse_pos libmgl mgl_update ptr (void) mgl_update libmgl mgl_delete_graph ptr (void) mgl_delete_graph libmgl mgl_create_data (ptr) mgl_create_data libmgl mgl_create_data_size int int int (ptr) mgl_create_data_size libmgl mgl_create_data_file ptr (ptr) mgl_create_data_file libmgl mgl_delete_data ptr (void) mgl_delete_data libmgl mgl_create_parser (ptr) mgl_create_parser libmgl mgl_delete_parser ptr (void) mgl_delete_parser libmgl mgl_add_param ptr int ptr (void) mgl_add_param libmgl mgl_add_paramw ptr int ptr (void) mgl_add_paramw libmgl mgl_add_var ptr ptr (ptr) mgl_add_var libmgl mgl_find_var ptr ptr (ptr) mgl_find_var libmgl mgl_parse int ptr ptr ptr (int) mgl_parse libmgl mgl_parsew int ptr ptr ptr (int) mgl_parsew libmgl mgl_parse_text ptr ptr ptr (void) mgl_parse_text libmgl mgl_parsew_text ptr ptr ptr (void) mgl_parsew_text libmgl mgl_restore_once ptr (void) mgl_restore_once libmgl mgl_parser_allow_setsize int ptr (void) mgl_parser_allow_setsize libmgl mgl_set_def_param ptr (void) mgl_set_def_param libmgl mgl_set_palette ptr ptr (void) mgl_set_palette libmgl mgl_set_pal_color sf sf sf int ptr (void) mgl_set_pal_color libmgl mgl_set_pal_num int ptr (void) mgl_set_pal_num libmgl mgl_set_rotated_text int ptr (void) mgl_set_rotated_text libmgl mgl_set_cut int ptr (void) mgl_set_cut libmgl mgl_set_cut_box sf sf sf sf sf sf ptr (void) mgl_set_cut_box libmgl mgl_set_tick_len sf ptr (void) mgl_set_tick_len libmgl mgl_set_bar_width sf ptr (void) mgl_set_bar_width libmgl mgl_set_base_line_width sf ptr (void) mgl_set_base_line_width libmgl mgl_set_mark_size sf ptr (void) mgl_set_mark_size libmgl mgl_set_arrow_size sf ptr (void) mgl_set_arrow_size libmgl mgl_set_font_size sf ptr (void) mgl_set_font_size libmgl mgl_set_font_def ptr ptr (void) mgl_set_font_def libmgl mgl_set_alpha_default sf ptr (void) mgl_set_alpha_default libmgl mgl_set_size int int ptr (void) mgl_set_size libmgl mgl_set_axial_dir ptr ptr (void) mgl_set_axial_dir libmgl mgl_set_meshnum int ptr (void) mgl_set_meshnum libmgl mgl_set_zoom sf sf sf sf ptr (void) mgl_set_zoom libmgl mgl_set_plotfactor sf ptr (void) mgl_set_plotfactor libmgl mgl_set_draw_face int ptr (void) mgl_set_draw_face libmgl mgl_set_scheme ptr ptr (void) mgl_set_scheme libmgl mgl_load_font ptr ptr ptr (void) mgl_load_font libmgl mgl_copy_font ptr ptr (void) mgl_copy_font libmgl mgl_restore_font ptr (void) mgl_restore_font libmgl mgl_show_image int ptr ptr (void) mgl_show_image libmgl mgl_write_frame ptr ptr ptr (void) mgl_write_frame libmgl mgl_write_bmp ptr ptr ptr (void) mgl_write_bmp libmgl mgl_write_jpg ptr ptr ptr (void) mgl_write_jpg libmgl mgl_write_png ptr ptr ptr (void) mgl_write_png libmgl mgl_write_png_solid ptr ptr ptr (void) mgl_write_png_solid libmgl mgl_write_eps ptr ptr ptr (void) mgl_write_eps libmgl mgl_write_svg ptr ptr ptr (void) mgl_write_svg libmgl mgl_write_idtf ptr ptr ptr (void) mgl_write_idtf libmgl mgl_write_gif ptr ptr ptr (void) mgl_write_gif libmgl mgl_start_gif int ptr ptr (void) mgl_start_gif libmgl mgl_close_gif ptr (void) mgl_close_gif libmgl mgl_get_rgb ptr (ptr) mgl_get_rgb libmgl mgl_get_rgba ptr (ptr) mgl_get_rgba libmgl mgl_get_width ptr (int) mgl_get_width libmgl mgl_get_height ptr (int) mgl_get_height libmgl mgl_new_frame ptr (int) mgl_new_frame libmgl mgl_end_frame ptr (void) mgl_end_frame libmgl mgl_get_num_frame ptr (int) mgl_get_num_frame libmgl mgl_reset_frames ptr (void) mgl_reset_frames libmgl mgl_set_transp_type int ptr (void) mgl_set_transp_type libmgl mgl_set_transp int ptr (void) mgl_set_transp libmgl mgl_set_alpha int ptr (void) mgl_set_alpha libmgl mgl_set_fog sf sf ptr (void) mgl_set_fog libmgl mgl_set_light int ptr (void) mgl_set_light libmgl mgl_set_light_n int int ptr (void) mgl_set_light_n libmgl mgl_add_light ptr sf sf sf int ptr (void) mgl_add_light libmgl mgl_add_light_rgb sf sf sf sf int sf sf sf int ptr (void) mgl_add_light_rgb libmgl mgl_set_ambbr sf ptr (void) mgl_set_ambbr libmgl mgl_identity ptr (void) mgl_identity libmgl mgl_clf ptr (void) mgl_clf libmgl mgl_flush ptr (void) mgl_flush libmgl mgl_clf_rgb sf sf sf ptr (void) mgl_clf_rgb libmgl mgl_subplot int int int ptr (void) mgl_subplot libmgl mgl_subplot_d sf sf int int int ptr (void) mgl_subplot_d libmgl mgl_inplot sf sf sf sf ptr (void) mgl_inplot libmgl mgl_relplot sf sf sf sf ptr (void) mgl_relplot libmgl mgl_columnplot int int ptr (void) mgl_columnplot libmgl mgl_aspect sf sf sf ptr (void) mgl_aspect libmgl mgl_rotate sf sf sf ptr (void) mgl_rotate libmgl mgl_rotate_vector sf sf sf sf ptr (void) mgl_rotate_vector libmgl mgl_perspective sf ptr (void) mgl_perspective libmgl mgl_set_ticks sf sf sf ptr (void) mgl_set_ticks libmgl mgl_set_subticks int int int ptr (void) mgl_set_subticks libmgl mgl_set_ticks_dir sf int sf ptr ptr (void) mgl_set_ticks_dir \ libmgl mgl_set_ticks_val ... ptr double val int ptr ptr (void) mgl_set_ticks_val libmgl mgl_set_ticks_vals ptr sf int ptr ptr (void) mgl_set_ticks_vals libmgl mgl_set_caxis sf sf ptr (void) mgl_set_caxis libmgl mgl_set_axis sf sf sf sf sf sf sf sf sf ptr (void) mgl_set_axis libmgl mgl_set_axis_3d sf sf sf sf sf sf ptr (void) mgl_set_axis_3d libmgl mgl_set_axis_2d sf sf sf sf ptr (void) mgl_set_axis_2d libmgl mgl_set_origin sf sf sf ptr (void) mgl_set_origin libmgl mgl_set_tick_origin sf sf sf ptr (void) mgl_set_tick_origin libmgl mgl_set_crange int ptr ptr (void) mgl_set_crange libmgl mgl_set_xrange int ptr ptr (void) mgl_set_xrange libmgl mgl_set_yrange int ptr ptr (void) mgl_set_yrange libmgl mgl_set_zrange int ptr ptr (void) mgl_set_zrange libmgl mgl_set_auto sf sf sf sf sf sf ptr (void) mgl_set_auto libmgl mgl_set_func ptr ptr ptr ptr (void) mgl_set_func libmgl mgl_set_ternary int ptr (void) mgl_set_ternary libmgl mgl_set_cutoff ptr ptr (void) mgl_set_cutoff libmgl mgl_box int ptr (void) mgl_box libmgl mgl_box_str int ptr ptr (void) mgl_box_str libmgl mgl_box_rgb int sf sf sf ptr (void) mgl_box_rgb libmgl mgl_axis ptr ptr (void) mgl_axis libmgl mgl_axis_grid ptr ptr ptr (void) mgl_axis_grid libmgl mgl_label ptr ptr ptr (void) mgl_label libmgl mgl_label_ext sf sf int ptr ptr ptr (void) mgl_label_ext libmgl mgl_tune_ticks sf int ptr (void) mgl_tune_ticks libmgl mgl_set_xttw ptr ptr (void) mgl_set_xttw libmgl mgl_set_yttw ptr ptr (void) mgl_set_yttw libmgl mgl_set_zttw ptr ptr (void) mgl_set_zttw libmgl mgl_set_cttw ptr ptr (void) mgl_set_cttw libmgl mgl_set_xtt ptr ptr (void) mgl_set_xtt libmgl mgl_set_ytt ptr ptr (void) mgl_set_ytt libmgl mgl_set_ztt ptr ptr (void) mgl_set_ztt libmgl mgl_set_ctt ptr ptr (void) mgl_set_ctt libmgl mgl_ball sf sf sf ptr (void) mgl_ball libmgl mgl_ball_rgb sf sf sf sf sf sf sf ptr (void) mgl_ball_rgb libmgl mgl_ball_str ptr sf sf sf ptr (void) mgl_ball_str libmgl mgl_line int ptr sf sf sf sf sf sf ptr (void) mgl_line libmgl mgl_facex sf sf ptr sf sf sf sf sf ptr (void) mgl_facex libmgl mgl_facey sf sf ptr sf sf sf sf sf ptr (void) mgl_facey libmgl mgl_facez sf sf ptr sf sf sf sf sf ptr (void) mgl_facez libmgl mgl_curve int ptr sf sf sf sf sf sf sf sf sf sf sf sf ptr (void) mgl_curve libmgl mgl_puts ptr sf sf sf ptr (void) mgl_puts libmgl mgl_putsw ptr sf sf sf ptr (void) mgl_putsw libmgl mgl_puts_dir sf ptr sf sf sf sf sf sf ptr (void) mgl_puts_dir libmgl mgl_putsw_dir sf ptr sf sf sf sf sf sf ptr (void) mgl_putsw_dir libmgl mgl_text ptr sf sf sf ptr (void) mgl_text libmgl mgl_title sf ptr ptr ptr (void) mgl_title libmgl mgl_titlew sf ptr ptr ptr (void) mgl_titlew libmgl mgl_putsw_ext ptr sf ptr ptr sf sf sf ptr (void) mgl_putsw_ext libmgl mgl_puts_ext ptr sf ptr ptr sf sf sf ptr (void) mgl_puts_ext libmgl mgl_text_ext ptr sf ptr ptr sf sf sf ptr (void) mgl_text_ext libmgl mgl_colorbar int ptr ptr (void) mgl_colorbar libmgl mgl_colorbar_ext sf sf sf sf int ptr ptr (void) mgl_colorbar_ext libmgl mgl_simple_plot ptr int ptr ptr (void) mgl_simple_plot libmgl mgl_add_legend ptr ptr ptr (void) mgl_add_legend libmgl mgl_add_legendw ptr ptr ptr (void) mgl_add_legendw libmgl mgl_clear_legend ptr (void) mgl_clear_legend libmgl mgl_legend_xy sf sf ptr sf sf ptr (void) mgl_legend_xy libmgl mgl_legend sf sf ptr int ptr (void) mgl_legend libmgl mgl_set_legend_box int ptr (void) mgl_set_legend_box libmgl mgl_fplot int ptr ptr ptr (void) mgl_fplot libmgl mgl_fplot_xyz int ptr ptr ptr ptr ptr (void) mgl_fplot_xyz libmgl mgl_plot_xyz ptr ptr ptr ptr ptr (void) mgl_plot_xyz libmgl mgl_plot_xy ptr ptr ptr ptr (void) mgl_plot_xy libmgl mgl_plot ptr ptr ptr (void) mgl_plot libmgl mgl_plot_2 ptr ptr ptr (void) mgl_plot_2 libmgl mgl_plot_3 ptr ptr ptr (void) mgl_plot_3 libmgl mgl_tens_xyz ptr ptr ptr ptr ptr ptr (void) mgl_tens_xyz libmgl mgl_tens_xy ptr ptr ptr ptr ptr (void) mgl_tens_xy libmgl mgl_tens ptr ptr ptr ptr (void) mgl_tens libmgl mgl_area_xyz ptr ptr ptr ptr ptr (void) mgl_area_xyz libmgl mgl_area_xy ptr ptr ptr ptr (void) mgl_area_xy libmgl mgl_area_xys ptr ptr ptr ptr (void) mgl_area_xys libmgl mgl_area ptr ptr ptr (void) mgl_area libmgl mgl_area_2 ptr ptr ptr (void) mgl_area_2 libmgl mgl_area_3 ptr ptr ptr (void) mgl_area_3 libmgl mgl_region_xy int ptr ptr ptr ptr ptr (void) mgl_region_xy libmgl mgl_region int ptr ptr ptr ptr (void) mgl_region libmgl mgl_mark ptr sf sf sf ptr (void) mgl_mark libmgl mgl_stem_xyz ptr ptr ptr ptr ptr (void) mgl_stem_xyz libmgl mgl_stem_xy ptr ptr ptr ptr (void) mgl_stem_xy libmgl mgl_stem ptr ptr ptr (void) mgl_stem libmgl mgl_stem_2 ptr ptr ptr (void) mgl_stem_2 libmgl mgl_stem_3 ptr ptr ptr (void) mgl_stem_3 libmgl mgl_step_xyz ptr ptr ptr ptr ptr (void) mgl_step_xyz libmgl mgl_step_xy ptr ptr ptr ptr (void) mgl_step_xy libmgl mgl_step ptr ptr ptr (void) mgl_step libmgl mgl_step_2 ptr ptr ptr (void) mgl_step_2 libmgl mgl_step_3 ptr ptr ptr (void) mgl_step_3 libmgl mgl_bars_xyz ptr ptr ptr ptr ptr (void) mgl_bars_xyz libmgl mgl_bars_xy ptr ptr ptr ptr (void) mgl_bars_xy libmgl mgl_bars ptr ptr ptr (void) mgl_bars libmgl mgl_bars_2 ptr ptr ptr (void) mgl_bars_2 libmgl mgl_bars_3 ptr ptr ptr (void) mgl_bars_3 libmgl mgl_barh_yx ptr ptr ptr ptr (void) mgl_barh_yx libmgl mgl_barh ptr ptr ptr (void) mgl_barh libmgl mgl_torus ptr ptr ptr ptr (void) mgl_torus libmgl mgl_torus_2 ptr ptr ptr (void) mgl_torus_2 libmgl mgl_text_xyz sf ptr ptr ptr ptr ptr ptr (void) mgl_text_xyz libmgl mgl_text_xy sf ptr ptr ptr ptr ptr (void) mgl_text_xy libmgl mgl_text_y sf ptr ptr ptr ptr (void) mgl_text_y libmgl mgl_chart ptr ptr ptr (void) mgl_chart libmgl mgl_error ptr ptr ptr ptr (void) mgl_error libmgl mgl_error_xy ptr ptr ptr ptr ptr (void) mgl_error_xy libmgl mgl_error_exy ptr ptr ptr ptr ptr ptr (void) mgl_error_exy libmgl mgl_mark_xyz ptr ptr ptr ptr ptr ptr (void) mgl_mark_xyz libmgl mgl_mark_xy ptr ptr ptr ptr ptr (void) mgl_mark_xy libmgl mgl_mark_y ptr ptr ptr ptr (void) mgl_mark_y libmgl mgl_tube_xyzr ptr ptr ptr ptr ptr ptr (void) mgl_tube_xyzr libmgl mgl_tube_xyr ptr ptr ptr ptr ptr (void) mgl_tube_xyr libmgl mgl_tube_r ptr ptr ptr ptr (void) mgl_tube_r libmgl mgl_tube_xyz ptr sf ptr ptr ptr ptr (void) mgl_tube_xyz libmgl mgl_tube_xy ptr sf ptr ptr ptr (void) mgl_tube_xy libmgl mgl_tube ptr sf ptr ptr (void) mgl_tube libmgl mgl_textmark_xyzr ptr ptr ptr ptr ptr ptr ptr (void) mgl_textmark_xyzr libmgl mgl_textmark_xyr ptr ptr ptr ptr ptr ptr (void) mgl_textmark_xyr libmgl mgl_textmark_yr ptr ptr ptr ptr ptr (void) mgl_textmark_yr libmgl mgl_textmark ptr ptr ptr ptr (void) mgl_textmark libmgl mgl_textmarkw_xyzr ptr ptr ptr ptr ptr ptr ptr (void) mgl_textmarkw_xyzr libmgl mgl_textmarkw_xyr ptr ptr ptr ptr ptr ptr (void) mgl_textmarkw_xyr libmgl mgl_textmarkw_yr ptr ptr ptr ptr ptr (void) mgl_textmarkw_yr libmgl mgl_textmarkw ptr ptr ptr ptr (void) mgl_textmarkw libmgl mgl_fsurf int ptr ptr ptr (void) mgl_fsurf libmgl mgl_fsurf_xyz int ptr ptr ptr ptr ptr (void) mgl_fsurf_xyz libmgl mgl_grid_xy sf ptr ptr ptr ptr ptr (void) mgl_grid_xy libmgl mgl_grid sf ptr ptr ptr (void) mgl_grid libmgl mgl_mesh_xy ptr ptr ptr ptr ptr (void) mgl_mesh_xy libmgl mgl_mesh ptr ptr ptr (void) mgl_mesh libmgl mgl_fall_xy ptr ptr ptr ptr ptr (void) mgl_fall_xy libmgl mgl_fall ptr ptr ptr (void) mgl_fall libmgl mgl_belt_xy ptr ptr ptr ptr ptr (void) mgl_belt_xy libmgl mgl_belt ptr ptr ptr (void) mgl_belt libmgl mgl_surf_xy ptr ptr ptr ptr ptr (void) mgl_surf_xy libmgl mgl_surf ptr ptr ptr (void) mgl_surf libmgl mgl_dens_xy sf ptr ptr ptr ptr ptr (void) mgl_dens_xy libmgl mgl_dens sf ptr ptr ptr (void) mgl_dens libmgl mgl_boxs_xy sf ptr ptr ptr ptr ptr (void) mgl_boxs_xy libmgl mgl_boxs sf ptr ptr ptr (void) mgl_boxs libmgl mgl_tile_xy ptr ptr ptr ptr ptr (void) mgl_tile_xy libmgl mgl_tile ptr ptr ptr (void) mgl_tile libmgl mgl_tiles_xy ptr ptr ptr ptr ptr ptr (void) mgl_tiles_xy libmgl mgl_tiles ptr ptr ptr ptr (void) mgl_tiles libmgl mgl_cont_xy_val sf ptr ptr ptr ptr ptr ptr (void) mgl_cont_xy_val libmgl mgl_cont_val sf ptr ptr ptr ptr (void) mgl_cont_val libmgl mgl_cont_xy sf int ptr ptr ptr ptr ptr (void) mgl_cont_xy libmgl mgl_cont sf int ptr ptr ptr (void) mgl_cont libmgl mgl_contf_xy_val sf ptr ptr ptr ptr ptr ptr (void) mgl_contf_xy_val libmgl mgl_contf_val sf ptr ptr ptr ptr (void) mgl_contf_val libmgl mgl_contf_xy sf int ptr ptr ptr ptr ptr (void) mgl_contf_xy libmgl mgl_contf sf int ptr ptr ptr (void) mgl_contf libmgl mgl_axial_xy_val ptr ptr ptr ptr ptr ptr (void) mgl_axial_xy_val libmgl mgl_axial_val ptr ptr ptr ptr (void) mgl_axial_val libmgl mgl_axial_xy int ptr ptr ptr ptr ptr (void) mgl_axial_xy libmgl mgl_axial int ptr ptr ptr (void) mgl_axial libmgl mgl_surfc_xy ptr ptr ptr ptr ptr ptr (void) mgl_surfc_xy libmgl mgl_surfc ptr ptr ptr ptr (void) mgl_surfc libmgl mgl_surfa_xy ptr ptr ptr ptr ptr ptr (void) mgl_surfa_xy libmgl mgl_surfa ptr ptr ptr ptr (void) mgl_surfa libmgl mgl_stfa_xy sf ptr int ptr ptr ptr ptr ptr (void) mgl_stfa_xy libmgl mgl_stfa sf ptr int ptr ptr ptr (void) mgl_stfa libmgl mgl_vect_xy sf ptr ptr ptr ptr ptr ptr (void) mgl_vect_xy libmgl mgl_vect_2d sf ptr ptr ptr ptr (void) mgl_vect_2d libmgl mgl_vectl_xy sf ptr ptr ptr ptr ptr ptr (void) mgl_vectl_xy libmgl mgl_vectl_2d sf ptr ptr ptr ptr (void) mgl_vectl_2d libmgl mgl_vectc_xy sf ptr ptr ptr ptr ptr ptr (void) mgl_vectc_xy libmgl mgl_vectc_2d sf ptr ptr ptr ptr (void) mgl_vectc_2d libmgl mgl_vect_xyz ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_vect_xyz libmgl mgl_vect_3d ptr ptr ptr ptr ptr (void) mgl_vect_3d libmgl mgl_vectl_xyz ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_vectl_xyz libmgl mgl_vectl_3d ptr ptr ptr ptr ptr (void) mgl_vectl_3d libmgl mgl_vectc_xyz ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_vectc_xyz libmgl mgl_vectc_3d ptr ptr ptr ptr ptr (void) mgl_vectc_3d libmgl mgl_map_xy int int ptr ptr ptr ptr ptr ptr (void) mgl_map_xy libmgl mgl_map int int ptr ptr ptr ptr (void) mgl_map libmgl mgl_surf3a_xyz_val ptr ptr ptr ptr ptr ptr sf ptr (void) mgl_surf3a_xyz_val libmgl mgl_surf3a_val ptr ptr ptr sf ptr (void) mgl_surf3a_val libmgl mgl_surf3a_xyz int ptr ptr ptr ptr ptr ptr ptr (void) mgl_surf3a_xyz libmgl mgl_surf3a int ptr ptr ptr ptr (void) mgl_surf3a libmgl mgl_surf3c_xyz_val ptr ptr ptr ptr ptr ptr sf ptr (void) mgl_surf3c_xyz_val libmgl mgl_surf3c_val ptr ptr ptr sf ptr (void) mgl_surf3c_val libmgl mgl_surf3c_xyz (void) mgl_surf3c_xyz libmgl mgl_surf3c int ptr ptr ptr ptr (void) mgl_surf3c libmgl mgl_flow_xy sf int int ptr ptr ptr ptr ptr ptr (void) mgl_flow_xy libmgl mgl_flow_2d sf int int ptr ptr ptr ptr (void) mgl_flow_2d libmgl mgl_flow_xyz int int ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_flow_xyz libmgl mgl_flow_3d int int ptr ptr ptr ptr ptr (void) mgl_flow_3d libmgl mgl_pipe_xy sf int int sf ptr ptr ptr ptr ptr ptr (void) mgl_pipe_xy libmgl mgl_pipe_2d sf int int sf ptr ptr ptr ptr (void) mgl_pipe_2d libmgl mgl_pipe_xyz int int sf ptr ptr ptr ptr ptr ptr ptr ptr (void) mgl_pipe_xyz libmgl mgl_pipe_3d int int sf ptr ptr ptr ptr ptr (void) mgl_pipe_3d libmgl mgl_dew_xy sf ptr ptr ptr ptr ptr ptr (void) mgl_dew_xy libmgl mgl_dew_2d sf ptr ptr ptr ptr (void) mgl_dew_2d libmgl mgl_grid3_xyz ptr int ptr ptr ptr ptr ptr ptr (void) mgl_grid3_xyz libmgl mgl_grid3 ptr int ptr ptr ptr (void) mgl_grid3 libmgl mgl_grid3_all_xyz ptr ptr ptr ptr ptr ptr (void) mgl_grid3_all_xyz libmgl mgl_grid3_all ptr ptr ptr (void) mgl_grid3_all libmgl mgl_dens3_xyz ptr int ptr ptr ptr ptr ptr ptr (void) mgl_dens3_xyz libmgl mgl_dens3 ptr int ptr ptr ptr (void) mgl_dens3 libmgl mgl_dens3_all_xyz ptr ptr ptr ptr ptr ptr (void) mgl_dens3_all_xyz libmgl mgl_dens3_all ptr ptr ptr (void) mgl_dens3_all libmgl mgl_surf3_xyz_val ptr ptr ptr ptr ptr sf ptr (void) mgl_surf3_xyz_val libmgl mgl_surf3_val ptr ptr sf ptr (void) mgl_surf3_val libmgl mgl_surf3_xyz int ptr ptr ptr ptr ptr ptr (void) mgl_surf3_xyz libmgl mgl_surf3 int ptr ptr ptr (void) mgl_surf3 libmgl mgl_cont3_xyz_val ptr int ptr ptr ptr ptr ptr ptr ptr (void) mgl_cont3_xyz_val libmgl mgl_cont3_val ptr int ptr ptr ptr ptr (void) mgl_cont3_val libmgl mgl_cont3_xyz int ptr int ptr ptr ptr ptr ptr ptr (void) mgl_cont3_xyz libmgl mgl_cont3 int ptr int ptr ptr ptr (void) mgl_cont3 libmgl mgl_cont_all_xyz int ptr ptr ptr ptr ptr ptr (void) mgl_cont_all_xyz libmgl mgl_cont_all int ptr ptr ptr (void) mgl_cont_all libmgl mgl_cloudp_xyz sf ptr ptr ptr ptr ptr ptr (void) mgl_cloudp_xyz libmgl mgl_cloudp sf ptr ptr ptr (void) mgl_cloudp libmgl mgl_cloud_xyz sf ptr ptr ptr ptr ptr ptr (void) mgl_cloud_xyz libmgl mgl_cloud sf ptr ptr ptr (void) mgl_cloud libmgl mgl_contf3_xyz_val ptr int ptr ptr ptr ptr ptr ptr ptr (void) mgl_contf3_xyz_val libmgl mgl_contf3_val ptr int ptr ptr ptr ptr (void) mgl_contf3_val libmgl mgl_contf3_xyz int ptr int ptr ptr ptr ptr ptr ptr (void) mgl_contf3_xyz libmgl mgl_contf3 int ptr int ptr ptr ptr (void) mgl_contf3 libmgl mgl_contf_all_xyz int ptr ptr ptr ptr ptr ptr (void) mgl_contf_all_xyz libmgl mgl_contf_all int ptr ptr ptr (void) mgl_contf_all libmgl mgl_beam_val int ptr sf ptr ptr ptr ptr sf ptr (void) mgl_beam_val libmgl mgl_beam int int ptr sf ptr ptr ptr ptr ptr (void) mgl_beam libmgl mgl_triplot_xyzc ptr ptr ptr ptr ptr ptr ptr (void) mgl_triplot_xyzc libmgl mgl_triplot_xyz ptr ptr ptr ptr ptr ptr (void) mgl_triplot_xyz libmgl mgl_triplot_xy sf ptr ptr ptr ptr ptr (void) mgl_triplot_xy libmgl mgl_dots ptr ptr ptr ptr ptr (void) mgl_dots libmgl mgl_dots_tr ptr ptr ptr (void) mgl_dots_tr libmgl mgl_crust sf ptr ptr ptr ptr ptr (void) mgl_crust libmgl mgl_crust_tr sf ptr ptr ptr (void) mgl_crust_tr libmgl mgl_dens_x sf ptr ptr ptr (void) mgl_dens_x libmgl mgl_dens_y sf ptr ptr ptr (void) mgl_dens_y libmgl mgl_dens_z sf ptr ptr ptr (void) mgl_dens_z libmgl mgl_cont_x int sf ptr ptr ptr (void) mgl_cont_x libmgl mgl_cont_y int sf ptr ptr ptr (void) mgl_cont_y libmgl mgl_cont_z int sf ptr ptr ptr (void) mgl_cont_z libmgl mgl_cont_x_val sf ptr ptr ptr ptr (void) mgl_cont_x_val libmgl mgl_cont_y_val sf ptr ptr ptr ptr (void) mgl_cont_y_val libmgl mgl_cont_z_val sf ptr ptr ptr ptr (void) mgl_cont_z_val libmgl mgl_contf_x int sf ptr ptr ptr (void) mgl_contf_x libmgl mgl_contf_y int sf ptr ptr ptr (void) mgl_contf_y libmgl mgl_contf_z int sf ptr ptr ptr (void) mgl_contf_z libmgl mgl_contf_x_val sf ptr ptr ptr ptr (void) mgl_contf_x_val libmgl mgl_contf_y_val sf ptr ptr ptr ptr (void) mgl_contf_y_val libmgl mgl_contf_z_val sf ptr ptr ptr ptr (void) mgl_contf_z_val libmgl mgl_data_rearrange int int int ptr (void) mgl_data_rearrange libmgl mgl_data_set_float int int int sf ptr (void) mgl_data_set_float libmgl mgl_data_set_double int int int df ptr (void) mgl_data_set_double libmgl mgl_data_set_float2 int int sf ptr (void) mgl_data_set_float2 libmgl mgl_data_set_double2 int int df ptr (void) mgl_data_set_double2 libmgl mgl_data_set_float3 int int int sf ptr (void) mgl_data_set_float3 libmgl mgl_data_set_double3 int int int ptr ptr (void) mgl_data_set_double3 libmgl mgl_data_set ptr ptr (void) mgl_data_set libmgl mgl_data_set_vector ptr ptr (void) mgl_data_set_vector libmgl mgl_data_set_matrix ptr ptr (void) mgl_data_set_matrix libmgl mgl_data_get_value int int int ptr (fp) mgl_data_get_value libmgl mgl_data_get_nx ptr (int) mgl_data_get_nx libmgl mgl_data_get_ny ptr (int) mgl_data_get_ny libmgl mgl_data_get_nz ptr (int) mgl_data_get_nz libmgl mgl_data_set_value int int int sf ptr (void) mgl_data_set_value libmgl mgl_data_set_values int int int ptr ptr (void) mgl_data_set_values libmgl mgl_data_read ptr ptr (int) mgl_data_read libmgl mgl_data_read_mat int ptr ptr (int) mgl_data_read_mat libmgl mgl_data_read_dim int int int ptr ptr (int) mgl_data_read_dim libmgl mgl_data_save int ptr ptr (void) mgl_data_save libmgl mgl_data_export int sf sf ptr ptr ptr (void) mgl_data_export libmgl mgl_data_import sf sf ptr ptr ptr (void) mgl_data_import libmgl mgl_data_create int int int ptr (void) mgl_data_create libmgl mgl_data_transpose ptr ptr (void) mgl_data_transpose libmgl mgl_data_norm int int sf sf ptr (void) mgl_data_norm libmgl mgl_data_norm_slice int int ptr sf sf ptr (void) mgl_data_norm_slice libmgl mgl_data_subdata int int int ptr (ptr) mgl_data_subdata libmgl mgl_data_column ptr ptr (ptr) mgl_data_column libmgl mgl_data_set_id ptr ptr (void) mgl_data_set_id libmgl mgl_data_fill ptr sf sf ptr (void) mgl_data_fill libmgl mgl_data_fill_eq ptr ptr ptr ptr ptr (void) mgl_data_fill_eq libmgl mgl_data_put_val int int int sf ptr (void) mgl_data_put_val libmgl mgl_data_put_dat int int int ptr ptr (void) mgl_data_put_dat libmgl mgl_data_modify int ptr ptr (void) mgl_data_modify libmgl mgl_data_modify_vw ptr ptr ptr ptr (void) mgl_data_modify_vw libmgl mgl_data_squeeze int int int int ptr (void) mgl_data_squeeze libmgl mgl_data_max ptr (fp) mgl_data_max libmgl mgl_data_min ptr (fp) mgl_data_min libmgl mgl_data_value int int int ptr (fp) mgl_data_value libmgl mgl_data_combine ptr ptr (ptr) mgl_data_combine libmgl mgl_data_extend int int ptr (void) mgl_data_extend libmgl mgl_data_insert int int ptr ptr (void) mgl_data_insert libmgl mgl_data_delete int int ptr ptr (void) mgl_data_delete libmgl mgl_data_smooth ptr sf int ptr (void) mgl_data_smooth libmgl mgl_data_sum ptr ptr (ptr) mgl_data_sum libmgl mgl_data_max_dir ptr ptr (ptr) mgl_data_max_dir libmgl mgl_data_min_dir ptr ptr (ptr) mgl_data_min_dir libmgl mgl_data_cumsum ptr ptr (void) mgl_data_cumsum libmgl mgl_data_integral ptr ptr (void) mgl_data_integral libmgl mgl_data_diff ptr ptr (void) mgl_data_diff libmgl mgl_data_diff_par ptr ptr ptr ptr (void) mgl_data_diff_par libmgl mgl_data_diff2 ptr ptr (void) mgl_data_diff2 libmgl mgl_data_swap ptr ptr (void) mgl_data_swap libmgl mgl_data_mirror ptr ptr (void) mgl_data_mirror libmgl mgl_data_spline sf sf sf ptr (fp) mgl_data_spline libmgl mgl_data_spline1 sf sf sf ptr (fp) mgl_data_spline1 libmgl mgl_data_linear sf sf sf ptr (fp) mgl_data_linear libmgl mgl_data_linear1 sf sf sf ptr (fp) mgl_data_linear1 libmgl mgl_data_resize int int int ptr (ptr) mgl_data_resize libmgl mgl_data_resize_box (ptr) mgl_data_resize_box libmgl mgl_data_hist int sf sf int ptr (ptr) mgl_data_hist libmgl mgl_data_hist_w int sf sf int ptr ptr (ptr) mgl_data_hist_w libmgl mgl_data_momentum ptr ptr ptr (ptr) mgl_data_momentum libmgl mgl_data_evaluate_i int ptr ptr (ptr) mgl_data_evaluate_i libmgl mgl_data_evaluate_ij int ptr ptr ptr (ptr) mgl_data_evaluate_ij libmgl mgl_data_evaluate_ijk int ptr ptr ptr ptr (ptr) mgl_data_evaluate_ijk libmgl mgl_data_envelop ptr ptr (void) mgl_data_envelop libmgl mgl_data_sew sf ptr ptr (void) mgl_data_sew libmgl mgl_data_crop ptr int int ptr (void) mgl_data_crop libmgl mgl_data_mul_dat ptr ptr (void) mgl_data_mul_dat libmgl mgl_data_div_dat ptr ptr (void) mgl_data_div_dat libmgl mgl_data_add_dat ptr ptr (void) mgl_data_add_dat libmgl mgl_data_sub_dat ptr ptr (void) mgl_data_sub_dat libmgl mgl_data_mul_num sf ptr (void) mgl_data_mul_num libmgl mgl_data_div_num sf ptr (void) mgl_data_div_num libmgl mgl_data_add_num sf ptr (void) mgl_data_add_num libmgl mgl_data_sub_num sf ptr (void) mgl_data_sub_num libmgl mgl_fit_1 sf ptr ptr ptr ptr ptr (fp) mgl_fit_1 libmgl mgl_fit_2 sf ptr ptr ptr ptr ptr (fp) mgl_fit_2 libmgl mgl_fit_3 sf ptr ptr ptr ptr ptr (fp) mgl_fit_3 libmgl mgl_fit_xy sf ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xy libmgl mgl_fit_xyz sf ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyz libmgl mgl_fit_xyza sf ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyza libmgl mgl_fit_ys sf ptr ptr ptr ptr ptr ptr (fp) mgl_fit_ys libmgl mgl_fit_xys sf ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xys libmgl mgl_fit_xyzs sf ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyzs libmgl mgl_fit_xyzas sf ptr ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyzas libmgl mgl_fit_1_d ptr ptr ptr ptr ptr ptr (fp) mgl_fit_1_d libmgl mgl_fit_2_d ptr ptr ptr ptr ptr ptr (fp) mgl_fit_2_d libmgl mgl_fit_3_d ptr ptr ptr ptr ptr ptr (fp) mgl_fit_3_d libmgl mgl_fit_xy_d ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xy_d libmgl mgl_fit_xyz_d ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyz_d libmgl mgl_fit_xyza_d ptr ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyza_d libmgl mgl_fit_ys_d ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_ys_d libmgl mgl_fit_xys_d ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xys_d libmgl mgl_fit_xyzs_d ptr ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyzs_d libmgl mgl_fit_xyzas_d ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr (fp) mgl_fit_xyzas_d libmgl mgl_puts_fit sf ptr ptr sf sf sf ptr (void) mgl_puts_fit libmgl mgl_sphere ptr sf sf sf sf ptr (void) mgl_sphere libmgl mgl_drop sf sf ptr sf sf sf sf sf sf sf ptr (void) mgl_drop libmgl mgl_cone int ptr sf sf sf sf sf sf sf sf ptr (void) mgl_cone libmgl mgl_pde_solve sf sf ptr ptr ptr ptr (ptr) mgl_pde_solve libmgl mgl_qo2d_solve ptr ptr sf sf ptr ptr ptr ptr (ptr) mgl_qo2d_solve libmgl mgl_af2d_solve ptr ptr sf sf ptr ptr ptr ptr (ptr) mgl_af2d_solve libmgl mgl_ray_trace sf sf sf sf sf sf sf sf ptr (ptr) mgl_ray_trace libmgl mgl_jacobian_2d ptr ptr (ptr) mgl_jacobian_2d libmgl mgl_jacobian_3d ptr ptr ptr (ptr) mgl_jacobian_3d libmgl mgl_transform_a ptr ptr ptr (ptr) mgl_transform_a libmgl mgl_transform ptr ptr ptr (ptr) mgl_transform libmgl mgl_data_stfa ptr int ptr ptr (ptr) mgl_data_stfa legacy on previous Module; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/CMakeLists.txt�����������������������������������������������������������������0000644�0001750�0001750�00000003047�13513030041�017334� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������configure_file(${MathGL2_SOURCE_DIR}/include/config.h.in ${MathGL2_BINARY_DIR}/include/mgl2/config.h) configure_file(${MathGL2_SOURCE_DIR}/include/build.h.in ${MathGL2_BINARY_DIR}/include/mgl2/build.h) install(DIRECTORY mgl2/ DESTINATION ${MGL_INCLUDE_PATH} PATTERN ".svn" EXCLUDE PATTERN "fltk.h" EXCLUDE PATTERN "glut.h" EXCLUDE PATTERN "wx.h" EXCLUDE PATTERN "qt.h" EXCLUDE PATTERN "qmathgl.h" EXCLUDE PATTERN "window.h" EXCLUDE PATTERN "*old.h" EXCLUDE PATTERN "*~" EXCLUDE PATTERN "*.fs" PATTERN "*.pas" PATTERN "*.h") install(FILES ${MathGL2_BINARY_DIR}/include/mgl2/config.h DESTINATION ${MGL_INCLUDE_PATH}) if(MGL_HAVE_FLTK) install(FILES mgl2/fltk.h DESTINATION ${MGL_INCLUDE_PATH}) endif(MGL_HAVE_FLTK) if(MGL_HAVE_GLUT) install(FILES mgl2/glut.h DESTINATION ${MGL_INCLUDE_PATH}) endif(MGL_HAVE_GLUT) if(MGL_HAVE_WX) install(FILES mgl2/wx.h DESTINATION ${MGL_INCLUDE_PATH}) endif(MGL_HAVE_WX) if(MGL_HAVE_QT) install(FILES mgl2/qt.h mgl2/qmathgl.h DESTINATION ${MGL_INCLUDE_PATH}) endif(MGL_HAVE_QT) #if(MGL_HAVE_FLTK AND MGL_HAVE_WX AND MGL_HAVE_QT) if(MGL_HAVE_FLTK AND MGL_HAVE_QT AND MGL_HAVE_WX) install(FILES mgl2/window.h DESTINATION ${MGL_INCLUDE_PATH}) #endif(MGL_HAVE_FLTK AND MGL_HAVE_WX AND MGL_HAVE_QT) endif(MGL_HAVE_FLTK AND MGL_HAVE_QT AND MGL_HAVE_WX) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/���������������������������������������������������������������������������0000755�0001750�0001750�00000000000�13513030041�015374� 5����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/stop.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000664�13513030041�017115� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * stop_xpm[] = { "16 16 4 1", " c None", ". c #770000", "+ c #FF0000", "@ c #FFFFFF", " ", " ...... ", " .++++++. ", " .++++++++. ", " .++++++++++. ", " .+++@@++@@+++. ", " .+++@@@@@@+++. ", " .++++@@@@++++. ", " .++++@@@@++++. ", " .+++@@@@@@+++. ", " .+++@@++@@+++. ", " .++++++++++. ", " .++++++++. ", " .++++++. ", " ...... ", " "}; ����������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_o.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017735� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_o_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " .... ", " ...... ", " ........ ", " ........ ", ".............. ", " ........ ", " ........ ", " ....... ", " .... ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper_d.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017371� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_d_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " . ", " . ", " . ", " . ...... ", " . ", " . ...... ", " . ", " . ", " . ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/cons.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000664�13513030041�017072� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * cons_xpm[] = { "16 16 4 1", " c None", ". c #000000", "+ c #0000FF", "@ c #FF0000", " ", " .............. ", " . . ", " . . . . . . .. ", " . . ", " . . . . . . .. ", " .............. ", " ", " +++++++++++++ ", " +++++++++ ", " +++++ ", " + ", " @@@@@@@@@@@@@@ ", " @ @ @ @ @ @ @@ ", " @@@@@@@@@@@@@@ ", " "}; ����������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arc.xpm��������������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�016672� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arc_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ...... ", " .. .. ", " . . ", " . ", " . ", " .", " .", " .", " ", " ", " ", " ", " ", " ", " ", " "}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_e.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017364� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_e_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "################", "################", "................", "................", "################", "################", "................", "................", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_v.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017601� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_v_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ... ", " .... ", " ..... ", " ...... ", " ...........", " ...... ", " ..... ", " .... ", " ... ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/next_sl.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000706�13513030041�017601� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * next_sl_xpm[] = { "16 16 5 1", " c None", ". c #00007F", "+ c #007FFF", "@ c #0000FF", "# c #003F80", " ", " .. ", " .+. ", " .++. ", " .++@+. ", " ....++@+@+. ", " .@+@+@+@+@+. ", " .@@@@@@@@+@+. ", " .@@@@@@@@@@@@. ", " .@@@@@@@@#@#. ", " .@#@#@#@#@#. ", " ....@#@#@#. ", " .@#@#. ", " .##. ", " .#. ", " .. "}; ����������������������������������������������������������mathgl-2.4.4/include/xpm/comment.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017564� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * comment_xpm[] = { "16 16 2 1", " c None", ". c #009f00", " ", " ", " ", " . . ", " . . ", " . . ", " ............ ", " . . ", " . . ", " . . ", " . . ", " ............ ", " . . ", " . . ", " . . ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/prev_sl.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000706�13513030041�017577� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * prev_sl_xpm[] = { "16 16 5 1", " c None", ". c #00007F", "+ c #007FFF", "@ c #0000FF", "# c #003F80", " ", " .. ", " .+. ", " .++. ", " .+@++. ", " .+@+@++.... ", " .+@+@+@+@+@. ", " .+@+@@@@@@@@. ", " .@@@@@@@@@@@@. ", " .#@#@@@@@@@@. ", " .#@#@#@#@#@. ", " .#@#@#@.... ", " .#@#@. ", " .##. ", " .#. ", " .. "}; ����������������������������������������������������������mathgl-2.4.4/include/xpm/mark_cf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017524� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_cf_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ...... ", " .. .. ", " . . ", " . . ", " . . ", ". .", ". .", ". .. .", ". .. .", ". .", ". .", " . . ", " . . ", " . . ", " .. .. ", " ...... "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/udav.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000033407�13513030041�017070� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *udav_xpm[]={ "64 64 349 2", "Qt c None", "#n c #000080", "#h c #010180", "#y c #010181", "#s c #020281", "#c c #020282", "dg c #030382", ".8 c #030383", "#r c #040483", "#m c #040484", "#g c #050584", "#M c #050585", "#q c #060685", "a. c #060686", "#p c #070786", "ck c #070787", "aj c #080887", "bm c #080888", "aK c #090988", "a4 c #090989", "aJ c #0a0a89", "## c #0a0a8a", "#G c #0b0b8a", "cx c #0b0b8b", "b7 c #0c0c8b", "#z c #0c0c8c", "b6 c #0d0d8c", "b8 c #0d0d8d", "#l c #0e0e8d", "cj c #0e0e8e", "b5 c #0f0f8e", "#S c #0f0f8f", "ci c #10108f", "bE c #101090", "b4 c #111190", "c2 c #111191", "#W c #121291", "b9 c #121292", "#b c #131392", "b3 c #131393", "ak c #141493", "aD c #141494", "bG c #151594", "aq c #151595", "bF c #161695", "#i c #161696", "aE c #171796", "ae c #171797", ".5 c #181897", "cq c #181898", "#L c #191998", "bU c #191999", "b2 c #1a1a99", "aL c #1a1a9a", "ds c #1b1b9a", "#A c #1b1b9b", "#k c #1c1c9b", "#f c #1c1c9c", "cG c #1d1d9c", "bM c #1d1d9d", "bN c #1e1e9d", "ch c #1e1e9e", "bL c #1f1f9e", "b1 c #1f1f9f", "#j c #20209f", "bO c #2020a0", "cS c #2121a0", "bY c #2121a1", "db c #2222a1", "bK c #2222a2", "bn c #2323a2", "a# c #2323a3", "bH c #2424a4", "bJ c #2525a4", "a3 c #2525a5", "#o c #2626a5", "df c #2626a6", "#. c #2727a6", "bP c #2727a7", "ai c #2828a7", "cF c #2828a8", "cf c #2929a9", "b0 c #2a2aa9", "#x c #2a2aaa", ".7 c #2b2baa", "bI c #2b2bab", "cy c #2c2cab", "a5 c #2c2cac", "aI c #2d2dac", "#d c #2d2dad", "cp c #2e2ead", "bo c #2e2eae", "ap c #2f2fae", "#1 c #3030b0", "cg c #3131b1", "bZ c #3232b1", "de c #3333b2", "dw c #3333b3", "bQ c #3434b4", "bp c #3535b5", "c3 c #3636b5", "#R c #3636b6", "cC c #3737b7", "aC c #3838b7", "#t c #3838b8", "#T c #3939b8", "#F c #3939b9", "bq c #3a3ab9", "#6 c #3a3aba", "aM c #3c3cbb", "#B c #3d3dbc", "cr c #3d3dbd", "#N c #3e3ebd", "dA c #3e3ebe", "ar c #3f3fbe", "bA c #3f3fbf", "bR c #4040c0", "bS c #4141c0", "dh c #4141c1", "ce c #4242c1", "da c #4343c3", "br c #4444c3", "#X c #4545c4", "a6 c #4545c5", "cM c #4646c5", "bw c #4646c6", "#e c #4747c6", "bs c #4747c7", "bv c #4848c7", "aB c #4848c8", "bt c #4949c8", "bu c #4949c9", "bx c #4a4ac9", "as c #4a4aca", "cs c #4b4bca", "ct c #4b4bcb", "#u c #4c4ccb", "bl c #4c4ccc", "dz c #5050cf", "c6 c #5151d0", "a7 c #5151d1", "by c #5252d1", "#H c #5353d2", "dx c #5454d3", "d# c #5454d4", "at c #5555d5", "aA c #5656d5", "cw c #5656d6", "dy c #5757d6", "bz c #5858d8", "#a c #5959d9", "cE c #5a5ad9", "cL c #5b5bdb", "a8 c #5c5cdb", "aN c #5c5cdc", ".6 c #5d5ddd", "c5 c #5e5edd", "bk c #5e5ede", "dt c #5f5fde", "cT c #6060df", "al c #6262e1", "au c #6262e2", "az c #6464e4", "af c #6565e4", "cD c #6565e5", "#2 c #6666e6", "d. c #6767e7", "co c #6868e7", ".9 c #6868e8", "av c #6969e8", "cN c #6a6aea", "a2 c #6b6bea", "c. c #6b6beb", "dk c #6c6ceb", "aO c #6c6cec", "ay c #6d6dec", "ad c #6e6eee", "ax c #6f6fef", "bD c #7070f0", "#w c #7171f0", "aw c #7171f1", "cu c #7272f1", "c7 c #7272f2", "a9 c #7373f2", "aF c #7373f3", "dn c #7474f4", "b. c #7878f7", "#C c #7979f8", ".4 c #7979f9", "aP c #7a7af9", "aa c #7b7bfa", "b# c #7c7cfb", "cd c #7e7efd", "bX c #7f7ffe", ".3 c #800000", ".1 c #800101", "ba c #8080ff", ".2 c #810101", ".X c #810202", "dp c #8181ff", ".W c #820202", ".Y c #820303", "#5 c #8282ff", ".Z c #830303", "aH c #8383ff", ".R c #840505", "#v c #8484ff", ".S c #850606", "bb c #8585ff", ".T c #860707", "#K c #8686ff", ".U c #870808", ".V c #880808", "aQ c #8888ff", ".Q c #890a0a", "dr c #8989ff", ".K c #8a0a0a", "cz c #8a8aff", ".j c #8b0b0b", "cK c #8b8bff", "bc c #8c8cff", "cU c #8d8dff", ".B c #8e0e0e", ".P c #8e0f0f", "ao c #8e8eff", ".L c #8f0f0f", "cH c #9090ff", "bd c #9292ff", ".C c #931414", "aR c #9393ff", ".O c #941414", "#D c #9494ff", "#O c #9595ff", "cV c #9696ff", ".M c #981818", "#E c #9898ff", ".c c #991a1a", "cO c #9999ff", ".N c #9a1b1b", ".s c #9b1b1b", ".J c #9d1e1e", "be c #9d9dff", "aS c #9e9eff", "dd c #9f9fff", "c8 c #a1a1ff", ".D c #a32424", "#7 c #a3a3ff", "#I c #a5a5ff", ".r c #a72828", "aT c #a7a7ff", "do c #a8a8ff", "cn c #a9a9ff", ".# c #ab2c2c", "c9 c #ababff", ".A c #ac2c2c", "cW c #adadff", "#Y c #aeaeff", ".I c #af2f2f", "du c #b0b0ff", "#0 c #b1b1ff", "c4 c #b2b2ff", "bf c #b3b3ff", ".E c #b43535", "cA c #b4b4ff", "#Q c #b5b5ff", "dv c #b6b6ff", "cl c #b7b7ff", "cX c #b8b8ff", "aU c #b9b9ff", "cc c #babaff", ".i c #bc3c3c", "bW c #bcbcff", "dm c #bdbdff", ".H c #be3f3f", "aZ c #bebeff", "bB c #bfbfff", "aV c #c0c0ff", ".b c #c14141", ".t c #c14242", "bg c #c1c1ff", "#V c #c2c2ff", ".F c #c34343", "#9 c #c3c3ff", "cY c #c4c4ff", "#J c #c5c5ff", "cP c #c6c6ff", "aW c #c7c7ff", "aY c #c8c8ff", ".a c #c94949", "bC c #c9c9ff", ".k c #ca4a4a", "c1 c #cacaff", ".G c #cb4b4b", "aX c #cbcbff", "di c #ccccff", "dj c #cdcdff", "bh c #ceceff", "a1 c #d0d0ff", "c# c #d1d1ff", "c0 c #d2d2ff", "cR c #d3d3ff", ".z c #d45555", "cZ c #d4d4ff", "bT c #d6d6ff", "dl c #d8d8ff", "#3 c #dadaff", "am c #dbdbff", "bi c #dcdcff", "ag c #ddddff", "#P c #dfdfff", "cI c #e1e1ff", "bV c #e4e4ff", ".q c #e66666", "dc c #e6e6ff", "aG c #e7e7ff", ".d c #e86969", "cb c #e8e8ff", "cJ c #eaeaff", "ab c #ececff", ".u c #ed6d6d", "bj c #ededff", "cB c #efefff", "#U c #f0f0ff", "cQ c #f1f1ff", "cv c #f2f2ff", "dq c #f4f4ff", "cm c #f5f5ff", "ca c #f6f6ff", "a0 c #f7f7ff", "an c #f9f9ff", "ah c #fafaff", "#Z c #fbfbff", "ac c #fcfcff", "#8 c #fdfdff", "#4 c #fefeff", ".y c #ff7f7f", ".h c #ff8686", ".v c #ff9292", ".l c #ff9595", ".x c #ff9d9d", ".w c #ffa5a5", ".p c #ffb0b0", ".e c #ffb3b3", ".g c #ffbfbf", ".f c #ffcece", ".m c #ffd9d9", ".o c #ffe8e8", ".n c #fff8f8", ".0 c #ffff00", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.#.a.b.cQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.c.d.e.f.g.h.iQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.j.k.l.m.n.o.p.q.rQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.s.t.u.v.w.x.y.z.A.BQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.C.D.E.F.G.a.H.I.J.BQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.K.L.C.M.N.N.M.O.P.QQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.R.S.T.U.V.V.V.U.T.SQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.W.X.W.W.W.W.Y.Y.Z.RQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.1.1.1.1.1.1.2.W.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.3.3.3.3.3.2.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.4.5.2.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.6.7.8.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.9#..8.0.0.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0###a#b#c.0.0.0.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0#d#e#f#g#h.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0#i#j#k#l#m#h#n#o.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0#p#q#r#s#n#n#m#t#u#v#w#x.0.0.0.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0#y#h#n#m#r#q#z#A#B#C#D#E#F.0.0.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0#r#s#h#h#h#y#r#G#j#H#I#J#K#L.0.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0#n#n#n#y#M#b#N#O#P#Q#R.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0.0.0.0#h#n#h#r#S#T#E#U#V#N.0.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0#h#h#r#W#X#Y#Z#0#1.0.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0#y#q#k#2#3#4#5.5.0.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0#c#z#6#7#8#9#X#q.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0a.a#aaabacadae.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0#m.5afagah#Kai.0.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0.0.0.0.0.0.0.0.0#gaj.0.0.0.0.0.0.0.0.0akalamanaoapaj.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.0.0a.aqa#aparasatauavadawaxayazaAaBaCa#aDaEaFaGanaHaIaJ.0.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtaKaL#xaM#uaNaOaPaQaRaSaT#0aUaVaWaXaXaYaZ#Y#E#.aSa0a1a2a3a4.0.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQt###fa5#Ta6a7a8afaOa9b.b#babbbcbdbeaTbfbgbhbiaGbjbk#3#Z#IblaLajbm.0.0.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtaDbnbobpbqarbrbsbtbuaBbvbw#e#ebx#ubybzaladaaao#7bAbB#8bCbDapbEa.aObqbF.0.0QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtbGbH#dbobI#x.7a5a5#xaibJbK#jbLbMbNbNbObnbP#dbQbRbSaZ#4bTbbarbUa4#ZbVbWbXbr#LQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQt#SbYapbZb0b1b2b2aLbUaEb3b4b5b6b7#G#####Gb7b8#Sb9c.bT#4c#bbbrbL#z#q#Pca#8cbcccdcebFQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQt#icf#taMcgchcicj#Scjb7a4ck#q#g#m#r.8.8.8.8#rblclca#ZaUaF#NbMb8a.#MaQ#0amcmah#Pcncocpa4QtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQt#Gcq.7crcsctcra3b6aJbma.#m.8#c#s#y#y#y#hbJcu#Vcvcvcaaocw#1.5cx#q#rcybSalczcA#PcacBaYaQa6aEQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQt###ka#cCctaNcDazcEbt#tcFch.5cGb0bRazcHbBcIbjbVcJcKcLaCbLbEbm#m.8##bE#AaIcMcNcOcPcbcQcR#EatcSQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtajcj#L#dcCcscTcu#5cUcVbe#IcWcXcYbhcZc0c1cRcUaycsbZbNc2aJ#M.8#ca..8#q##b9bLc3aAbXc4biab#3#7c5#o#pQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQt#qaKb8bGchbSaBc6cE#2c7bX#KbccVc8c9#Qd.d#da#1db#i#laK#M.8#s#sa.#h#y#c#r#pb8cqb0btaF#7a1dccZdda8#o#MQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQt#g#g#paJb8b9.5chbJbI#1c3cC#t#Rde#ddf#jcqb9b6aK#q#r#c#s#y#y.0#h#n#n#h#ydg#M##ak#odhc.dddi#PdjcVd#dbQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQt.8.8#m#M#paK###zcj#SbEbEbE#S#lb7aJaj#q#m.8#c#s#y#h#h#s.0.0.0Qt#m#h#h#y#c#maKb9bndhdkbeaXdldm#vbw#LQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQt#c#c#cdgdg.8#r#m#m#m#m#m#r.8dg#c#s#y#h#h#h#n#h#y.0.0QtQtQtQtQtQtQt#y#y#s#maK#ba3brdndodia1aU#Obyb4QtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQt#s#y#y#y#y#y#y#y#y#y#h#h#h#h#n#n#n#n#n#n#yQtQtQtQtQtQtQtQtQtQtQtQtQt#y#c#maJaDbIa7dpaZdqaha1drbAb3QtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtdg#y#h#h#n#n#n#n#n#n#n#n#n#n#n#n#hdgQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#s#c#Mcxdsc3dtaodudvaScudhdsQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtdg#y#h#h#h#n#n#n#h#y#cQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtdg#pbEb1dwbwdxdydzdA#xaEQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#maJb5bGdsbLbOchaLakb8ckQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#q#qckaKaJ####a4bm#p#pQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#m#c#cdgdgdg.8.8.8#rQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#y#h#h#h#h#h#y#s#rQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#h#n#n#n#n#h#cQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#h#h#yQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt"}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/table.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000716�13513030041�017215� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * table_xpm[] = { "16 16 4 1", " c None", "# c #000000", "o c #777777", ". c #FFFFFF", " ", " ###############", " #ooo#oooo#oooo#", " #ooo#oooo#oooo#", " ###############", " #ooo#....#....#", " #ooo#....#....#", " ###############", " #ooo#....#....#", " #ooo#....#....#", " ###############", " #ooo#....#....#", " #ooo#....#....#", " ###############", " ", " "}; ��������������������������������������������������mathgl-2.4.4/include/xpm/mask_s_.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017541� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_S_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "....########....", "....########....", "....########....", "....########....", "....########....", "....########....", "....########....", "....########....", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_s.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017362� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_s_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", "................", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/norm_1.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017324� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * norm_1_xpm[] = { "16 16 3 1", ". c None", "+ c #7F0000", "@ c #FF0000", "................", "................", "................", "................", "................", "................", "................", ".++++++++++++++.", ".+@@@@@@@@@@@@+.", ".+@@@@@@@@@@@@+.", ".++++++++++++++.", "................", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/right_1.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000650�13513030041�017460� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * right_1_xpm[] = { "16 16 3 1", ". c None", "+ c #7F0000", "@ c #FF0000", "................", "................", "........+.......", "........++......", "........+@+.....", "..+++++++@@+....", "..+@@@@@@@@@+...", "..+@@@@@@@@@@+..", "..+@@@@@@@@@@@+.", "..+@@@@@@@@@@+..", "..+@@@@@@@@@+...", "..+++++++@@+....", "........+@+.....", "........++......", "........+.......", "................"}; ����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_a.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017717� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_a_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ... ", " .... ", " ..... ", " ...... ", "............... ", " ...... ", " ..... ", " .... ", " ... ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_of.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017540� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_of_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ...... ", " .......... ", " ............ ", " .............. ", " .............. ", "................", "................", "................", "................", "................", "................", " .............. ", " .............. ", " ............ ", " .......... ", " ...... "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_vf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017547� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_vf_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", "................", "................", " .............. ", " .............. ", " ............ ", " .......... ", " .......... ", " ........ ", " ...... ", " ...... ", " .... ", " .. "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/preview.xpm����������������������������������������������������������������0000644�0001750�0001750�00000006534�13513030041�017613� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *preview_xpm[] = { "16 16 174 2", " c None", ". c #EA6E0E", "+ c #F67F06", "@ c #E3BB18", "# c #A4E757", "$ c #56E6A3", "% c #25DAD6", "& c #11E5EB", "* c #2AF5D0", "= c #72F588", "- c #B0EC4B", "; c #C7DC34", "> c #C3E336", ", c #98F563", "' c #3FF6BC", ") c #07D5F5", "! c #0E9EEA", "~ c #F44C0A", "{ c #FC0E00", "] c #FB1900", "^ c #FF5B00", "/ c #F7C407", "( c #B5FD49", "_ c #4BFFB3", ": c #0BF6F3", "< c #05D9F9", "[ c #0CD2F2", "} c #14DEEB", "| c #1BF0E3", "1 c #20FEDE", "2 c #27FFD7", "3 c #2BFDD3", "4 c #3BEEC3", "5 c #F14F0A", "6 c #FC1400", "7 c #FB1700", "8 c #FF5000", "9 c #FBBA03", "0 c #B8FD46", "a c #39FCC5", "b c #01CAFE", "c c #0088FF", "d c #0075FF", "e c #008FFF", "f c #01CCFE", "g c #22FCDC", "h c #73FF8B", "i c #BAFC44", "j c #D3E228", "k c #F47B0A", "l c #FF8C00", "m c #F4BA0A", "n c #CBE733", "o c #7DFC81", "p c #2BEDD3", "q c #03C1FB", "r c #0090FF", "s c #0082FF", "t c #009DFF", "u c #08D4F7", "v c #3AFAC4", "w c #98FF66", "x c #E7EF18", "y c #FEBC01", "z c #F4920A", "A c #F4AD0B", "B c #D4F62A", "C c #63FD9B", "D c #16D9E9", "E c #0296FD", "F c #0063FF", "G c #0059FF", "H c #0076FF", "I c #00B6FF", "J c #1AF2E4", "K c #6EFF90", "L c #C8FD36", "M c #F9E306", "N c #FFB900", "O c #FFA800", "P c #F4AF0B", "Q c #EFBD0D", "R c #A0FF5E", "S c #1BF3E3", "T c #009CFF", "U c #0056FF", "V c #0041FF", "W c #005DFF", "X c #00A0FF", "Y c #0EEEF0", "Z c #5FFF9F", "` c #B7FF47", " . c #F1FA0D", ".. c #F9E606", "+. c #F0E70E", "@. c #D4F42A", "#. c #9CF05F", "$. c #F4AA0A", "%. c #DFF01F", "&. c #8DFD71", "*. c #4CF4B2", "=. c #2DDFD1", "-. c #21D5DE", ";. c #1CDFE2", ">. c #20F4DE", ",. c #3BFFC3", "'. c #79FF85", "). c #80FF7E", "!. c #72FE8C", "~. c #51FAAD", "{. c #28EFD6", "]. c #14CDEA", "^. c #F4760A", "/. c #FF6B00", "(. c #FD6D00", "_. c #F87A05", ":. c #F1910C", "<. c #E9B615", "[. c #D8DF26", "}. c #B2FC4C", "|. c #70FF8E", "1. c #2DFED1", "2. c #0BE3F3", "3. c #04B9FB", "4. c #0099FE", "5. c #0085FF", "6. c #007EFF", "7. c #0A84F4", "8. c #F1480A", "9. c #EA0500", "0. c #C50000", "a. c #B30000", "b. c #BB0100", "c. c #DA0600", "d. c #FA3500", "e. c #FCB403", "f. c #ACFD52", "g. c #24F8DA", "h. c #00A5FF", "i. c #0036FF", "j. c #0046FF", "k. c #007FFF", "l. c #11C0EA", "m. c #F4440A", "n. c #E10100", "o. c #B20000", "p. c #990000", "q. c #9B0000", "r. c #B90000", "s. c #EB0500", "t. c #FF6700", "u. c #E9E716", "v. c #75FF89", "w. c #1EE7E0", "x. c #09B9F6", "y. c #06ACF8", "z. c #11C6ED", "A. c #38F0C6", "B. c #8FF26F", "C. c #E9630E", "D. c #F43606", "E. c #E92406", "F. c #E02006", "G. c #DE2006", "H. c #F43706", "I. c #F56806", "J. c #F5A106", "K. c #EBCC11", "L. c #CED92D", "M. c #B9DB41", "N. c #B9DD43", "O. c #C8D933", "P. c #E3CE18", "Q. c #E8AB10", " ", " ", " ", ". + @ # $ % & * = - ; > , ' ) ! ", "~ { ] ^ / ( _ : < [ } | 1 2 3 4 ", "5 6 7 8 9 0 a b c d e f g h i j ", "k l m n o p q r s t u v w x y z ", "A B C D E F G H I J K L M N O P ", "Q R S T U V W X Y Z ` ...+.@.#.", "$.%.&.*.=.-.;.>.,.Z '.).!.~.{.].", "^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.", "8.9.0.a.b.c.d.e.f.g.h.U i.j.k.l.", "m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.", "C.D.E.F.G.E.H.I.J.K.L.M.N.O.P.Q.", " ", " "}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_d.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017722� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_d_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " . ", " ... ", " ..... ", " ....... ", "............... ", " ....... ", " ..... ", " ... ", " . ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_p.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017377� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_p_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "........##......", "........##......", "........##......", "........##......", "........##......", "........##......", "################", "################", "........##......", "........##......", "........##......", "........##......", "........##......", "........##......", "........##......", "........##......"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/tiles.xpm������������������������������������������������������������������0000644�0001750�0001750�00000004613�13513030041�017246� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * tiles_xpm[] = { "16 16 113 2", " c None", ". c #00D9FB", "+ c #00FEC7", "@ c #7DFF1E", "# c #DBDF08", "$ c #EAC004", "% c #E5D403", "& c #FF5D00", "* c #FC1600", "= c #FC2500", "- c #00EAE9", "; c #00E9CA", "> c #05F1B1", ", c #03F8B5", "' c #00FFC7", ") c #00FFD6", "! c #FF5900", "~ c #FD0600", "{ c #FA0000", "] c #FF2600", "^ c #00A1FF", "/ c #00CEFF", "( c #00FEE9", "_ c #00FF71", ": c #80FF12", "< c #CFFF07", "[ c #FF7000", "} c #FF5800", "| c #FE7200", "1 c #F9B100", "2 c #00EDF2", "3 c #1AFF56", "4 c #C1FA00", "5 c #FDD600", "6 c #FFA700", "7 c #FF9200", "8 c #F3D400", "9 c #A0FD21", "0 c #21F996", "a c #ECF100", "b c #FFC900", "c c #FF9B00", "d c #FF9300", "e c #FDA700", "f c #AEFF05", "g c #00F9C7", "h c #00AAFF", "i c #0052FF", "j c #FDCA00", "k c #E6DE00", "l c #FCA900", "m c #ADFF00", "n c #00FCC3", "o c #00C8FF", "p c #0089FF", "q c #0079FE", "r c #0094FF", "s c #00CDFF", "t c #93E71F", "u c #6BF55F", "v c #57FA76", "w c #3EFF80", "x c #1BFF89", "y c #00FF84", "z c #00FF95", "A c #F52C00", "B c #F03200", "C c #F23E00", "D c #FB5B00", "E c #F39E00", "F c #D4EA00", "G c #3BFF31", "H c #00FCD9", "I c #00C2FF", "J c #FE5500", "K c #E70200", "L c #B30000", "M c #9C0000", "N c #A30000", "O c #C30000", "P c #F61400", "Q c #FF9600", "R c #99FD04", "S c #01FDD5", "T c #00A6FF", "U c #0054FF", "V c #0037FF", "W c #EC0400", "X c #BD0000", "Y c #A20000", "Z c #A00000", "` c #B70000", " . c #EA0100", ".. c #FF5600", "+. c #EDE300", "@. c #0CF5CC", "#. c #06D2E4", "$. c #09CEE0", "%. c #18E5C1", "&. c #4AFF6C", "*. c #C1EB09", "=. c #FF7200", "-. c #FE4F00", ";. c #F73E00", ">. c #F03A00", ",. c #F03800", "'. c #F63A00", "). c #E2BD00", "!. c #D0C10A", "~. c #CDC110", "{. c #DFBB02", "]. c #F7B100", "^. c #FF9C00", " ", " ", " . + @ # $ % ", "& * = - ; > , ' ) ", "! ~ { ] ^ / ( _ : < ", "[ } | 1 2 3 4 5 6 ", "7 8 9 0 a b c d ", "e f g h i j k ", "l m n o p q r s ", " t u v w x y z ", " A B C D E F G H I ", "J K L M N O P Q R S T U V ", "} W X Y Z ` ...+. @.#.$.%.&.*.", "=.-.;.>.,.'. ).!.~.{.].^.", " ", " "}; ���������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_n.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000611�13513030041�017367� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_n_xpm[] = { "16 16 1 1", " c None", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; �����������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/zoom_in.xpm����������������������������������������������������������������0000644�0001750�0001750�00000004415�13513030041�017600� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * zoom_in_xpm[] = { "16 16 105 2", " c None", ". c #878B87", "+ c #868C8A", "@ c #888B89", "# c #ACB6BF", "$ c #CDD6DD", "% c #E4E7E9", "& c #929594", "* c #CFD8E0", "= c #D3DDE5", "- c #A4BFDC", "; c #99B9DA", "> c #9AB9DA", ", c #A4BFDD", "' c #CFDAE5", ") c #B4C9DF", "! c #9DBDDD", "~ c #B5CDE6", "{ c #5C84B8", "] c #5B84B8", "^ c #B0CAE4", "/ c #9ABADD", "( c #98B9DC", "_ c #BCD1E8", ": c #5F87B9", "< c #FFFFFF", "[ c #5A84B7", "} c #ABC6E2", "| c #91B4DA", "1 c #868C8B", "2 c #9DBBDA", "3 c #B6CDE6", "4 c #5D85B8", "5 c #5E86B8", "6 c #5982B7", "7 c #5781B6", "8 c #9FBDDE", "9 c #9EBBDA", "0 c #878B88", "a c #8EB2D6", "b c #5983B7", "c c #507DB4", "d c #86ACD4", "e c #89AED4", "f c #4E7BB3", "g c #4A78B2", "h c #878C8B", "i c #CFD8DE", "j c #A7C1DD", "k c #86ADD6", "l c #4F7CB3", "m c #89AED6", "n c #A9C3DE", "o c #D0D8DE", "p c #888B87", "q c #B1BAC1", "r c #D9E1E8", "s c #94B6DA", "t c #96B7DB", "u c #527EB5", "v c #537EB5", "w c #97B8DB", "x c #DAE2E8", "y c #B2BBC1", "z c #8A8C8A", "A c #D7DDE2", "B c #CAD8E6", "C c #A4C0DF", "D c #A6C2E0", "E c #A7C3E1", "F c #D8DEE3", "G c #949895", "H c #DADFE3", "I c #E1E6EA", "J c #C7D7E8", "K c #BDD2E6", "L c #BED2E6", "M c #C8D8E8", "N c #DFE5EA", "O c #DBE0E4", "P c #959896", "Q c #9DA09B", "R c #60625F", "S c #8A8D8A", "T c #BCC1C4", "U c #DCE0E2", "V c #E9EBEB", "W c #BDC2C5", "X c #898C88", "Y c #878A84", "Z c #B9BCB6", "` c #BDBFBC", " . c #61635F", ".. c #8A8C88", "+. c #8D918D", "@. c #8B8D89", "#. c #8E918D", "$. c #575955", "%. c #7A7B78", "&. c #B7B8B6", "*. c #595B57", "=. c #555753", "-. c #767873", ";. c #A0A29F", ">. c #565854", " . + . . + . ", " @ # $ % % $ # @ ", " & * = - ; > , ' * & ", " @ * ) ! ~ { ] ^ / ) * @ ", ". # ' ( _ : < < [ } | ' # . ", "1 $ 2 3 4 5 < < 6 7 8 9 $ + ", "0 % a b < < < < < < c d % . ", "0 % e f < < < < < < g e % . ", "h i j k f f < < l f m n o h ", "p q r s t u < < v ( w x y p ", " z A B C D 7 7 E D B F . ", " G H I J K L M N O P Q R ", " S T U V V U W X Y Z ` . ", " ..+.@.@.#... $.%.Y &.*.", " =.-.;.*.", " =.>. "}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_sf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017544� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_sf_xpm[] = { "16 16 2 1", " c None", ". c #000000", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................", "................"}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_s.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017576� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_s_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ........ ", " ........ ", " ........ ", " ........ ", " ..............", " ........ ", " ........ ", " ........ ", " ........ ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_tf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017545� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_tf_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " .... ", " ...... ", " ...... ", " ........ ", " .......... ", " .......... ", " ............ ", " .............. ", " .............. ", "................", "................", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/update.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000627�13513030041�017411� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *update_xpm[] = { "16 16 2 1", " c None", ". c #00007F", " ", " ", " .... ", " . . ", " . ..... ", " . ... ", " . ", " ", " ", " . ", " ... . ", " ..... . ", " . . ", " .... ", " ", " "}; ���������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper_m.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017412� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_m_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #7F7F7F", " ", " ", " ", " ", " . . ", " +. .+ ", " +.+ ...... ", " ...... ", " +.+ ...... ", " +. .+ ", " . . ", " ", " ", " ", " ", " "}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper_of.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000650�13513030041�017554� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_of_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #FF0000", " . ++ ", " . . ++ ", " . . ++++++", " . .... .++++++", " . . . . ++ ", " . .... . ++ ", " . ", " ..... ", " . . ", " .. . ", " . . . ", " . . ", " .... . . ", ". .. . ..... ", ". . . ", " .. . . "}; ����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_m.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017354� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_m_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ".. .. .. .. ", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000627�13513030041�017220� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark__xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", " .. ", " .. ", " ", " ", " ", " ", " ", " ", " "}; ���������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_e.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017344� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_e_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ". . . . . . . . ", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/last.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017071� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * last_xpm[] = { "16 16 2 1", " c None", ". c #0000FF", " ", " ", " ", " . .. ", " ... .. ", " ..... .. ", " ....... .. ", " ......... .. ", " ............ ", " ............ ", " ......... .. ", " ....... .. ", " ..... .. ", " ... .. ", " . .. ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_r.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017401� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_r_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "..####..........", "..####..........", "..##..####......", "..##..####......", "..##......####..", "..##......####..", "..##..####......", "..##..####......", "..####..........", "..####..........", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_d.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017356� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_d_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", ". .", ". .", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " .. "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_s.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017402� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_s_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "....########....", "....########....", "....##....##....", "....##....##....", "....##....##....", "....##....##....", "....########....", "....########....", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_d.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017363� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_d_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "........##......", "........##......", "......##..##....", "......##..##....", "....##......##..", "....##......##..", "......##..##....", "......##..##....", "........##......", "........##......", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_i.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017370� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_i_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "................", "................", "..######..######", "..######..######", "................", "................", "................", "................", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_l.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017353� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_l_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ".... .... ", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_y.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017403� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_y_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " . . ", " . . ", " . . ", " . . ", " ... ", " . ", " . ", " . ", " . ", " . ", " . ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/tran.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000664�13513030041�017074� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * tran_xpm[] = { "16 16 4 1", " c None", ". c #000000", "+ c #FF0000", "@ c #0000FF", " ", " ", " ......++++++++ ", " . . + ", " . . ..+ + + ++ ", " . . + ", " . . ..+ + + ++ ", " .++++.++++++++ ", " . . .. ", " . . @ ", " . . .. @@@ ", " . . @ ", " . . .. @ ", " . . @@ ", " . . .. @@@ ", " ...... "}; ����������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_l.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017366� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_l_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " .. . ", " . . ", " .. . ", " . . ", " .. . ", " . . ", ". . ", ". . ", " . . ", " .. . ", " . . ", " .. . ", " . . ", " .. . ", " .. "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_a.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017554� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_a_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ... ", " .... ", " ..... ", " ...... ", " ...............", " ...... ", " ..... ", " .... ", " ... ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/integr.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017421� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * integr_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #808080", " ", " ", " ", " . ", " . ", " . . ", " . . ", " . . ", " . ... . . ", " . . . . ", " . . . . ", " . ... . . ", " . + ", " ", " ", " "}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/option.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017441� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * option_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #7F0000", " ", " ", " ", " .. ", " .++. ", " .++. ", " .. ", " ", " ", " .. ", " .++. ", " .++. ", " .+. ++ ++ ++ ", " . ++ ++ ++ ", " . ", " "}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_k.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017566� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_k_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .. ", " .. ... ", " .. .... ", " .. ..... ", " ........ ", " ...............", " ........ ", " .. ..... ", " .. .... ", " .. ... ", " .. ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_p.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017372� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_p_xpm[] = { "16 16 2 1", " c None", ". c #000000", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", "................", " . ", " . ", " . ", " . ", " . ", " . ", " . "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_o.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017376� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_o_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "......####......", "......####......", "....##....##....", "....##....##....", "....##....##....", "....##....##....", "......####......", "......####......", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_a.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017360� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_a_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "##............##", "##............##", "..##........##..", "..##........##..", "....##....##....", "....##....##....", "......####......", "......####......", "......####......", "......####......", "....##....##....", "....##....##....", "..##........##..", "..##........##..", "##............##", "##............##"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_o_.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017535� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_O_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "......####......", "......####......", "....########....", "....########....", "....########....", "....########....", "......####......", "......####......", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_d.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017343� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_d_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ". . . . ", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/up_1.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000645�13513030041�016773� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * up_1_xpm[] = { "16 16 3 1", ". c None", "+ c #7F0000", "@ c #FF0000", "................", "................", "........+.......", ".......+@+......", "......+@@@+.....", ".....+@@@@@+....", "....+@@@@@@@+...", "...+@@@@@@@@@+..", "..++++@@@@@++++.", ".....+@@@@@+....", ".....+@@@@@+....", ".....+@@@@@+....", ".....+@@@@@+....", ".....+@@@@@+....", ".....+++++++....", "................"}; �������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_t.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017403� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_t_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "..####..........", "..####..........", "##....##........", "##....##........", "........##....##", "........##....##", "..........####..", "..........####..", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_s.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017741� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_s_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ........ ", " ........ ", " ........ ", " ........ ", ".............. ", " ........ ", " ........ ", " ........ ", " ........ ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_pf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017541� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_pf_xpm[] = { "16 16 2 1", " c None", ". c #000000", "................", ". . .", ". . .", ". . .", ". . .", ". . .", ". . .", ". . .", "................", ". . .", ". . .", ". . .", ". . .", ". . .", ". . .", "................"}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/alpha.xpm������������������������������������������������������������������0000644�0001750�0001750�00000004453�13513030041�017215� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * alpha_xpm[] = { "16 16 107 2", " c None", ". c #395155", "+ c #3A5155", "@ c #384F54", "# c #4C6A71", "$ c #68929C", "% c #B8FFFF", "& c #B1F9FF", "* c #B7FFFF", "= c #6B939C", "- c #113F4A", "; c #7CADB9", "> c #B4FCFF", ", c #84BAC8", "' c #51585B", ") c #78888C", "! c #79898D", "~ c #4D4D4D", "{ c #17B0D6", "] c #2CE0FF", "^ c #1D99B8", "/ c #1F282B", "( c #A1E2F3", "_ c #ABF0FF", ": c #ACF2FF", "< c #658187", "[ c #E1FFFF", "} c #D7F8FF", "| c #D7F9FF", "1 c #D7F7FF", "2 c #428494", "3 c #28D6FF", "4 c #2AD6FF", "5 c #26C3EA", "6 c #1A88A2", "7 c #346974", "8 c #7BB8C6", "9 c #9FDEEE", "0 c #97D4E3", "a c #C2E2E9", "b c #D6F8FF", "c c #C5E6ED", "d c #2DB7DA", "e c #2AD1FB", "f c #23BFE6", "g c #0B6A81", "h c #42B0CC", "i c #4DB0C8", "j c #3A575C", "k c #7B878A", "l c #7D8A8E", "m c #7D8A8D", "n c #3B4A4E", "o c #0586A5", "p c #00BEED", "q c #005A70", "r c #317F93", "s c #56DFFF", "t c #47AEC7", "u c #7ADDF6", "v c #81ECFF", "w c #84F0FF", "x c #2F7E90", "y c #00DBFF", "z c #0094B9", "A c #3FA4BC", "B c #4CC5E4", "C c #72D1E7", "D c #7FE4FE", "E c #80E5FF", "F c #78D1E8", "G c #0EABD1", "H c #00BBEA", "I c #51D4F4", "J c #3A7888", "K c #85EEFF", "L c #60C0D8", "M c #00B7E6", "N c #0096BB", "O c #215764", "P c #3FA7C0", "Q c #70C6DC", "R c #83ECFF", "S c #378599", "T c #00B1DE", "U c #4AC5E4", "V c #447B89", "W c #82E8FF", "X c #84E4FD", "Y c #007696", "Z c #00556A", "` c #0A1A1E", " . c #4FC5E2", ".. c #75D1E8", "+. c #81E7FF", "@. c #598B98", "#. c #00B1DF", "$. c #235C69", "%. c #6BC4DA", "&. c #82E6FF", "*. c #148099", "=. c #2C5B65", "-. c #74D6F0", ";. c #074F61", ">. c #13353F", ",. c #67B8C9", "'. c #0E191C", " . + + @ ", " # $ % & & * = - ", " ; > , ' ) ! ~ { ] ^ ", " / ( _ : < [ } | 1 2 3 4 5 6 ", " 7 8 9 0 a b } } b c d e f g ", " h i j k l l l l m n o p q ", " r s t u v v v v w x y z ", " A B C D E E E F G H ", " I J K D E E L M N ", " O P Q E E R S T ", " U V W E X Y Z ", " ` ...+.@.#. ", " $.%.&.*. ", " =.-.;. ", " >.,. ", " '. "}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_i.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017564� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_i_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .. ", " .. ", " .. ", " .. ", " .. ", " ...............", " .. ", " .. ", " .. ", " .. ", " .. ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/none.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017065� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * none_xpm[] = { "16 16 2 1", " c None", ". c #000000", "................", ".. ..", ". . . .", ". . . .", ". . . .", ". . . .", ". . . .", ". .. .", ". .. .", ". . . .", ". . . .", ". . . .", ". . . .", ". . . .", ".. ..", "................"}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/rotate.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000644�13513030041�017424� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *rotate_xpm[]={ "16 16 3 1", ". c None", "# c #000080", "a c #8080ff", "......#########.", "......#aaaaaa#..", ".......#aaaa##..", "..###..#aaaaa#..", ".#aa#..#aaa#aa#.", ".#aa#...#a##aa#.", "#aa#....#a#.#aa#", "#aa#.....#..#aa#", "#aa#........#aa#", "#aa#........#aa#", ".#a#........#a#.", ".#aa#......#aa#.", "..#aa##..##aa#..", "...#aaa##aaa#...", "....##aaaa##....", "......####......"}; ��������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_v.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017744� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_v_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ... ", " .... ", " ..... ", " ...... ", "........... ", " ...... ", " ..... ", " .... ", " ... ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_j.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017351� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_j_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ".... . .... .", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_v.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017400� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_v_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", "................", ". .", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " .. "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/text.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017112� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * text_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ............ ", " ............ ", " . .. . ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " .... ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/down_1.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017320� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * down_1_xpm[] = { "16 16 3 1", ". c None", "+ c #7F0000", "@ c #FF0000", "................", "................", ".....+++++++....", ".....+@@@@@+....", ".....+@@@@@+....", ".....+@@@@@+....", ".....+@@@@@+....", ".....+@@@@@+....", "..++++@@@@@++++.", "...+@@@@@@@@@+..", "....+@@@@@@@+...", ".....+@@@@@+....", "......+@@@+.....", ".......+@+......", "........+.......", "................"}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/copy.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000664�13513030041�017102� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * copy_xpm[] = { "16 16 4 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #808080", " ", " ", " ........ ", " .++++++.@ ", " .+@@@@+.@ ", " .++........ ", " .+@.++++++.@ ", " .++.+....+.@ ", " .+@.++++++.@ ", " .++.+....+.@ ", " ....++++++.@ ", " @.+....+.@ ", " .++++++.@ ", " ........@ ", " @@@@@@@@ ", " "}; ����������������������������������������������������������������������������mathgl-2.4.4/include/xpm/curve.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000627�13513030041�017253� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * curve_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .", " .", " . ", " . ", " . ", " . ", " .. ", " .. ", " .. ", " .. ", " . ", " . ", " . ", " . ", ". ", ". "}; ���������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_k.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017731� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_k_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .. ", " ... .. ", " .... .. ", " ..... .. ", " ........ ", "............... ", " ........ ", " ..... .. ", " .... .. ", " ... .. ", " .. ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/size.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017100� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * size_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .............. ", " . . . ", " . ... . ", " . . . ", " . . . ", " . . . . . ", " .............. ", " . . . . . ", " . . . ", " . . . ", " . . . ", " . ... . ", " . . . ", " .............. "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/crop.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017071� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * crop_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " . ", " ", " . ", " ", " . . ...... ", " . . ", " . . ", " . . ", " . . ", " ...... . . ", " ", " . ", " ", " . ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/pause.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000646�13513030041�017245� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * pause_xpm[] = { "16 16 3 1", " c None", ". c #777777", "q c #000000", " ", " ", " ", " qqq qqq ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " qqq qqq ", " ", " ", " "}; ������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/axis_sh.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000650�13513030041�017561� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * axis_sh_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #FF0000", " ", " . ", ". . + ", " . +++ ", " . + ", ". . + + + ", " . +++++++++ ", " . + + + ", ". . + ", " . +++ ", " . + ", ". . ", " . ", " ............. ", ". ", " . . . . . "}; ����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_u.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017404� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_u_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "................", "................", "......####......", "......####......", "....##....##....", "....##....##....", "..##........##..", "..##........##..", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_l.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017373� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_l_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "..........####..", "..........####..", "......####..##..", "......####..##..", "..####......##..", "..####......##..", "......####..##..", "......####..##..", "..........####..", "..........####..", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017073� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " . ", " . ", " ..... ..... ", " . ", " . ", " ", " ", " ", " . . ", " . . . . ", " . ... ", " . ... ", " . . . . ", " . . ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_m.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017374� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_m_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "................", "................", "################", "################", "................", "................", "................", "................", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/axis.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017072� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * axis_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " .. ", " . ", " . ", " .. ", " . ", " . ", " .. ", " . ", " . ", " .. ", " . ", " . ", " .............. ", " . . . . ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/vect.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000001740�13513030041�017065� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * vect_xpm[] = { "16 16 41 1", " c None", ". c #B3FF00", "+ c #AEF900", "@ c #FBF400", "# c #FEF700", "$ c #FFDA00", "% c #AFFB00", "& c #FDF600", "* c #FDF500", "= c #FD9600", "- c #FD9000", "; c #FA8F00", "> c #FEAB00", ", c #FD9500", "' c #FB9400", ") c #FE9100", "! c #FBAA00", "~ c #FCA900", "{ c #FF9700", "] c #FF9200", "^ c #FDA900", "/ c #FDAB00", "( c #FB9D00", "_ c #FC0B00", ": c #FF0A00", "< c #FF4400", "[ c #FB4200", "} c #FC9E00", "| c #FE9F00", "1 c #FD4400", "2 c #FC4400", "3 c #FFA000", "4 c #FB1600", "5 c #FCAD00", "6 c #D00000", "7 c #D20000", "8 c #FD1500", "9 c #FA1500", "0 c #FEAF00", "a c #D10000", "b c #FDAE00", " .+ @# $ ", " % &@ $ ", ". & ", " * ", " = -; >", " ,' ) !~", "{ ] ^ ", " ] / ", " (", " _: <[ }|", " _ 12 3 ", " < | ", " ", " 4 5", " 67 89 50", "a 8 b "}; ��������������������������������mathgl-2.4.4/include/xpm/polygon.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017615� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *polygon_xpm[]={ "16 16 2 1", " c None", ". c #000000", " ", " .. ", " . . ", " .. .. ", " . . ", " .. .. ", ". .", ". .", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " .......... "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_df.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017525� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_df_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " .... ", " ...... ", " ........ ", " .......... ", " ............ ", " .............. ", "................", "................", " .............. ", " ............ ", " .......... ", " ........ ", " ...... ", " .... ", " .. "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/first.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000627�13513030041�017256� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * first_xpm[] = { "16 16 2 1", " c None", ". c #0000FF", " ", " ", " ", " .. . ", " .. ... ", " .. ..... ", " .. ....... ", " .. ......... ", " ............ ", " ............ ", " .. ......... ", " .. ....... ", " .. ..... ", " .. ... ", " .. . ", " "}; ���������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_n.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017571� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_n_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", " ..............", " ", " ", " ", " ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/unused/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�13513030041�016677� 5����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/unused/sum.xpm�������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�020234� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * sum_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .......... ", " . . ", " . . ", " . ", " . ", " . ", " .. ", " . ", " . ", " . ", " . . ", " . . ", " .......... ", " "}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/unused/swap.xpm������������������������������������������������������������0000644�0001750�0001750�00000000664�13513030041�020405� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * swap_xpm[] = { "16 16 4 1", " c None", ". c #0000FF", "+ c #000000", "@ c #FF0000", " ", " . .. ", " . . ", " . . ", " . . ", " ...... ", " + + ", " + + ", " + + ", " + + + + ", " ++ @@@ ++ ", " +++ @ @ +++ ", " @ @ ", " @ @ ", " @@@ @@@ ", " "}; ����������������������������������������������������������������������������mathgl-2.4.4/include/xpm/unused/smth.xpm������������������������������������������������������������0000644�0001750�0001750�00000000645�13513030041�020405� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * smth_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #FF0000", " ", " ", " ", " ", " . ", " . ", " . . . ", " . . .. ", " +++. . . ", " +. ++ +++. ", " . .++ ++ ", " . . . .+ ", " . . . . ", " . ", " . ", " "}; �������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_a.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017353� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_a_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " . . ", " . . ", " . . ", " . . ", " . . ", " ... ", " .............. ", " ... ", " . . ", " . . ", " . . ", " . . ", " . . ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_lf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017535� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_lf_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " .... ", " ..... ", " ....... ", " ........ ", " .......... ", " ........... ", "............ ", "............ ", " ........... ", " .......... ", " ........ ", " ....... ", " ..... ", " .... ", " .. "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/insert.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000666�13513030041�017436� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * insert_xpm[] = { "16 16 4 1", " c None", ". c #0000FF", "# c #000000", "w c #FFFFFF", " ", " ", ". ############ ", ".. #wwwwwwwwww# ", "...#w########w# ", "....wwwwwwwwww# ", ".....########w# ", "......wwwwwwww# ", ".......######w# ", "........wwwwww# ", ".......######w# ", "......wwwwwwww# ", ".....########w# ", "....wwwwwwwwww# ", "...############ ", ".. "}; ��������������������������������������������������������������������������mathgl-2.4.4/include/xpm/plot.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000664�13513030041�017106� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * plot_xpm[] = { "16 16 4 1", " c None", ". c #000000", "+ c #0000FF", "@ c #FF0000", " ", " . ", ".. + ", " . ++ ", " . + ", ".. + ", " . + ", " . + ", ".. @@@+ ", " . @ +@ @ ", " .@@ + @ @ ", ".. + @@@ ", " . ++ ", " .++ ", "............... ", " . . . . "}; ����������������������������������������������������������������������������mathgl-2.4.4/include/xpm/delete.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017363� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * delete_xpm[] = { "16 16 2 1", " c none", ". c #000000", " ", " ", " ", " ... ... ", " ... ... ", " ... ... ", " ...... ", " .... ", " .... ", " ...... ", " ... ... ", " ... ... ", " ... ... ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_t.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017577� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_t_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " .. ", " .... ", " ...... ", " ........ ", " ...............", " ........ ", " ...... ", " .... ", " .. ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/other.xpm������������������������������������������������������������������0000644�0001750�0001750�00000004232�13513030041�017244� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * other_xpm[] = { "16 16 98 2", " c None", ". c #FFFFFF", "+ c #00CAFF", "@ c #00ADFF", "# c #0000EB", "$ c #00007F", "% c #0000B4", "& c #0000B9", "* c #00D1FF", "= c #73FF8B", "- c #68FF96", "; c #00BFFF", "> c #0000C3", ", c #0000C7", "' c #01DDFD", ") c #0041FF", "! c #0DFBF1", "~ c #3EFFC0", "{ c #00EEFF", "] c #0024FF", "^ c #000082", "/ c #000083", "( c #2EFFD0", "_ c #00E9FF", ": c #0001EA", "< c #0074FF", "[ c #009CFF", "} c #0058FF", "| c #0000D5", "1 c #009FFF", "2 c #63FF9B", "3 c #0000C1", "4 c #00009D", "5 c #0000F7", "6 c #0042FF", "7 c #0030FF", "8 c #0000DC", "9 c #000080", "0 c #0017FE", "a c #00E0FF", "b c #0000F6", "c c #0075FF", "d c #0094FF", "e c #0044FF", "f c #0000BE", "g c #000086", "h c #000BFE", "i c #004FFF", "j c #0000AC", "k c #006EFF", "l c #10FEEE", "m c #35FFC9", "n c #0000C9", "o c #0083FF", "p c #0031FF", "q c #000090", "r c #0007F9", "s c #0BF9F3", "t c #7EFF80", "u c #58FFA6", "v c #007DFF", "w c #000085", "x c #1FFFDF", "y c #000081", "z c #0039FF", "A c #00DBFF", "B c #01BDFD", "C c #0AFEF4", "D c #0000AA", "E c #00009A", "F c #001BFC", "G c #00C9FE", "H c #4BFFB3", "I c #0006F7", "J c #008FFF", "K c #6FFF8F", "L c #F5FF09", "M c #FFDB00", "N c #F1FB0D", "O c #0021FF", "P c #0000EA", "Q c #13FCEB", "R c #F0FF0E", "S c #FF8700", "T c #FF5B00", "U c #EDFC11", "V c #12FDEC", "W c #0003E9", "X c #00B7FF", "Y c #98FF66", "Z c #FFDF00", "` c #FFB300", " . c #00B8FF", ".. c #0067FF", "+. c #04E9FA", "@. c #1DFCE1", "#. c #00EDFF", "$. c #000088", " + @ # $ $ % ", " & * = - ; > $ $ , ' ", " $ $ ) ! ~ { ] ^ $ $ / ( _ ", " $ $ : < [ } | $ $ $ $ 1 2 3 ", " $ $ 4 5 6 7 8 9 $ $ $ 0 a 7 $ ", " $ $ / b c d e f $ $ g h i 8 $ ", " $ $ j k l m * # $ $ n o p q $ ", " $ $ r s t u v w $ $ j x 1 y $ ", " $ $ z A B $ $ $ $ $ $ C ~ D $ ", " $ $ $ $ E F [ G [ 0 E $ H I $ ", " $ $ $ D J K L M N K J D $ O $ ", " $ $ P Q R S T S U V W $ $ $ ", " $ f X Y Z ` Z Y .f $ $ $ ", " $ > ..+.@.#...> $ $ ", " $ $ y $.^ $ ", " $ $ $ "}; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_rf.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017543� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_rf_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " .... ", " ..... ", " ....... ", " ........ ", " .......... ", " ........... ", " ............", " ............", " ........... ", " .......... ", " ........ ", " ....... ", " ..... ", " .... ", " .. "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/ok.xpm���������������������������������������������������������������������0000644�0001750�0001750�00000000644�13513030041�016537� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * ok_xpm[] = { "16 16 3 1", " c None", "! c #000090", "# c #0000FF", " ", " # ", " ## ", " ##! ", " ##! ", " ##! ", " ##! ", " ##! ", " ##! ", " ### ###! ", " ### ##! ", " #####! ", " ###! ", " ##! ", " #! ", " ! "}; ��������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/zoom_1.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017335� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * zoom_1_xpm[] = { "16 16 3 1", ". c None", "+ c #7F0000", "@ c #FF0000", "................", "................", "......++++......", "......+@@+......", "......+@@+......", "......+@@+......", "......+@@+......", ".++++++@@++++++.", ".+@@@@@@@@@@@@+.", ".+@@@@@@@@@@@@+.", ".++++++@@++++++.", "......+@@+......", "......+@@+......", "......+@@+......", "......+@@+......", "......++++......"}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_x.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017402� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_x_xpm[] = { "16 16 2 1", " c None", ". c #000000", ". .", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " .. ", " .. ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", ". ."}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_j.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017371� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_j_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "................", "................", "................", "................", "..##..##########", "..##..##########", "................", "................", "................", "................", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_r.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017374� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_r_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " . .. ", " . . ", " . .. ", " . . ", " . .. ", " . . ", " . .", " . .", " . . ", " . .. ", " . . ", " . .. ", " . . ", " . .. ", " .. "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_o.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017572� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_o_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " .... ", " ...... ", " ........ ", " ........ ", " ..............", " ........ ", " ........ ", " ....... ", " .... ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper_a.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017366� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_a_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " . ", " . ", " . ...... ", " ....... ", " . ...... ", " . ", " . ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper_dir.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000632�13513030041�017726� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_dir_xpm[] = { "16 16 2 1", " c None", ". c #000000", " . ", " . . ", " . . ", " . .... . ", " . . . . ", " . .... . ", " . ", " ..... ", " . . ", " .. . ", " . . . ", " . . ", " .... . . ", ". .. . ..... ", ". . . ", " .. . . "}; ������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_o.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017371� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_o_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ...... ", " .. .. ", " . . ", " . . ", " . . ", ". .", ". .", ". .", ". .", ". .", ". .", " . . ", " . . ", " . . ", " .. .. ", " ...... "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_n.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017734� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_n_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ".............. ", " ", " ", " ", " ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/hist.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017075� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * hist_xpm[] = { "16 16 2 1", " c None", ". c #0000FF", " ", " ", " ... ", " ... ", " ... ", " ... ... ", " ... ... ", " ... ... ", " ... ... ", " ... ... ", " ... ... ... ", " ... ... ... ", "... ... ... ... ", "... ... ... ... ", "... ... ... ... ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/dash_i.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017350� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * dash_i_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ", ".. . .. . .. . .", " ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/squize.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017451� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * squize_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #7F7F7F", " ", " ", " ...... ", " . . ", " . . ", " . . . . ", " +. . . .+ ", "...... ......", " +. . . .+ ", " . . . . ", " . . ", " . . ", " . . ", " ...... ", " ", " "}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_i.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017727� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_i_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .. ", " .. ", " .. ", " .. ", " .. ", "............... ", " .. ", " .. ", " .. ", " .. ", " .. ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/wire.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017074� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * wire_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " . . ", " . . ", " . . ", " ............ ", " . . ", " . . ", " . . ", " . . ", " ............ ", " . . ", " . . ", " . . ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/box.xpm��������������������������������������������������������������������0000644�0001750�0001750�00000000644�13513030041�016716� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * box_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #666666", " ", " ......... ", " .+ .. ", " . + . . ", " . + . . ", " . + . . ", " ......... . ", " . + . . ", " . + . . ", " . +++.++++. ", " . + . . ", " . + . . ", " . + . . ", " .+ .. ", " ......... ", " "}; ��������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/line.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017055� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * line_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", ". "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/window.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000001056�13513030041�017433� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * window_xpm[] = { "16 16 10 1", " c None", ". c #000000", "+ c #333377", "@ c #FFFFFF", "# c #777777", "$ c #00007F", "% c #4444FF", "& c #FF0000", "* c #007F00", "= c #7F0000", " ", " ", ".............. ", ".++++++++++++. ", ".@@@@@#@@@@@@. ", ".@$.............", ".@@.%%%%%%%%%%%.", ".@$.@@@@@#@@@@@.", ".@@.@$$@@#@@@@@.", ".@$.@@@@@#@@@@@.", ".@@.@$&*@#@@@@@.", "....@@@@@#@@@@@.", " .@$&=@#@@@@@.", " .@@@@@#@@@@@.", " .............", " "}; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_t.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017376� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_t_xpm[] = { "16 16 2 1", " c None", ". c #000000", " .. ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", " . . ", ". .", "................", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/oper_s.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017410� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * oper_s_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " ", " ", " ", " ...... ", " ....... ", " ...... ", " ", " ", " ", " ", " ", " ", " "}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/next.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017100� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * next_xpm[] = { "16 16 2 1", " c #E7E7E7", ". c #0000FF", " ", " ", " ", " . ", " ... ", " ..... ", " ....... ", " ......... ", " ........... ", " ........... ", " ......... ", " ....... ", " ..... ", " ... ", " . ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/fileprint.xpm��������������������������������������������������������������0000644�0001750�0001750�00000000704�13513030041�020117� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *fileprint[] = { " 16 14 6 1", ". c #000000", "# c #848284", "a c #c6c3c6", "b c #ffff00", "c c #ffffff", "d c None", "ddddd.........dd", "dddd.cccccccc.dd", "dddd.c.....c.ddd", "ddd.cccccccc.ddd", "ddd.c.....c....d", "dd.cccccccc.a.a.", "d..........a.a..", ".aaaaaaaaaa.a.a.", ".............aa.", ".aaaaaa###aa.a.d", ".aaaaaabbbaa...d", ".............a.d", "d.aaaaaaaaa.a.dd", "dd...........ddd" }; ������������������������������������������������������������mathgl-2.4.4/include/xpm/func.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017061� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * func_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " . . . ", " . . . ", " . . . ", " ... . . . . ", " . . . . . ", " . . .. . ", " . . .. . ", " . . . . . ", " . . . . . ", " . . ", " . . ", " ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/barrow_t.xpm���������������������������������������������������������������0000644�0001750�0001750�00000000623�13513030041�017742� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ const char * barrow_t_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " .. ", " .... ", " ...... ", " ........ ", "............... ", " ........ ", " ...... ", " .... ", " .. ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/zoom_out.xpm���������������������������������������������������������������0000644�0001750�0001750�00000004556�13513030041�020007� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * zoom_out_xpm[] = { "16 16 111 2", " c None", ". c #878B87", "+ c #868C8A", "@ c #888B89", "# c #ACB6BF", "$ c #CDD6DD", "% c #E4E7E9", "& c #929594", "* c #CFD8E0", "= c #D3DDE5", "- c #A4BFDC", "; c #99B9DA", "> c #9AB9DA", ", c #A4BFDD", "' c #CFDAE5", ") c #B4C9DF", "! c #9DBDDD", "~ c #B5CDE6", "{ c #5C84B8", "] c #5B84B8", "^ c #B0CAE4", "/ c #9ABADD", "( c #98B9DC", "_ c #BCD1E8", ": c #5F87B9", "< c #FFFFFF", "[ c #5A84B7", "} c #ABC6E2", "| c #91B4DA", "1 c #868C8B", "2 c #9DBBDA", "3 c #B6CDE6", "4 c #5D85B8", "5 c #5982B7", "6 c #A7C3E1", "7 c #9FBDDE", "8 c #9EBBDA", "9 c #878B88", "0 c #8EB2D6", "a c #5A83B7", "b c #5681B6", "c c #9EBDDE", "d c #86ACD4", "e c #89AED4", "f c #8AAFD7", "g c #94B6DB", "h c #547FB5", "i c #507DB4", "j c #85ACD5", "k c #7BA5D2", "l c #878C8B", "m c #CFD8DE", "n c #A7C1DD", "o c #86ADD6", "p c #89AED6", "q c #4E7BB3", "r c #4F7CB3", "s c #8BB0D7", "t c #A9C3DE", "u c #D0D8DE", "v c #888B87", "w c #B1BAC1", "x c #D9E1E8", "y c #94B6DA", "z c #96B7DB", "A c #527EB5", "B c #537EB5", "C c #97B8DB", "D c #DAE2E8", "E c #B2BBC1", "F c #8A8C8A", "G c #D7DDE2", "H c #CAD8E6", "I c #A4C0DF", "J c #A6C2E0", "K c #5781B6", "L c #D8DEE3", "M c #949895", "N c #DADFE3", "O c #E1E6EA", "P c #C7D7E8", "Q c #BDD2E6", "R c #BED2E6", "S c #C8D8E8", "T c #DFE5EA", "U c #DBE0E4", "V c #959896", "W c #9DA09B", "X c #60625F", "Y c #8A8D8A", "Z c #BCC1C4", "` c #DCE0E2", " . c #E9EBEB", ".. c #BDC2C5", "+. c #898C88", "@. c #878A84", "#. c #B9BCB6", "$. c #BDBFBC", "%. c #61635F", "&. c #8A8C88", "*. c #8D918D", "=. c #8B8D89", "-. c #8E918D", ";. c #575955", ">. c #7A7B78", ",. c #B7B8B6", "'. c #595B57", "). c #555753", "!. c #767873", "~. c #A0A29F", "{. c #565854", " . + . . + . ", " @ # $ % % $ # @ ", " & * = - ; > , ' * & ", " @ * ) ! ~ { ] ^ / ) * @ ", ". # ' ( _ : < < [ } | ' # . ", "1 $ 2 3 4 < < < 5 6 7 8 $ + ", "9 % 0 ^ [ a < < b c | d % . ", "9 % e f g h < < i j k e % . ", "l m n o p q < < r s p t u l ", "v w x y z A < < B ( C D E v ", " F G H I J K K 6 J H L . ", " M N O P Q R S T U V W X ", " Y Z ` . .` ..+.@.#.$.%. ", " &.*.=.=.-.&. ;.>.@.,.'.", " ).!.~.'.", " ).{. "}; ��������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/folder.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000004554�13513030041�017405� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * folder_xpm[] = { "16 16 111 2", " c None", ". c #7A7A7A", "+ c #797979", "@ c #787878", "# c #C9C9C9", "$ c #C7C7C7", "% c #C5C5C5", "& c #C4C4C4", "* c #B4B4B4", "= c #747474", "- c #737373", "; c #B0B0B0", "> c #ADADAD", ", c #ABABAB", "' c #AAAAAA", ") c #ACACAC", "! c #8D8D8D", "~ c #8C8C8C", "{ c #808080", "] c #6C6C6C", "^ c #6E6E6E", "/ c #C1C1C0", "( c #A7A7A7", "_ c #A5A5A5", ": c #A4A4A4", "< c #B6B6B6", "[ c #B9B9B9", "} c #BBBBBB", "| c #A2A2A2", "1 c #6A6A6A", "2 c #BDBDBD", "3 c #416DA6", "4 c #3666A5", "5 c #3566A4", "6 c #3465A4", "7 c #3768A6", "8 c #656565", "9 c #B7B7B7", "0 c #3566A5", "a c #BED3EA", "b c #BFD4EA", "c c #BED4EA", "d c #BED3E9", "e c #B8CFE8", "f c #3465A5", "g c #5F5F5F", "h c #B3B3B3", "i c #C1D5EA", "j c #91B4DB", "k c #91B5DB", "l c #92B5DB", "m c #96B8DC", "n c #B7CFE7", "o c #3466A4", "p c #5B5B5B", "q c #AEAEAE", "r c #3667A5", "s c #C4D7EB", "t c #94B7DC", "u c #91B4DA", "v c #B6CDE6", "w c #565656", "x c #A9A9A9", "y c #3666A4", "z c #C6D8EC", "A c #99BADD", "B c #95B7DC", "C c #8EB2DA", "D c #8BB0D9", "E c #B8CFE7", "F c #515151", "G c #A5A5A4", "H c #3767A5", "I c #BED2E9", "J c #9BBADD", "K c #99B9DD", "L c #95B6DC", "M c #90B3DA", "N c #8EB2D9", "O c #89AED8", "P c #87ADD7", "Q c #8BB0D8", "R c #B1C9E5", "S c #4C4C4C", "T c #A1A1A1", "U c #3868A5", "V c #A9C4E2", "W c #81A8D5", "X c #7AA4D3", "Y c #7EA7D4", "Z c #9CBADD", "` c #484848", " . c #9B9B9B", ".. c #3867A4", "+. c #85ABD5", "@. c #6E9CCE", "#. c #6D9CCE", "$. c #709ECF", "%. c #84ABD5", "&. c #494949", "*. c #999999", "=. c #3968A5", "-. c #7EA6D3", ";. c #78A3D2", ">. c #79A4D3", ",. c #7AA5D1", "'. c #788697", "). c #3A69A5", "!. c #5083BA", "~. c #4578B2", "{. c #464D53", " ", ". + + + + + + ", "@ # $ % & & * = ", "- % ; > , ' ) ! ! ~ ~ ~ { ] ", "^ / ) ' ( _ : : ) < [ } | 1 ", "1 2 3 4 4 4 4 4 5 5 5 5 6 6 6 7 ", "8 9 0 a b b c c c d d d d d e f ", "g h 5 i j j k k l l l l l m n o ", "p q r s t t t t t t t t t u v 0 ", "w x y z A A A A A A A B C D E 0 ", "F G H I J K L l M N O P P Q R 0 ", "S T U V W X X X X X X X X Y Z 0 ", "` ...+.@.#.#.#.#.#.#.#.#.$.%.0 ", "&.*.=.-.;.;.;.;.;.;.;.;.;.>.,.0 ", "` '.).!.!.!.!.!.!.!.!.!.!.!.~.4 ", "{.6 6 6 6 6 6 6 6 6 6 6 6 6 5 "}; ����������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/show_sl.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000650�13513030041�017601� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * show_sl_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #007FFF", " ", " ", " ............ ", " . .++++++. . ", " ...++++++... ", " . .++++++. . ", " . .++++++. . ", " ...++++++... ", " . .++++++. . ", " . .++++++. . ", " ...++++++... ", " . .++++++. . ", " . .++++++. . ", " ...++++++... ", " . .++++++. . ", " ............ "}; ����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/diff.xpm�������������������������������������������������������������������0000644�0001750�0001750�00000000626�13513030041�017036� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * diff_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " .. ", " . . . ", " . . ", " .... . ", " . . . .. ", " . . . . . ", " .. . . ", " . .... ", " . . . ", " . . . . .", " . .. . ", " . .", " ", " "}; ����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mask_d_.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000625�13513030041�017522� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char *mask_D_xpm[]={ "16 16 2 1", ". c None", "# c #000000", "................", "................", "........##......", "........##......", "......######....", "......######....", "....##########..", "....##########..", "......######....", "......######....", "........##......", "........##......", "................", "................", "................", "................"}; �����������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/light.xpm������������������������������������������������������������������0000644�0001750�0001750�00000001324�13513030041�017231� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * light_xpm[] = { "16 16 23 1", " c None", "! c #000000", "# c #808080", "$ c #808000", "% c #606040", "& c #C0C0C0", "' c #808040", "( c #FFFF00", ") c #A0A000", "* c #202000", "+ c #404000", ", c #C0C000", "- c #E0E000", ". c #408040", "0 c #008080", "1 c #408080", "2 c #FFFFC0", "3 c #C0C080", "4 c #FFFFFF", "5 c #FFFF80", "6 c #FFFF40", "7 c #606000", "8 c #206040", " # # ", " #$%&&'$# ", " '()*+,-% ", " $.0000.+ ", " #'+01&223.0+'# ", "&$(.1455555..($#", " %)0&566((-$0)% ", " &*055((((-)0*& ", " &+056((((-)0+& ", " ',035(((-,70,' ", "&$-.8,---,,8.-$#", " #%*08$))780*%# ", " $.0000.+ ", " '()*+,-% ", " #$%&&'$# ", " # # "}; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/left_1.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000647�13513030041�017303� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * left_1_xpm[] = { "16 16 3 1", ". c None", "+ c #7F0000", "@ c #FF0000", "................", "................", ".......+........", "......++........", ".....+@+........", "....+@@+++++++..", "...+@@@@@@@@@+..", "..+@@@@@@@@@@+..", ".+@@@@@@@@@@@+..", "..+@@@@@@@@@@+..", "...+@@@@@@@@@+..", "....+@@+++++++..", ".....+@+........", "......++........", ".......+........", "................"}; �����������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/arrow_d.xpm����������������������������������������������������������������0000644�0001750�0001750�00000000631�13513030041�017557� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * arrow_d_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " ", " ", " . ", " ... ", " ..... ", " ....... ", " ...............", " ....... ", " ..... ", " ... ", " . ", " ", " ", " ", " "}; �������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/diff2.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000646�13513030041�017122� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * diff2_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #7F7F7F", " ", " ", " ", " ", " . ", " .. ", " .+.. ", " +. ..+ ", " . .. ", " .+ +.. ", " +. ..+ ", " . .. ", " .+ +.. ", " ............ ", " ", " "}; ������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/style.xpm������������������������������������������������������������������0000644�0001750�0001750�00000000646�13513030041�017270� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * style_xpm[] = { "16 16 3 1", " c None", ". c #FF0000", "q c #7F0000", " ", " ", " ", " qqq qqq ", " q.q q.q ", " q.q q.q ", " q.q q.q ", " q q ", " q q ", " ", " ", " ", " ", " ", " ", " "}; ������������������������������������������������������������������������������������������mathgl-2.4.4/include/xpm/mark_s.xpm�����������������������������������������������������������������0000644�0001750�0001750�00000000630�13513030041�017375� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* XPM */ static const char * mark_s_xpm[] = { "16 16 2 1", " c None", ". c #000000", "................", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", ". .", "................"}; ��������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/config.h.in��������������������������������������������������������������������0000644�0001750�0001750�00000003443�13513030041�016617� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _MGL_CONFIG_H_ #define _MGL_CONFIG_H_ #define MGL_VER2 ${MathGL_VERSION_MINOR}.${MathGL_PATCH_VERSION} // minor version of MathGL 2.* (like 1.3 for v.2.1.3) #define MGL_VER_MAJOR ${MathGL_VERSION_MAJOR} #define MGL_VER_MINOR ${MathGL_VERSION_MINOR} #define MGL_VER_PATCH ${MathGL_PATCH_VERSION} #define MGL_VERSION (${MathGL_VERSION_MAJOR}000+${MathGL_VERSION_MINOR}.${MathGL_PATCH_VERSION}) #define MGL_VER_STRING "${MathGL_VERSION_MAJOR}.${MathGL_VERSION_MINOR}.${MathGL_PATCH_VERSION}" #define MGL_USE_DOUBLE ${MGL_USE_DOUBLE} #ifdef WIN32 // a man ask to use built-in font under Windows #define MGL_DEF_FONT_NAME "" #else #define MGL_DEF_FONT_NAME "${MGL_DEF_FONT}" #endif #define MGL_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}" #if defined(_MSC_VER) || defined(__BORLANDC__) #define MGL_SYS_NAN 0 #define MGL_HAVE_PTHREAD 0 #define MGL_HAVE_PTHR_WIDGET 0 #define MGL_HAVE_ATTRIBUTE 0 #define MGL_HAVE_C99_COMPLEX 0 #else #define MGL_SYS_NAN ${MGL_HAVE_NAN_INF} #define MGL_HAVE_PTHREAD ${MGL_HAVE_PTHREAD} #define MGL_HAVE_PTHR_WIDGET ${MGL_HAVE_PTHR_WIDGET} #define MGL_HAVE_ATTRIBUTE ${MGL_HAVE_ATTRIBUTE} #define MGL_HAVE_C99_COMPLEX ${MGL_HAVE_C99_COMPLEX} #endif #define MGL_SIZEOF_LONG ${SIZEOF_LONG} #define MGL_HAVE_LTDL ${MGL_HAVE_LTDL} #define MGL_HAVE_RVAL ${MGL_HAVE_RVAL} #define MGL_HAVE_ZLIB ${MGL_HAVE_ZLIB} #define MGL_HAVE_PNG ${MGL_HAVE_PNG} #define MGL_HAVE_GSL ${MGL_HAVE_GSL} #define MGL_HAVE_OPENGL ${MGL_HAVE_OPENGL} #define MGL_HAVE_OMP ${MGL_HAVE_OMP} #define MGL_HAVE_JPEG ${MGL_HAVE_JPEG} #define MGL_HAVE_GIF ${MGL_HAVE_GIF} #define MGL_HAVE_PDF ${MGL_HAVE_PDF} #define MGL_HAVE_HDF4 ${MGL_HAVE_HDF4} #define MGL_HAVE_HDF5 ${MGL_HAVE_HDF5} #define MGL_USE_GETTEXT ${MGL_USE_LIBINTL} #define MGL_FONT_PATH "${MGL_FONT_PATH}" #define MGL_HAVE_FL_COPY ${MGL_HAVE_FL_COPY} #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/include/build.h.in���������������������������������������������������������������������0000644�0001750�0001750�00000000135�13513030041�016444� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _MGL_BUILD_H_ #define _MGL_BUILD_H_ #define MGL_BUILD_DATE "${MathGL_DATE}" #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/AUTHORS��������������������������������������������������������������������������������0000644�0001750�0001750�00000000357�13513030041�014222� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Author of MathGL: Alexey Balakin Some extensions was written by: Dmitriy Kulagin - cmake script Mikhail Vidassov - U3D/PDF/OBJ export Mikhail Barg - Pascal/Delphi interface Sergey Plis - Forth interface���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/CMakeLists.txt�������������������������������������������������������������������������0000644�0001750�0001750�00000070227�13513030041�015715� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cmake_minimum_required(VERSION 3.1.0) project( MathGL2 ) set(mgl_clean_files ) set(MGL_DEP_LIBS) add_definitions(-DMGL_SRC) #add_definitions(-DZLIB_WINAPI) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${MathGL2_SOURCE_DIR}/scripts) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE) endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_VERBOSE_MAKEFILE ON) set(MathGL_VERSION_MAJOR 2) set(MathGL_VERSION_MINOR 4) set(MathGL_PATCH_VERSION 4) set(MathGL_VERSION ${MathGL_VERSION_MAJOR}.${MathGL_VERSION_MINOR}.${MathGL_PATCH_VERSION}) set(MathGL_SOVERSION 7.5.0) string(TIMESTAMP MathGL_DATE UTC) if(CMAKE_BUILD_TYPE STREQUAL "Debug") option(enable-lcov "Enable coverage." OFF) if(enable-lcov) include(CodeCoverage) APPEND_COVERAGE_COMPILER_FLAGS() endif(enable-lcov) else(CMAKE_BUILD_TYPE STREQUAL "Debug") unset(enable-lcov CACHE) endif(CMAKE_BUILD_TYPE STREQUAL "Debug") #set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1) set(MathGL_INSTALL_LIB_DIR "lib" CACHE PATH "Installation directory for libraries") set(MathGL_INSTALL_BIN_DIR "bin" CACHE PATH "Installation directory for executables") set(MathGL_INSTALL_INCLUDE_DIR "include" CACHE PATH "Installation directory for headers") if(WIN32 AND NOT CYGWIN) set(DEF_INSTALL_CMAKE_DIR cmake) else() set(DEF_INSTALL_CMAKE_DIR lib/cmake/mathgl) endif() set(MathGL_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") # Make relative paths absolute (needed later on) foreach(p LIB BIN INCLUDE CMAKE) set(var MathGL_INSTALL_${p}_DIR) if(NOT IS_ABSOLUTE "${${var}}") set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") endif() endforeach() macro(mgl_po_src) set(l_files ) foreach(src_file ${ARGN}) get_filename_component(fp ${src_file} ABSOLUTE) file(RELATIVE_PATH rel ${CMAKE_SOURCE_DIR} ${fp}) list(APPEND l_files "${rel}") endforeach(src_file ${ARGN}) set(po_files ${po_files} ${l_files} PARENT_SCOPE) endmacro(mgl_po_src) function(mgl_add_lib mgl_tmp_lib) if(${mgl_tmp_lib} MATCHES mgl) set(mgllib mgl) set(mgllib2 mgl2) else(${mgl_tmp_lib} MATCHES mgl) set(mgllib mgl-${mgl_tmp_lib}) set(mgllib2 mgl2-${mgl_tmp_lib}) endif(${mgl_tmp_lib} MATCHES mgl) set(mgl_src_lst ${ARGV}) list(REMOVE_AT mgl_src_lst 0) add_library(${mgllib} SHARED ${mgl_src_lst}) add_library(${mgllib}-static STATIC ${mgl_src_lst}) set_target_properties(${mgllib} PROPERTIES SOVERSION ${MathGL_SOVERSION}) set_target_properties(${mgllib} PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS") set_target_properties(${mgllib} PROPERTIES C_VISIBILITY_PRESET hidden) set_target_properties(${mgllib} PROPERTIES CXX_VISIBILITY_PRESET hidden) set_target_properties(${mgllib} PROPERTIES VISIBILITY_INLINES_HIDDEN 1) target_compile_definitions(${mgllib}-static PUBLIC MGL_STATIC_DEFINE) if(MSVC) set(mgl_lib_static "-static") if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(mgl_lib_end "d") else(CMAKE_BUILD_TYPE STREQUAL "Debug") set(mgl_lib_end) endif(CMAKE_BUILD_TYPE STREQUAL "Debug") elseif(MSVC) set(mgl_lib_static) set_target_properties(${mgllib} PROPERTIES CLEAN_DIRECT_OUTPUT 1) set_target_properties(${mgllib}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) endif(MSVC) if(enable-mgl2) set_target_properties(${mgllib} PROPERTIES OUTPUT_NAME "${mgllib2}${mgl_lib_end}") set_target_properties(${mgllib}-static PROPERTIES OUTPUT_NAME "${mgllib2}${mgl_lib_static}${mgl_lib_end}") else(enable-mgl2) set_target_properties(${mgllib} PROPERTIES OUTPUT_NAME "${mgllib}${mgl_lib_end}") set_target_properties(${mgllib}-static PROPERTIES OUTPUT_NAME "${mgllib}${mgl_lib_static}${mgl_lib_end}") endif(enable-mgl2) install( TARGETS ${mgllib} ${mgllib}-static EXPORT MathGLTargets RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR} ARCHIVE DESTINATION ${MathGL_INSTALL_LIB_DIR} LIBRARY DESTINATION ${MathGL_INSTALL_LIB_DIR} ) endfunction(mgl_add_lib mgl_tmp_lib) MACRO(MGL_DEPENDENT_OPTION option doc default depends1 force1 depends2 force2) IF(${option}_ISSET MATCHES "^${option}_ISSET$") SET(${option}_AVAILABLE 1) IF(${force1}) FOREACH(d ${depends1}) STRING(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}") IF(${CMAKE_DEPENDENT_OPTION_DEP}) ELSE(${CMAKE_DEPENDENT_OPTION_DEP}) SET(${option}_AVAILABLE 0) SET(depends1_AVAILABLE 1) ENDIF(${CMAKE_DEPENDENT_OPTION_DEP}) ENDFOREACH(d) ENDIF(${force1}) IF(${force2}) FOREACH(d ${depends2}) STRING(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}") IF(${CMAKE_DEPENDENT_OPTION_DEP}) ELSE(${CMAKE_DEPENDENT_OPTION_DEP}) SET(${option}_AVAILABLE 0) SET(depends2_AVAILABLE 1) ENDIF(${CMAKE_DEPENDENT_OPTION_DEP}) ENDFOREACH(d) ENDIF(${force2}) IF(${option}_AVAILABLE) OPTION(${option} "${doc}" "${default}") SET(${option} "${${option}}" CACHE BOOL "${doc}" FORCE) ELSE(${option}_AVAILABLE) IF(${option} MATCHES "^${option}$") ELSE(${option} MATCHES "^${option}$") SET(${option} "${${option}}" CACHE INTERNAL "${doc}") ENDIF(${option} MATCHES "^${option}$") IF(depends1_AVAILABLE) SET(${option} OFF) ELSEIF(depends2_AVAILABLE) SET(${option} ON) ENDIF(depends1_AVAILABLE) ENDIF(${option}_AVAILABLE) ELSE(${option}_ISSET MATCHES "^${option}_ISSET$") SET(${option} "${${option}_ISSET}") ENDIF(${option}_ISSET MATCHES "^${option}_ISSET$") ENDMACRO(MGL_DEPENDENT_OPTION) include(CMakeDependentOption) string(TIMESTAMP MGL_NIGHT "%d.%m.%y") if(WIN32) option(enable-dep-dll "Enable copying off all dependent dll libraries to the install directory" OFF) endif(WIN32) option(enable-double "Enable double precision in MathGL library" ON) option(enable-mpi "Enable mpi") option(enable-opengl "Enable OpenGL support" ON) option(enable-all-docs "Enable all documentation building") #option(enable-doc "Enable documentation building") option(enable-all "Enable all core features") option(enable-all-widgets "Enable all Widgets") option(enable-all-swig "Enable all SWIG based interfaces") option(enable-rvalue "Enable move constructor support (need C++11)" OFF) option(enable-pthread "Enable POSIX threads support" OFF) if(MSVC) option(enable-pthr-widget "Enable POSIX threads for widgets" OFF) else(MSVC) option(enable-pthr-widget "Enable POSIX threads for widgets" ON) endif(MSVC) option(enable-openmp "Enable OpenMP support" ON) option(disable-C99complex "Enable C99 complex number support" OFF) if(enable-pthread AND enable-openmp) message(SEND_ERROR "You can't enable POSIX threads and OpenMP at the same time!") endif(enable-pthread AND enable-openmp) option(enable-lgpl "Enable only LGPL part of MathGL") option(enable-mgl2 "Use names 'libmgl2-*' instead of 'libmgl-*'") option(enable-ltdl "Enable loading modules support") option(enable-doc-site "Enable HTML documentation for website") #CMAKE_DEPENDENT_OPTION(enable-doc-site "Enable HTML documentation for website" OFF "NOT enable-all-docs" ON) CMAKE_DEPENDENT_OPTION(enable-doc-html "Enable HTML documentation" OFF "NOT enable-all-docs" ON) CMAKE_DEPENDENT_OPTION(enable-doc-info "Enable INFO documentation" OFF "NOT enable-all-docs" ON) CMAKE_DEPENDENT_OPTION(enable-doc-pdf-ru "Enable Russian PDF documentation" OFF "NOT enable-all-docs" ON) CMAKE_DEPENDENT_OPTION(enable-doc-pdf-en "Enable English PDF documentation" OFF "NOT enable-all-docs" ON) #CMAKE_DEPENDENT_OPTION(enable-doc-prc "Enable PDF samples for HTML docs" OFF "NOT enable-all-docs" ON) #CMAKE_DEPENDENT_OPTION(enable-doc-json "Enable JSON samples for HTML docs" OFF "NOT enable-all-docs" ON) option(enable-texi2html "Use texi2html (obsolete package) instead of texi2any" OFF) CMAKE_DEPENDENT_OPTION(enable-mgltex "Enable installation of mgltex package (MGL scripts in LATEX document)" OFF "NOT enable-lgpl" OFF) CMAKE_DEPENDENT_OPTION(enable-zlib "Enable zlib support" ON "NOT enable-all" ON) CMAKE_DEPENDENT_OPTION(enable-png "Enable png support" ON "NOT enable-all" ON) CMAKE_DEPENDENT_OPTION(enable-jpeg "Enable jpeg support" OFF "NOT enable-all" ON) MGL_DEPENDENT_OPTION(enable-gsl "Enable gsl support" OFF "NOT enable-lgpl" ON "NOT enable-all" ON) MGL_DEPENDENT_OPTION(enable-hdf4 "Enable hdf4 support" OFF "NOT enable-lgpl" ON "NOT enable-all" ON) MGL_DEPENDENT_OPTION(enable-hdf5 "Enable hdf5 support" OFF "NOT enable-lgpl" ON "NOT enable-all" ON) CMAKE_DEPENDENT_OPTION(enable-pdf "Enable pdf support" OFF "NOT enable-all" ON) CMAKE_DEPENDENT_OPTION(enable-gif "Enable gif support" OFF "NOT enable-all" ON) CMAKE_DEPENDENT_OPTION(enable-glut "Enable glut support" OFF "NOT enable-all-widgets" ON) CMAKE_DEPENDENT_OPTION(enable-fltk "Enable fltk widget" OFF "NOT enable-all-widgets" ON) CMAKE_DEPENDENT_OPTION(enable-wx "Enable wxWidget widget" OFF "NOT enable-all-widgets" ON) CMAKE_DEPENDENT_OPTION(enable-qt4 "Enable Qt4 widget" OFF "NOT enable-all-widgets" ON) CMAKE_DEPENDENT_OPTION(enable-qt4asqt "Set Qt4 as default libmgl-qt" OFF "enable-qt4" OFF) CMAKE_DEPENDENT_OPTION(enable-qt5 "Enable Qt5 widget" OFF "NOT enable-all-widgets" ON) CMAKE_DEPENDENT_OPTION(enable-qt5asqt "Set Qt5 as default libmgl-qt" OFF "enable-qt5" OFF) # msvc fwprintf print char* for the specifier of "%s" format if(MSVC AND MSVC_VERSION GREATER 1899) SET(CMAKE_CXX_FLAGS "/EHsc -D_CRT_STDIO_ISO_WIDE_SPECIFIERS ${CMAKE_CXX_FLAGS}") SET(CMAKE_C_FLAGS "-D_CRT_STDIO_ISO_WIDE_SPECIFIERS ${CMAKE_C_FLAGS}") endif(MSVC AND MSVC_VERSION GREATER 1899) include(CheckCXXSourceCompiles) if(${CMAKE_SIZEOF_VOID_P} EQUAL 4) set(CMAKE_REQUIRED_FLAGS -msse2 -mfpmath=sse) CHECK_CXX_SOURCE_COMPILES(" int main(void){}" mgl_sse) if(mgl_sse) SET(CMAKE_CXX_FLAGS "-msse2 -mfpmath=sse ${CMAKE_CXX_FLAGS}") SET(CMAKE_C_FLAGS "-msse2 -mfpmath=sse ${CMAKE_C_FLAGS}") endif(mgl_sse) unset(CMAKE_REQUIRED_FLAGS) endif(${CMAKE_SIZEOF_VOID_P} EQUAL 4) if(enable-qt4 OR enable-qt5) set(QT_ENABLED ON) if(enable-qt4asqt AND enable-qt5asqt) message(SEND_ERROR "You cannot make Qt4 and Qt5 as qt at the same time.") endif(enable-qt4asqt AND enable-qt5asqt) if(enable-qt4 AND NOT enable-qt5) set(enable-qt4asqt TRUE) endif(enable-qt4 AND NOT enable-qt5) if(enable-qt5 AND NOT enable-qt4) set(enable-qt5asqt TRUE) endif(enable-qt5 AND NOT enable-qt4) # if(NOT enable-opengl) # message(SEND_ERROR "You cannot build MathGL with Qt4 or Qt5 without OpenGL enabled.") # endif(NOT enable-opengl) endif(enable-qt4 OR enable-qt5) CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample (WebKit variant is the default)." ON "QT_ENABLED" OFF) CMAKE_DEPENDENT_OPTION(enable-json-sample-we "Enable JSON sample (WebEngine variant)." OFF "enable-json-sample" OFF) MGL_DEPENDENT_OPTION(enable-python "Enable python interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON) MGL_DEPENDENT_OPTION(enable-lua "Enable Lua (v.5.1) interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON) MGL_DEPENDENT_OPTION(enable-octave "Enable octave interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON) MGL_DEPENDENT_OPTION(enable-octave-install "Octave interface will install for all users" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON) include_directories( ${MathGL2_SOURCE_DIR}/include ${MathGL2_BINARY_DIR}/include) set(MGL_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/include/mgl2") set(MGL_CGI_PATH_INSTALL "lib/cgi-bin" CACHE STRING "Set CGI install directory") #set(MGL_CGI_PATH_INSTALL "share/mathgl" CACHE STRING "Set CGI install directory") set(MGL_CGI_PATH "${CMAKE_INSTALL_PREFIX}/${MGL_CGI_PATH_INSTALL}") set(MGL_DEF_FONT "STIX" CACHE STRING "Set default font name") if(NOT WIN32) # set(MGL_CGI_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl") set(MGL_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl") set(MGL_DOC_PATH "${CMAKE_INSTALL_PREFIX}/share/doc/mathgl") set(MGL_MAN_PATH "${CMAKE_INSTALL_PREFIX}/share/man") set(MGL_INFO_PATH "${CMAKE_INSTALL_PREFIX}/share/info") set(MGL_FONT_PATH "${MGL_DATA_PATH}/fonts") else(NOT WIN32) set(MGL_FONT_PATH "${CMAKE_INSTALL_PREFIX}/fonts") endif(NOT WIN32) include(CheckFunctionExists) include(CMakePushCheckState) include(TestBigEndian) TEST_BIG_ENDIAN(WORDS_BIGENDIAN) if(WORDS_BIGENDIAN) ADD_DEFINITIONS(-DWORDS_BIGENDIAN) endif(WORDS_BIGENDIAN) CHECK_FUNCTION_EXISTS(sin MGL_SIN) CHECK_FUNCTION_EXISTS(memrchr HAVE_MEMRCHR) if(NOT MGL_SIN) cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} m) CHECK_FUNCTION_EXISTS(sin MGL_SIN_M) cmake_pop_check_state() if(MGL_SIN_M) set(M_LIB m) elseif(MGL_SIN_M) message(SEND_ERROR "Math library not found") endif(MGL_SIN_M) endif(NOT MGL_SIN) set(MGL_DEP_LIBS ${M_LIB} ${MGL_DEP_LIBS}) if(HAVE_MEMRCHR) ADD_DEFINITIONS(-DHAVE_MEMRCHR) endif(HAVE_MEMRCHR) include(CheckTypeSize) check_type_size("long" SIZEOF_LONG) if(NOT disable-C99complex) # unset(MGL_HAVE_C99_COMPLEX) CHECK_CXX_SOURCE_COMPILES( "#include #include int main(int argc, char *args[]) {std::complex c(2.0, 1.0); double _Complex i=1.0i; double _Complex *a = reinterpret_cast(&c); std::complex b(*a);return 0;}" MGL_HAVE_C99_COMPLEX) if(NOT MGL_HAVE_C99_COMPLEX) set(MGL_HAVE_C99_COMPLEX 0) endif(NOT MGL_HAVE_C99_COMPLEX) else(NOT disable-C99complex) set(MGL_HAVE_C99_COMPLEX 0) endif(NOT disable-C99complex) #unset(MGL_HAVE_NAN_INF) CHECK_CXX_SOURCE_COMPILES( "#include int main(){double a=NAN, b=INFINITY;return 0;}" MGL_HAVE_NAN_INF) if(NOT MGL_HAVE_NAN_INF) set(MGL_HAVE_NAN_INF 0) endif(NOT MGL_HAVE_NAN_INF) #unset(MGL_HAVE_ATTRIBUTE) CHECK_CXX_SOURCE_COMPILES( "int __attribute__((pure)) test1() {return 0;} int __attribute__((const)) test2(int x) {return x*x;} int main(int argc, char* argv[]) {return 0;}" MGL_HAVE_ATTRIBUTE) if(NOT MGL_HAVE_ATTRIBUTE) set(MGL_HAVE_ATTRIBUTE 0) endif(NOT MGL_HAVE_ATTRIBUTE) if(NOT MSVC AND enable-rvalue) SET(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}") unset(MGL_HAVE_RVAL CACHE) CHECK_CXX_SOURCE_COMPILES( "struct test { test() {} test(test&& a){} }; int main() { test t; return 0; }" MGL_HAVE_RVAL) if(NOT MGL_HAVE_RVAL) message(SEND_ERROR "Couldn't enable rvalue.") # set(MGL_HAVE_RVAL 0) endif(NOT MGL_HAVE_RVAL) else(NOT MSVC AND enable-rvalue) set(MGL_HAVE_RVAL 0) endif(NOT MSVC AND enable-rvalue) CHECK_CXX_SOURCE_COMPILES( "#include int main(int argc, char *args[]) { int ch = getopt(argc, args, \"1:2:3:4:5:6:7:8:9:hno:L:C:A:s:S:q:\"); return 0; }" MGL_HAVE_GETOPT) if(NOT MGL_HAVE_GETOPT) include_directories(${MathGL2_SOURCE_DIR}/addons/getopt) set(getopt_lib-static getopt-static) endif(NOT MGL_HAVE_GETOPT) if(enable-double) set(MGL_USE_DOUBLE 1) else(enable-double) set(MGL_USE_DOUBLE 0) endif(enable-double) if(enable-qt4 OR enable-qt5) set(MGL_HAVE_QT 1) endif(enable-qt4 OR enable-qt5) if(enable-mpi) set(MGL_HAVE_MPI 1) find_package(MPI REQUIRED) set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS}) set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS}) include_directories(${MPI_INCLUDE_PATH}) else(enable-mpi) set(MGL_HAVE_MPI 0) endif(enable-mpi) if(enable-pthr-widget OR enable-pthread) if(enable-pthread) set(MGL_HAVE_PTHREAD 1) else(enable-pthread) set(MGL_HAVE_PTHREAD 0) endif(enable-pthread) # cmake v.3.1 set(MGL_HAVE_PTHR_WIDGET 1) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) # was for v.2.8.12 # include(FindThreads) if(NOT CMAKE_USE_PTHREADS_INIT) message(SEND_ERROR "Couldn't find POSIX threads library.") endif(NOT CMAKE_USE_PTHREADS_INIT) # cmake v.3.1 set(MGL_DEP_LIBS Threads::Threads ${MGL_DEP_LIBS}) # was for v.2.8.12 # set(MGL_DEP_LIBS ${CMAKE_THREAD_LIBS_INIT} ${MGL_DEP_LIBS}) else(enable-pthr-widget OR enable-pthread) set(MGL_HAVE_PTHR_WIDGET 0) set(MGL_HAVE_PTHREAD 0) endif(enable-pthr-widget OR enable-pthread) if(enable-openmp) find_package(OpenMP) if(OPENMP_FOUND) set(MGL_HAVE_OMP 1) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") else(OPENMP_FOUND) message(SEND_ERROR "Couldn't find OpenMP. You can enable POSIX threads instead.") set(MGL_HAVE_OMP 0) endif(OPENMP_FOUND) else(enable-openmp) set(MGL_HAVE_OMP 0) endif(enable-openmp) if(enable-gsl) set(MGL_HAVE_GSL 1) find_library(GSL_LIB gsl) find_library(GSL_CBLAS_LIB gslcblas) find_path(GSL_INCLUDE_DIR gsl/gsl_fft_complex.h) if(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR) message(SEND_ERROR "${GSL_LIB}") message(SEND_ERROR "${GSL_CBLAS_LIB}") message(SEND_ERROR "${GSL_INCLUDE_DIR}") message(SEND_ERROR "Couldn't find GSL libraries.") else(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR) set(CMAKE_REQUIRED_INCLUDES ${GSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${GSL_LIB} ${GSL_CBLAS_LIB}) CHECK_CXX_SOURCE_COMPILES("#include int main(){gsl_multifit_fdfsolver *s=0;gsl_matrix *J = 0; gsl_multifit_fdfsolver_jac(s, J);}" MGL_HAVE_GSL2) unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_LIBRARIES) endif(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR) set(MGL_DEP_LIBS ${GSL_LIB} ${GSL_CBLAS_LIB} ${MGL_DEP_LIBS}) include_directories(${GSL_INCLUDE_DIR}) else(enable-gsl) set(MGL_HAVE_GSL 0) endif(enable-gsl) if(enable-all OR enable-ltdl) set(MGL_HAVE_LTDL 1) find_library(LTDL_LIB ltdl) find_path(LTDL_INCLUDE_DIR ltdl.h) if(NOT LTDL_LIB OR NOT LTDL_INCLUDE_DIR) message(SEND_ERROR "${LTDL_LIB}") message(SEND_ERROR "${LTDL_INCLUDE_DIR}") message(SEND_ERROR "Couldn't find LTDL library.") endif(NOT LTDL_LIB OR NOT LTDL_INCLUDE_DIR) set(MGL_DEP_LIBS ${LTDL_LIB} ${MGL_DEP_LIBS}) include_directories(${LTDL_INCLUDE_DIR}) else(enable-all OR enable-ltdl) set(MGL_HAVE_LTDL 0) endif(enable-all OR enable-ltdl) if(enable-hdf4) set(MGL_HAVE_HDF4 1) find_library(HDF4_LIB NAMES df hdf) find_library(HDF4MF_LIB mfhdf) find_path(HDF4_INCLUDE_DIR mfhdf.h PATH_SUFFIXES hdf) if(NOT HDF4_LIB OR NOT HDF4MF_LIB OR NOT HDF4_INCLUDE_DIR) message(SEND_ERROR "${HDF4_LIB}") message(SEND_ERROR "${HDF4MF_LIB}") message(SEND_ERROR "${HDF4_INCLUDE_DIR}") message(SEND_ERROR "Couldn't find HDF4 libraries.") endif(NOT HDF4_LIB OR NOT HDF4MF_LIB OR NOT HDF4_INCLUDE_DIR) set(MGL_DEP_LIBS ${HDF4MF_LIB} ${HDF4_LIB} ${MGL_DEP_LIBS}) include_directories(${HDF4_INCLUDE_DIR}) else(enable-hdf4) set(MGL_HAVE_HDF4 0) endif(enable-hdf4) if(enable-hdf5) set(MGL_HAVE_HDF5 1) find_package(HDF5) if(NOT HDF5_FOUND) find_package(HDF5 NAMES hdf5 COMPONENTS C shared static) if(NOT HDF5_FOUND) message(SEND_ERROR "Couldn't find HDF5 library.") endif(NOT HDF5_FOUND) endif(NOT HDF5_FOUND) set(MGL_DEP_LIBS ${HDF5_LIBRARIES} ${HDF5_C_SHARED_LIBRARY} ${MGL_DEP_LIBS}) include_directories(${HDF5_INCLUDE_DIRS}) else(enable-hdf5) set(MGL_HAVE_HDF5 0) endif(enable-hdf5) if(enable-jpeg) set(MGL_HAVE_JPEG 1) include(FindJPEG) if(NOT JPEG_FOUND) message(SEND_ERROR "Couldn't find JPEG library.") endif(NOT JPEG_FOUND) set(MGL_DEP_LIBS ${JPEG_LIBRARIES} ${MGL_DEP_LIBS}) include_directories(${JPEG_INCLUDE_DIR}) else(enable-jpeg) set(MGL_HAVE_JPEG 0) endif(enable-jpeg) if(enable-zlib) set(MGL_HAVE_ZLIB 1) include(FindZLIB) if(NOT ZLIB_FOUND) message(SEND_ERROR "Couldn't find ZLib library.") endif(NOT ZLIB_FOUND) set(MGL_DEP_LIBS ${ZLIB_LIBRARIES} ${MGL_DEP_LIBS}) include_directories(${ZLIB_INCLUDE_DIR}) else(enable-zlib) set(MGL_HAVE_ZLIB 0) endif(enable-zlib) if(enable-png) set(MGL_HAVE_PNG 1) if(NOT MGL_HAVE_ZLIB) message(SEND_ERROR "You have to enable ZLib if you plan to use PNG export.") endif(NOT MGL_HAVE_ZLIB) include(FindPNG) if(NOT PNG_FOUND) message(SEND_ERROR "Couldn't find PNG library.") endif(NOT PNG_FOUND) set(MGL_DEP_LIBS ${PNG_LIBRARIES} ${MGL_DEP_LIBS}) include_directories(${PNG_INCLUDE_DIR}) else(enable-png) set(MGL_HAVE_PNG 0) endif(enable-png) if(enable-pdf) set(MGL_HAVE_PDF 1) if(NOT MGL_HAVE_PNG) message(SEND_ERROR "You have to enable PNG if you plan to use PDF export.") endif(NOT MGL_HAVE_PNG) find_library(HPDF_LIB hpdf) if(NOT HPDF_LIB) message(SEND_ERROR "Couldn't find libHaru or libhpdf.") endif(NOT HPDF_LIB) find_path(HPDF_INCLUDE_DIR hpdf_u3d.h) if(NOT HPDF_INCLUDE_DIR) message(SEND_ERROR "Couldn't find headers of 3d-enabled version of libhpdf.") endif(NOT HPDF_INCLUDE_DIR) include_directories(${HPDF_INCLUDE_DIR}) set(MGL_DEP_LIBS ${HPDF_LIB} ${MGL_DEP_LIBS}) else(enable-pdf) set(MGL_HAVE_PDF 0) endif(enable-pdf) if(enable-gif) set(MGL_HAVE_GIF 1) include(FindGIF) if(NOT GIF_FOUND) message(SEND_ERROR "Couldn't find GIF library.") endif(NOT GIF_FOUND) set(MGL_DEP_LIBS ${GIF_LIBRARIES} ${MGL_DEP_LIBS}) include_directories(${GIF_INCLUDE_DIR}) else(enable-gif) set(MGL_HAVE_GIF 0) endif(enable-gif) if(enable-opengl) set(MGL_HAVE_OPENGL 1) set(OpenGL_GL_PREFERENCE LEGACY) include(FindOpenGL) if(NOT OPENGL_FOUND) message(SEND_ERROR "Couldn't find OpenGL libraries.") endif(NOT OPENGL_FOUND) set(MGL_DEP_LIBS ${OPENGL_LIBRARIES} ${MGL_DEP_LIBS}) include_directories(${OPENGL_INCLUDE_DIR} ) else(enable-opengl) set(MGL_HAVE_OPENGL 0) endif(enable-opengl) if(enable-glut) set(MGL_HAVE_GLUT 1) if(NOT MGL_HAVE_OPENGL) message(SEND_ERROR "You have to enable OpenGL if you plan to use GLUT.") endif(NOT MGL_HAVE_OPENGL) include(FindGLUT) if(NOT GLUT_FOUND) message(SEND_ERROR "Couldn't find GLUT library.") endif(NOT GLUT_FOUND) else(enable-glut) set(MGL_HAVE_GLUT 0) endif(enable-glut) if(enable-fltk) set(MGL_HAVE_FLTK 1) FIND_PACKAGE(FLTK) if(NOT FLTK_FOUND) message(SEND_ERROR "Couldn't find FLTK library.") else(NOT FLTK_FOUND) include_directories(${FLTK_INCLUDE_DIR}) CHECK_CXX_SOURCE_COMPILES( "#include int main(){return 0;}" MGL_HAVE_FL_COPY) endif(NOT FLTK_FOUND) if(NOT MGL_HAVE_FL_COPY) set(MGL_HAVE_FL_COPY 0) endif(NOT MGL_HAVE_FL_COPY) else(enable-fltk) set(MGL_HAVE_FLTK 0) endif(enable-fltk) if(enable-wx) set(MGL_HAVE_WX 1) FIND_PACKAGE(wxWidgets COMPONENTS base core gl) if(NOT wxWidgets_FOUND) message(SEND_ERROR "Couldn't find wxWidgets library.") endif(NOT wxWidgets_FOUND) else(enable-wx) set(MGL_HAVE_WX 0) endif(enable-wx) find_program(findxgettext xgettext) find_program(findmsgmerge msgmerge) find_program(findmsgfmt msgfmt) find_program(findmsgcat msgcat) if(NOT findmsgfmt OR NOT findxgettext OR NOT findmsgmerge OR NOT findmsgcat ) message("Building of translation files was disabled, because xgettext, msgmerge, msgcat or msgfmt was not found. Current translations will be just coped.") set(USE_GETTEXT 0) else(NOT findmsgfmt OR NOT findxgettext OR NOT findmsgmerge OR NOT findmsgcat ) set(USE_GETTEXT 1) endif(NOT findmsgfmt OR NOT findxgettext OR NOT findmsgmerge OR NOT findmsgcat ) find_package(Intl) if(NOT Intl_FOUND) set(MGL_USE_LIBINTL 0) message("Gettext and translations was fully disabled, because libintl was not found.") else(NOT Intl_FOUND) set(MGL_USE_LIBINTL 1) set(MGL_DEP_LIBS ${Intl_LIBRARIES} ${MGL_DEP_LIBS}) include_directories(${Intl_INCLUDE_DIRS}) endif(NOT Intl_FOUND) set(po_files ) if(WIN32) set(USE_GETTEXT 0) set(MGL_USE_LIBINTL 0) endif(WIN32) if(enable-doc-info) set(MGL_HAVE_DOC_INFO 1) find_program(findmi makeinfo) if(NOT findmi) message(SEND_ERROR "Couldn't find makeinfo needed for documentation building.") endif(NOT findmi) else(enable-doc-info) set(MGL_HAVE_DOC_INFO 0) endif(enable-doc-info) if(enable-doc-html OR enable-doc-site) if(enable-texi2html) find_program(findth texi2html) if(NOT findth) message(SEND_ERROR "Couldn't find texi2html needed for documentation building.") endif(NOT findth) else(enable-texi2html) find_program(findth texi2any) if(NOT findth) message(SEND_ERROR "Couldn't find texi2any needed for documentation building.") endif(NOT findth) endif(enable-texi2html) endif(enable-doc-html OR enable-doc-site) if(enable-texi2html) set(site_en ${CMAKE_BINARY_DIR}/texinfo/doc_en/doc_en.html) set(site_ru ${CMAKE_BINARY_DIR}/texinfo/doc_ru/doc_ru.html) set(th_opt ) else(enable-texi2html) set(th_opt --html) set(site_en ${CMAKE_BINARY_DIR}/texinfo/doc_en/index.html) set(site_ru ${CMAKE_BINARY_DIR}/texinfo/doc_ru/index.html) endif(enable-texi2html) if(enable-doc-html) set(MGL_HAVE_DOC_HTML 1) else(enable-doc-html) set(MGL_HAVE_DOC_HTML 0) endif(enable-doc-html) if(enable-doc-site) set(MGL_HAVE_DOC_SITE 1) else(enable-doc-site) set(MGL_HAVE_DOC_SITE 0) endif(enable-doc-site) if(enable-doc-pdf-ru) set(MGL_HAVE_DOC_PDF_RU 1) find_program(findtp texi2pdf) if(NOT findtp) message(SEND_ERROR "Couldn't find texi2pdf needed for documentation building.") endif(NOT findtp) else(enable-doc-pdf-ru) set(MGL_HAVE_DOC_PDF_RU 0) endif(enable-doc-pdf-ru) if(enable-doc-pdf-en) set(MGL_HAVE_DOC_PDF_EN 1) find_program(findtp texi2pdf) if(NOT findtp) message(SEND_ERROR "Couldn't find texi2pdf needed for documentation building.") endif(NOT findtp) else(enable-doc-pdf-en) set(MGL_HAVE_DOC_PDF_EN 0) endif(enable-doc-pdf-en) if(enable-doc-site) set(MGL_HAVE_DOC_JSON 1) else(enable-doc-site) set(MGL_HAVE_DOC_JSON 0) endif(enable-doc-site) if(enable-doc-site) set(MGL_HAVE_DOC_PRC 1) if(NOT enable-pdf) message(SEND_ERROR "You need to enable pdf support for MathGL.") endif(NOT enable-pdf) else(enable-doc-site) set(MGL_HAVE_DOC_PRC 0) endif(enable-doc-site) if(UNIX) add_definitions(-DNO_COLOR_ARRAY) endif(UNIX) if(WIN32) add_definitions(-DWIN32) endif(WIN32) if(NOT MGL_HAVE_GETOPT) add_subdirectory( addons/getopt ) endif(NOT MGL_HAVE_GETOPT) add_subdirectory( src ) add_subdirectory( widgets ) add_subdirectory( include ) if(NOT enable-lgpl) if(MGL_HAVE_QT) add_subdirectory( udav ) if(enable-json-sample) add_subdirectory( json ) endif(enable-json-sample) endif(MGL_HAVE_QT) if(enable-python OR enable-lua OR enable-octave) add_subdirectory( lang ) endif(enable-python OR enable-lua OR enable-octave) add_subdirectory( utils ) add_subdirectory( examples ) if(NOT WIN32) add_subdirectory( fonts ) endif(NOT WIN32) add_subdirectory( mgllab ) endif(NOT enable-lgpl) if(NOT MSVC AND NOT BORLAND) if(MGL_HAVE_DOC_HTML OR MGL_HAVE_DOC_SITE OR MGL_HAVE_DOC_INFO OR MGL_HAVE_DOC_PDF_RU OR MGL_HAVE_DOC_PDF_EN ) add_subdirectory( texinfo ) endif(MGL_HAVE_DOC_HTML OR MGL_HAVE_DOC_SITE OR MGL_HAVE_DOC_INFO OR MGL_HAVE_DOC_PDF_RU OR MGL_HAVE_DOC_PDF_EN ) endif(NOT MSVC AND NOT BORLAND) if(enable-mgltex) add_subdirectory( mgltex ) endif(enable-mgltex) if(MGL_USE_LIBINTL) if(USE_GETTEXT) set(mgl_tl_list ) add_custom_command(OUTPUT mathgl.pot COMMAND ${findxgettext} -s --keyword=_ -C -c --package-name=MathGL2 --package-version=${MathGL_VERSION} -o ${MathGL2_BINARY_DIR}/mathgl.pot ${po_files} WORKING_DIRECTORY ${MathGL2_SOURCE_DIR}/ DEPENDS ${po_files} ) set(mgl_clean_files mathgl.pot ${mgl_clean_files}) foreach(tl ru es) # en) add_custom_command(OUTPUT mathgl_${tl}.po.done COMMAND ${findmsgmerge} -U mathgl_${tl}.po ${MathGL2_BINARY_DIR}/mathgl.pot COMMAND ${CMAKE_COMMAND} -E touch ${MathGL2_BINARY_DIR}/mathgl_${tl}.po.done WORKING_DIRECTORY ${MathGL2_SOURCE_DIR}/ DEPENDS mathgl.pot mathgl_${tl}.po) add_custom_command(OUTPUT mathgl_${tl}.mo COMMAND ${findmsgfmt} -o mathgl_${tl}.mo ${MathGL2_SOURCE_DIR}/mathgl_${tl}.po DEPENDS mathgl_${tl}.po.done) install( FILES ${MathGL2_BINARY_DIR}/mathgl_${tl}.mo DESTINATION "${CMAKE_INSTALL_PREFIX}/share/locale/${tl}/LC_MESSAGES/" RENAME mathgl.mo ) set(mgl_tl_list mathgl_${tl}.mo ${mgl_tl_list}) set(mgl_clean_files mathgl_${tl}.mo mathgl_${tl}.po.done ${mgl_clean_files}) endforeach(tl) add_custom_target(mgl_translations ALL DEPENDS ${mgl_tl_list}) else(USE_GETTEXT) foreach(tl ru es) # en) install( FILES ${MathGL2_SOURCE_DIR}/translations/mathgl_${tl}.mo DESTINATION "${CMAKE_INSTALL_PREFIX}/share/locale/${tl}/LC_MESSAGES/" RENAME mathgl.mo ) endforeach(tl) endif(USE_GETTEXT) endif(MGL_USE_LIBINTL) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${mgl_clean_files}") # WARNING!!! DO NOT ADD ANYTHING AFTER THIS LINE! add_subdirectory ( scripts ) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/todo.txt�������������������������������������������������������������������������������0000644�0001750�0001750�00000017227�13513030041�014664� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const ============= FAR FUTURE ================ 1. Export to COLLADA or X3D !!! 2. Read DICOM, MAT, WFM files 3. Contour lines for bilinear interpolation (strong saddle-like faces) -- best way by adding curve primitive (type=5)?!? 4. 3D text (with depth), and text along 3D curve (for Quality=3) ??? 5. Get true coordinates in CalcXYZ for curved equations too. 6. Extra markers for '&' and '&#' signs ?!? or user-defined signs 7. Improve z-order for rapidly oscillating surfaces (сравнение проекций центров на грань -- too slow) 8. Enable consecutive (as multiplication of matrices instead of single summary one) rotation of axis + the same in JS. Problem with widgets?!? 9. Export background image to svg ??? 10. Frames by mouse in UDAV ??? A. мысли о frame??? для группы графиков -- не "удалять" их, а запихивать в отдельный кадр -- вопрос что с анимацией??? B. как делать анимацию (кадры) для мышиной версии ... список кадров, кнопки добавить в кадры + вставить из кадра 11. Parallel drawing in QMathGL (looks to complicated -- FLTK is better!) 12. \overline{\overline{a}} ??? 13. Use arrow_plot_3d ??? 14. Mask in SVG ??? ============= NEW FEATURES ============= 1. Centered curved text (see text2) 2. Quality=3 for mirror+shadows? Couldn't be in bitmap only mode 4. "latex on" option ?!? 5. Add "text3d x y z lx ly lz nx ny nz 'txt' ['stl'='' depth=0.1 depth2=nan]" 6. Flag to determine discontinuous surfaces in 'fsurf' 7. Add PGM|PPM export (see https://en.wikipedia.org/wiki/Netpbm_format) 8. Check title & rasterize 10. mgltask -- add $3-loop, $R=formula for R=4,...,9,0,A,...,Z 11. mgl.cgi -- add log-file{IP,time,script}, add file-password (enable I/O if pass is the same as in a file) 12. Chord diagram 13. Calendar diagram -- 1D data as dens for 7-row (day) or 12-row (months) + divisions at month or year 14. Dendrogram ??? 15. Voronoi diagram ??? -- triangulation + coloring by point 16. Sankey diagram ??? * Add 'connect' for connecting points to set of surfaces ZZ. Update *.i for new functions {before release!!!} curve_draw: step?, bifurcation?, flow3d ============= DOCUMENTATION ============= A. Paper about MathGL!!! B. Add chapter with real samples C. Translate to Russian everything D. Docs about JS interface 0. Update Qt and UDAV figures 1. Update installation (dll from mgl_script + Qt plugins/ + Win10) 2. Add more samples: * Example of 'contp', 'flowp' * Example of frame manipulation * Example of 'title' style '#' * Example of 'triplot'+'quadplot' with colors per-face * Example of 'tricontv' * Example of 'grad_xyz' * Example of 'flow', 'pipe' style '*'. * Example of 'fsurf' * Example of 'tile','tiles' styles 'x', 'z' * Example of 'lamerey' style '~' * Example of 'iris', extended * Example of wired 'area' and 'region' (2d case), 'region' with !z1||!z2 (?!?) * Example of 'step' with markers; 'barh', 'bars' (3d) style 'F' * Example of CalcXYZ() * Example of 'clf' with color, 'rasterize', 'loadbackground', 'logo' * Example of 'pde' in 3d, and 'qo3d' * Example of 'tridmat' in all 5 modes, and for real numbers too. * Example of "data" creation {'list', 'def*','ask','{OP DAT}'} * Example of 'rk_step' * Example of 'openhdf' * Extend examples of 'fit' and 'hist' in multi-dimension case. * Example of complex 'hankel' for PDE solving * Example of 'wavelet' * Example of time-values in formulas (like hh-mm-ss_DD.MM.YYYY or hh-mm-ss or DD.MM.YYYY) * Example of Step, Bars for x.nx = y.nx+1 * Example of `dat <==> Transpose(dat). * Example of 'coil' * Example of 'roots' * Example of custom dialog * Example of 'progress' 3. Docs about mgllab (overview, dialogs, ...) 4. Example of Evaluate + ".mx" ??? 8. 'connect' ZZ. Update time.texi {before release!!!} как начать пользоваться (quickstart) как скомпилировать и установить (building & installing) как запустить (running) как протестировать свои правки (testing) как настроить (configuration) какие есть примеры использования (examples) Shortly, there are 3 steps: 1. Download binary for the platform you want to use (32bit or 64bit) and unpack it somewhere. Note, if mix 32bit and 64bit binaries in the same executable, when a compiler under Windows will not give warning about it, but yours program will be crushed! 2. Get all requires libraries (probably some of them is installed on your PC). Also you can just use MathgL utilities (like, http://downloads.sourceforge.net/mathgl/mgl_scripts-2.4.2.win64.7z) which contain all required DLLs. 3. Use MathGL libraries. For MinGW (or clang, or GNU gcc, and so on) compiler you just need to provide option -I path_incl, -L path_lib, where path_inc and path_lib are paths to MathGL include/ and lib/ folders. Alternatively, you can copy MathGL binaries to the MinGW folders (include/ to include/, lib/ to lib/ and so on) and do nothing special else. For Visual Studio you need to create the import library first. Finally, add the MathGL library to the project -- in MinGW compiler add option -lmgl (and similar ones if you use MathGL widgets). Instead of steps 1-2, you can download sources and build the MathGL libraries with dependencies/features, which you need. Note, that minimal version have no external dependencies but support plot export to BMP, EPS and SVG only, have no special functions, nonlinear fitting and use slow Fourier transform. The build system use CMake and is rather standard. After building binaries, continue from step 3 :-). ============= mgllab =========== * Manual data changing should be written into script ?!? * Check: "You can shift axis range by pressing middle button and moving mouse. Also, you can zoom in/out axis range by using mouse wheel." * Shift/Zoom/Perspective by mouse!!! * 1d view -- over longer size + y-size for current slice only * info about used memory for graphics * "debug" mode?!? or breakpoints?! * something strange with highlighting * collect mouse clicks to draw line(s) and save it into data * select 'bbox' by mouse * dialog to visual construct "custom dialog" + read/add "##d" to the end of file. * check manual dash/mask X. Own file-chooser dialog -- separate path and fname fields + add sorting by date|size ??? Y. Window with Zoom/Hidden ??? ============= UDAV ============= 1. Zoom rectangle after mouse selection 3. Manual data changing should be written into script a. Suggest to save into HDF5 if data changed manually b. Each manual change in cell produce command like 'put dat val i j k' c. Add command to insert as 'list' d. Reset script after saving to HDF5 or putting to main script e. Ask about script changes before closing data tab 4. List of constants into the list of data?! 5. Add color cycle ??? 6. Color position in color scheme dialog 7. Select 'bbox' by mouse 9. Save data from the summary panel 10. Select subdata section (between NAN in curve) by mouse + adding it to script ?!! 11. Zoom in a region by middle mouse (if not in rotation mode) * "debug" mode?!? or breakpoints?! * collect mouse clicks to draw line(s) and save it into data * Animation from ##c, ##a + remove old entries at "Put to script" (the same in mgllab) * Custom dialog in QMathGL ============= UNSURE =========== 1. GTK window/widgets ??? 2. "Cut off" curves if text is printed inside it (for contour labels) ?!? 5. Check RunThr() in python/octave 6. Auto axis range for formulas, like AutoRange("y(x)") or AutoRange('x',"x(t)"). 7. Use Hershey as built-in font ??? -- for smaller size only �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/cmake-qt4.txt��������������������������������������������������������������������������0000644�0001750�0001750�00000000600�13513030041�015470� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set(MGL_HAVE_QT4 1) set(MGL_QT4_LIBS_FIND QtCore QtGui QtOpenGL) set(MGL_QT4_LIBS_FIND_JSON QtNetwork QtWebKit) FIND_PACKAGE(Qt4 4.8 REQUIRED ${MGL_QT4_LIBS_FIND}) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(MGL_QT4_LIBS) foreach(mgl_qt4_lib ${MGL_QT4_LIBS_FIND}) set(MGL_QT4_LIBS ${MGL_QT4_LIBS} Qt4::${mgl_qt4_lib}) endforeach(mgl_qt4_lib) ��������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/utils/���������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�13513030041�014305� 5����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mathgl-2.4.4/utils/CMakeLists.txt�������������������������������������������������������������������0000644�0001750�0001750�00000002711�13513030041�017046� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������add_executable(make_pas make_pas.cpp) add_executable(mgltask mgltask.cpp) install( TARGETS mgltask EXPORT MathGLTargets RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR} ) add_executable(mglconv mglconv.cpp) if(MSVC) set(link_type -static) else(MSVC) set(link_type) endif(MSVC) target_link_libraries(mglconv mgl${link_type} ${getopt_lib-static}) install( TARGETS mglconv EXPORT MathGLTargets RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR} ) add_executable(mgl.cgi mglcgi.cpp) target_link_libraries(mgl.cgi mgl-static) install( TARGETS mgl.cgi EXPORT MathGLTargets # should be /usr/lib/cgi-bin/ RUNTIME DESTINATION ${MGL_CGI_PATH} ) mgl_po_src(mglconv.cpp mglview.cpp mglcgi.cpp) if(MGL_HAVE_FLTK) add_definitions(-DUSE_FLTK) add_executable(mglview mglview.cpp) target_link_libraries(mglview mgl-fltk ${getopt_lib-static} ${FLTK_LIBRARIES}) install( TARGETS mglview EXPORT MathGLTargets RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR} ) else(MGL_HAVE_FLTK) if(QT_ENABLED) add_executable(mglview mglview.cpp) if(enable-qt5) include(../scripts/qt5.cmake) target_link_libraries(mglview mgl-qt5${link_type} ${getopt_lib-static} ${MGL_QT5_LIBS}) else(enable-qt5) include(../scripts/qt4.cmake) target_link_libraries(mglview mgl-qt4${link_type} ${getopt_lib-static} ${MGL_QT4_LIBS}) endif(enable-qt5) install( TARGETS mglview EXPORT MathGLTargets RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR} ) endif(QT_ENABLED) endif(MGL_HAVE_FLTK) �������������������������������������������������������mathgl-2.4.4/utils/make_forth.cpp�������������������������������������������������������������������0000644�0001750�0001750�00000015721�13513030041�017136� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include #include const char *files[]={"../include/mgl2/base_cf.h","../include/mgl2/data_cf.h", "../include/mgl2/datac_cf.h", "../include/mgl2/cont.h", "../include/mgl2/fit.h", "../include/mgl2/plot.h", "../include/mgl2/surf.h", "../include/mgl2/volume.h", "../include/mgl2/vect.h", "../include/mgl2/prim.h", "../include/mgl2/other.h", "../include/mgl2/canvas_cf.h", "../include/mgl2/addon.h", ""}; const char *head="\\ Mathgl library wrapper\n\ \\ Copyright (C) 2008-2013, Sergey Plis, Alexey Balakin\n\\\n\ \\ This program is free software; you can redistribute it and/or modify\n\ \\ it under the terms of the GNU General Public License as published by\n\ \\ the Free Software Foundation; either version 2 of the License, or\n\ \\ (at your option) any later version.\n\\\n\ \\ This program is distributed in the hope that it will be useful,\n\ \\ but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ \\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ \\ GNU General Public License for more details.\n\n\ Module mathgl\n\ library libmgl libmgl.so\n\ library libmgl-glut libmgl-glut.so\n\ library libmgl-fltk libmgl-fltk.so\n\ library libmgl-qt libmgl-qt.so\n\ library libmgl-wx libmgl-wx.so\n\ legacy off\n\n\ libmgl mgl_create_graph_gl\t\t(ptr)\tmgl_create_graph_gl\n\ libmgl-glut mgl_create_graph_glut\tptr ptr ptr\t(ptr)\tmgl_create_graph_glut\n\ libmgl-fltk mgl_create_graph_fltk\tptr ptr ptr\t(ptr)\tmgl_create_graph_fltk\n\ libmgl-fltk mgl_fltk_run\t\t(void)\tmgl_fltk_run\n\ libmgl-qt mgl_create_graph_qt\tptr ptr ptr\t(ptr)\tmgl_create_graph_qt\n\ libmgl-qt mgl_qt_run\t\t\t(void)\tmgl_qt_run\n"; const char *parse_name(char *name, char *fnc) { static char res[1024]; memset(res,0,1024); char *ptr,*arg[20],nul=0; // TODO check if 20 arguments is enough unsigned i; for(i=0;name[i]!='(';i++) res[i]=name[i]; memcpy(fnc,res,i); fnc[i]=0; // copy name for later res[i]='\t'; i++; for(int j=1;j<=(25-i)/4;j++) res[i+j-1]='\t'; /* static char res[1024]; char *ptr,*arg[20],nul=0; // TODO check if 20 arguments is enough unsigned i; for(i=0;name[i]!='(';i++) res[i]=name[i]; memcpy(fnc,res,i); fnc[i]=0; // copy name for later res[i]='\t'; res[i+1]=0; i++;*/ while(name[i]<=' ') i++; for(int j=0;j<20;j++) arg[j]=&nul; for(int j=0;j<20;j++) { arg[j]= name[i]<=' ' ? name+i+1 : name+i; ptr=strchr(name+i,','); if(!ptr) break; *ptr=0; i=ptr-name+1; } ptr=strchr(name+i,')'); if(ptr) *ptr=0; for(int j=19;j>=0;j--) { if(arg[j][0]==0) continue; if(!strncmp(arg[j],"HMGL ",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"HADT ",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"HCDT ",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"HMDT ",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"HMPR ",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"HMEX ",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"const float *",13)) strcat(res, "ptr "); else if(!strncmp(arg[j],"const double *",14)) strcat(res, "ptr "); else if(!strncmp(arg[j],"mreal *",7)) strcat(res, "ptr "); else if(!strncmp(arg[j],"double *",8)) strcat(res, "ptr "); else if(!strncmp(arg[j],"char *",6)) strcat(res, "ptr "); else if(!strncmp(arg[j],"int *",5)) strcat(res, "ptr "); else if(!strncmp(arg[j],"long *",6)) strcat(res, "ptr "); else if(!strncmp(arg[j],"const char *",12)) strcat(res, "ptr "); else if(!strncmp(arg[j],"const wchar_t *",15)) strcat(res, "ptr "); else if(!strncmp(arg[j],"char ",5)) strcat(res, "char "); else if(!strncmp(arg[j],"long ",5)) strcat(res, "int "); else if(!strncmp(arg[j],"uint32_t ",9)) strcat(res, "int "); else if(!strncmp(arg[j],"int ",4)) strcat(res, "int "); else if(!strncmp(arg[j],"mreal ",6)) strcat(res, "sf "); else if(!strncmp(arg[j],"double ",7)) strcat(res, "double "); else if(!strncmp(arg[j],"gsl_vector *",12)) strcat(res, "ptr "); else if(!strncmp(arg[j],"gsl_matrix *",12)) strcat(res, "ptr "); else sprintf(res, " !!! %s;", arg[j]); // NOTE should be never here } return res; } bool parse_file(const char *fname, FILE *out) { if(!fname || fname[0]==0) return false; FILE *fp=fopen(fname,"rt"); if(!fp) return false; char buf[1024], *ptr, fnc[128]=""; while(!feof(fp)) { fgets(buf,1024,fp); // first filter unwanted strings if(buf[0]==0 || buf[0]=='\n' || buf[1]=='\n') continue; if(buf[0]=='#' || buf[0]=='}') continue; if(!strncmp(buf, "extern",6)) continue; if(!strncmp(buf, "class",5)) continue; if(!strncmp(buf, "struct",6)) continue; if(!strncmp(buf, "typedef",7)) continue; if(strstr(buf, "void *")) continue; if(strstr(buf, "_(")) continue; if(strstr(buf, "FILE")) continue; if(strstr(buf, "TODO")) continue; if(strstr(buf, "//")) continue; if(strstr(buf, "...)")) continue; // TODO following 5 lines enable later if(strstr(buf, "* const *")) continue; if(strstr(buf, "uint64_t")) continue; if(strstr(buf, "dual")) continue; if(strstr(buf, "HADT")) continue; if(strstr(buf, "HAEX")) continue; // now filter comments if(buf[0]=='/' && buf[1]=='*') { do fgets(buf,1024,fp); while(!strstr(buf,"*/")); continue; } ptr = strchr(buf,';'); if(ptr) *ptr=' '; for(unsigned i=strlen(buf)-1;buf[i]<=' ';i--) buf[i]=0; if(buf[0]=='/' && buf[1]=='/') fprintf(out,"%s\n",buf); else if(!strncmp(buf,"void MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(void)\t%s\n",parse_name(buf+16,fnc),fnc); else if(!strncmp(buf,"int MGL_EXPORT",14)) fprintf(out,"libmgl %s\t(int)\t%s\n",parse_name(buf+15,fnc),fnc); else if(!strncmp(buf,"double MGL_EXPORT",17)) fprintf(out,"libmgl %s\t(double)\t%s\n",parse_name(buf+18,fnc),fnc); else if(!strncmp(buf,"mreal MGL_EXPORT",16)) fprintf(out,"libmgl %s\t(sf)\t%s\n",parse_name(buf+17,fnc),fnc); else if(!strncmp(buf,"long MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(int)\t%s\n",parse_name(buf+16,fnc),fnc); else if(!strncmp(buf,"HMDT MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+16,fnc),fnc); else if(!strncmp(buf,"HMGL MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+16,fnc),fnc); else if(!strncmp(buf,"MGL_EXPORT const char *",23)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+24,fnc),fnc); else if(!strncmp(buf,"MGL_EXPORT mreal *",18)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+19,fnc),fnc); else if(!strncmp(buf,"MGL_EXPORT const unsigned char *",32)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+33,fnc),fnc); else if(!strncmp(buf,"HMPR MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+16,fnc),fnc); else if(!strncmp(buf,"HMEX MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+16,fnc),fnc); else if(!strncmp(buf,"HADT MGL_EXPORT",15)) fprintf(out,"libmgl %s\t(ptr)\t%s\n",parse_name(buf+16,fnc),fnc); else fprintf(out,"!!!!\t%s\n",buf); // NOTE should be never here! } fclose(fp); return true; } int main() { FILE *fout = fopen("../include/mgl2/mgl.fs","wt"); fprintf(fout,"%s\n",head); for(int i=0;parse_file(files[i],fout);i++); fclose(fout); return 0; } �����������������������������������������������mathgl-2.4.4/utils/mglview.cpp����������������������������������������������������������������������0000644�0001750�0001750�00000011755�13513030041�016474� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * mglview.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mgl2/mgl.h" #if USE_FLTK #include "mgl2/fltk.h" #include #include #else #include "mgl2/qt.h" #endif //----------------------------------------------------------------------------- std::wstring str, opt; std::vector anim; mglParse p(true); void prop_func(char id, const char *val, void *) { p.AddParam(id<='9' ? id-'0' : id-'a'+10, val); } //----------------------------------------------------------------------------- int show(mglGraph *gr) { if(anim.size()>0) { for(size_t i=0;iNewFrame(); p.AddParam(0,anim[i].c_str()); p.Execute(gr,str.c_str()); gr->EndFrame(); } return gr->GetNumFrame(); } p.Execute(gr,str.c_str()); printf("%s\n",gr->Message()); return 0; } //----------------------------------------------------------------------------- int main(int argc, char **argv) { mgl_textdomain(argv?argv[0]:NULL,""); char iname[256]=""; mgl_suppress_warn(true); bool gray = false; while(1) { int ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hL:s:g:v:"); if(ch>='1' && ch<='9') p.AddParam(ch-'0', optarg); else if(ch=='s') { FILE *fp = fopen(optarg,"r"); if(fp) { wchar_t ch; while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) opt.push_back(ch); fclose(fp); } } else if(ch=='v') p.SetVariant(atoi(optarg)); else if(ch=='g') gray= atoi(optarg); else if(ch=='L') { setlocale(LC_ALL, optarg); setlocale(LC_NUMERIC, "C"); } else if(ch=='h' || (ch==-1 && optind>=argc)) { printf(_("mglview show plot from MGL script or MGLD file.\nCurrent version is 2.%g\n"),MGL_VER2); printf(_("Usage:\tmglview [parameter(s)] scriptfile\n")); printf( _("\t-1 str set str as argument $1 for script\n" "\t... ...\n" "\t-9 str set str as argument $9 for script\n" "\t-g val set gray-scale mode (val=0|1)\n" "\t-v val set variant of arguments\n" "\t-s opt set MGL script for setting up the plot\n" "\t-L loc set locale to loc\n" "\t- get script from standard input\n" "\t-h print this message\n") ); return 0; } else if(ch==-1 && optind par; bool mgld=(*iname && iname[strlen(iname)-1]=='d'); if(!mgld) { str = opt + L"\n"; FILE *fp = *iname?fopen(iname,"r"):stdin; if(fp) { wchar_t ch; std::string text; while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) { str.push_back(ch); text.push_back(ch); } fclose(fp); double a1, a2, da; mgl_parse_comments(text.c_str(), a1, a2, da, anim, ids, par); // if(!ids.empty()) dr->gr->dialog(ids,par); } else { printf("No file for MGL script\n"); return 0; } } #if USE_FLTK mgl_ask_func = mgl_ask_fltk; mgl_progress_func = mgl_progress_fltk; mglFLTK gr(mgld?NULL:show, *iname?iname:"mglview"); #else mgl_ask_func = mgl_ask_qt; mglQT gr(mgld?NULL:show, *iname?iname:"mglview"); #endif gr.SetPropFunc(prop_func,NULL); gr.MakeDialog(ids, par); if(gray) gr.Gray(gray); if(mgld) { gr.Setup(false); gr.NewFrame(); const std::string loc = setlocale(LC_NUMERIC, "C"); if(!opt.empty()) { p.Execute(&gr,opt.c_str()); printf("Setup script: %s\n",gr.Message()); gr.ImportMGLD(iname,true); } else gr.ImportMGLD(iname); setlocale(LC_NUMERIC, loc.c_str()); gr.EndFrame(); gr.Update(); } if(!mglGlobalMess.empty()) printf("%s",mglGlobalMess.c_str()); return gr.Run(); } //----------------------------------------------------------------------------- �������������������mathgl-2.4.4/utils/mglcgi.cpp�����������������������������������������������������������������������0000644�0001750�0001750�00000007162�13513030041�016261� 0����������������������������������������������������������������������������������������������������ustar �alastair������������������������alastair���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * mglcgi.cpp is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "mgl2/mgl.h" //----------------------------------------------------------------------------- int MGL_LOCAL_CONST mgl_hex(char ch) { int res=-1; if(ch>='0' && ch<='9') res = ch-'0'; if(ch>='a' && ch<='f') res = ch-'a'+10; if(ch>='A' && ch<='F') res = ch-'A'+10; return res; } //----------------------------------------------------------------------------- /// Parse CGI string buf and return usual string as val for given name. /// The size of val should be the same as size of buf. void mgl_get_value(const char *buf, const char *name, char *val) { const char *pos = strstr(buf,name); memset(val,0,strlen(buf)+1); if(pos && (pos==buf || pos[-1]=='&')) { pos+=4; // shift for "mgl=" size_t l=strlen(pos); for(size_t i=0, j=0;i\n"); printf("\n"); printf("MathGL - library for scientific graphics\n"); // printf("

MGL script output

\n

The script

\n
%s

give

\n",str); gr.WriteSVG("-"); fflush(stdout); printf("\n\n"); // printf("Content-Type: image/png\n\n"); gr.WritePNG("-"); if(alloc) delete []buf; return 0; } //----------------------------------------------------------------------------- mathgl-2.4.4/utils/mgltask.cpp0000644000175000017500000001130613513030041016454 0ustar alastairalastair#include #include #include #include #include #include //=================================================================== #define IM1 2147483563 #define IM2 2147483399 #define AM (1.0/IM1) #define IMM1 (IM1-1) #define IA1 40014 #define IA2 40692 #define IQ1 53668 #define IQ2 52774 #define IR1 12211 #define IR2 3791 #define NTAB 32 #define NDIV (1+IMM1/NTAB) #define EPS 1.2e-7 #define RNMX (1.0-EPS) #ifndef NULL #define NULL 0L #endif //=================================================================== double Random() // Long period (> 2 * 10^18 ) random number generator of L'Ecuyer with // Bays-Durham shuffle and added safeguards. Returns a uniform random deviate // between 0.0 and 1.0 (exclusive of the endpoint values). Call with idum a // negative integer to initialize; thereafter, do not alter idum between // successive deviates in a sequence. RNMX should approximate the largest // floating value that is less than 1. { static long idum=0; int j; long k; static long idum2=123456789; static long iy=0; static long iv[NTAB]; double temp; if(idum==0) idum = -(long)(time(NULL)); if (idum <= 0) { // Initialize. if (-(idum) < 1) idum=1; // Be sure to prevent idum = 0. else idum = -(idum); idum2=(idum); for (j=NTAB+7;j>=0;j--) { // Load the shuffle table (after 8 warm-ups). k=(idum)/IQ1; idum=IA1*(idum-k*IQ1)-k*IR1; if (idum < 0) idum += IM1; if (j < NTAB) iv[j] = idum; } iy=iv[0]; } k=(idum)/IQ1; // Start here when not initializing. idum=IA1*(idum-k*IQ1)-k*IR1; // Compute idum=(IA1*idum) % IM1 without // over ows by Schrage's method. if (idum < 0) idum += IM1; k=idum2/IQ2; idum2=IA2*(idum2-k*IQ2)-k*IR2; // Compute idum2=(IA2*idum) % IM2 likewise. if (idum2 < 0) idum2 += IM2; j=iy/NDIV; // Will be in the range 0..NTAB-1. iy=iv[j]-idum2; // Here idum is shued, idum and idum2 are // combined to generate output. iv[j] = idum; if (iy < 1) iy += IMM1; if ((temp=AM*iy) > RNMX) // Because users don't expect endpoint values. return RNMX; else return temp; } //=================================================================== int strpos(char *str,char ch) { char *p=strchr(str,ch); int res; if(p) res = p-str; else res = -1; return res; } //=================================================================== // multi_task empl_7b_tr.ini empl.ini 0:1:2 2:2:6 int main(int argc, char *argv[]) { bool e[10]; if(argc<3) // if incorrect number of arguments then print the help { printf("mgltask make output file with a set of copies of mask-file with repeatedly replaced $# by loop values. It useful for making set of initial conditions with a few parameters varied in specified range.\n"); printf("Usage:\tmgltask maskfile outputfile [min1:step1:max1] [min2:step2:max2]\n\n"); printf("\tmask file -- mask file in which all '$#' will be replaced by counter # value\n"); printf("\t\tHere # = 0 is random number in [0,1].\n"); printf("\t\tHere # = 1,2...9 is counter number.\n"); printf("\toutputfile -- file where result will be saved\n"); printf("\tmin#:step#:max# -- is minimum, step increment and maximum values of counter #\n"); printf("\t'e'min#:step#:max# -- the same but in exponential form 10^#\n"); // system("PAUSE"); return 0; } //char maskname[256],outname[256]; char str[1024],*buf; double x1[10],x2[10],dx[10],x[10]; int k,i,n=argc-3;//=(argc==4) ? 1:2; FILE *fm,*fo; // first place zeros for(i=0;i<10;i++) { x1[i] = x2[i] = 0; dx[i] = 1; e[i] = false; } printf("mask = %s, out = %s\n",argv[1],argv[2]); // read parameters of loops for(i=0;i=0 && k * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mgl2/mgl.h" #include "mgl2/wnd.h" #ifdef _MSC_VER #define mnpos (std::basic_string::size_type)-1 #else #define mnpos std::wstring::npos #endif //----------------------------------------------------------------------------- int main(int argc, char *argv[]) { mgl_textdomain(argv?argv[0]:NULL,""); mgl_suppress_warn(true); mglGraph gr; mglParse p(true); char buf[2048], iname[256]="", oname[256]=""; std::vector var; // animation variants std::wstring str; // script bool none=false; while(1) { int ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hno:L:C:A:s:S:q:v:g:"); if(ch>='1' && ch<='9') p.AddParam(ch-'0', optarg); else if(ch=='s') { FILE *fp = fopen(optarg,"r"); if(fp) { wchar_t ch; while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) str.push_back(ch); fclose(fp); str += L"\n"; } } else if(ch=='n') none = true; else if(ch=='L') { setlocale(LC_ALL, optarg); setlocale(LC_NUMERIC, "C"); } else if(ch=='S') mgl_set_size_scl(atof(optarg)); else if(ch=='q') gr.SetQuality(atoi(optarg)); else if(ch=='v') p.SetVariant(atoi(optarg)); else if(ch=='g') gr.Gray(atoi(optarg)); else if(ch=='A') { std::wstring s; for(size_t i=0;optarg[i];i++) s.push_back(optarg[i]); var.push_back(s); } else if(ch=='C') { double v1,v2,dv=1,v; int res=sscanf(optarg,"%lg:%lg:%lg",&v1,&v2,&dv); if(res<3) dv=1; wchar_t num[64]; for(v=v1;v<=v2;v+=dv) { mglprintf(num,64,L"%g",v); var.push_back(num); } } else if(ch=='h' || (ch==-1 && optind>=argc)) { printf(_("mglconv convert mgl script to image file (default PNG).\nCurrent version is 2.%g\n"),MGL_VER2); printf(_("Usage:\tmglconv [parameter(s)] scriptfile\n")); printf( _("\t-1 str set str as argument $1 for script\n" "\t... ...\n" "\t-9 str set str as argument $9 for script\n" "\t-L loc set locale to loc\n" "\t-s fname set MGL script for setting up the plot\n" "\t-S val set scaling factor for images\n" "\t-q val set quality for output (val=0...9)\n" "\t-g val set gray-scale mode (val=0|1)\n" "\t-v val set variant of arguments\n" "\t-o name set output file name\n" "\t-n no default output (script should save results by itself)\n" "\t-A val add animation value val\n" "\t-C n1:n2:dn add animation value in range [n1,n2] with step dn\n" "\t-C n1:n2 add animation value in range [n1,n2] with step 1\n" "\t- get script from standard input\n" "\t-h print this message\n") ); return 0; } else if(ch=='o') mgl_strncpy(oname, optarg,256); else if(ch==-1 && optind1) // there is animation { if(gif) gr.StartGIF(oname); for(size_t i=0;i #include #include const char *files[] = { "../../include/mgl2/abstract.h", "../../include/mgl2/base_cf.h", "../../include/mgl2/data_cf.h", "../../include/mgl2/datac_cf.h", "../../include/mgl2/cont.h", "../../include/mgl2/fit.h", "../../include/mgl2/plot.h", "../../include/mgl2/surf.h", "../../include/mgl2/volume.h", "../../include/mgl2/vect.h", "../../include/mgl2/prim.h", "../../include/mgl2/other.h", "../../include/mgl2/canvas_cf.h", "../../include/mgl2/addon.h", "" }; const char *head = "//**************************************************************************\n\ // mgl_pas.pas is part of Math Graphic Library *\n\ // Copyright (C) 2008-2013 Mikhail Barg, Alexey Balakin *\n\ // *\n\ // This program is free software; you can redistribute it and/or modify *\n\ // it under the terms of the GNU Library General Public License as *\n\ // published by the Free Software Foundation; either version 2 of the *\n\ // License, or (at your option) any later version. *\n\ // *\n\ // This program is distributed in the hope that it will be useful, *\n\ // but WITHOUT ANY WARRANTY; without even the implied warranty of *\n\ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\n\ // GNU General Public License for more details. *\n\ // *\n\ // You should have received a copy of the GNU Library General Public *\n\ // License along with this program; if not, write to the *\n\ // Free Software Foundation, Inc., *\n\ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\n\ //**************************************************************************\n\n\ unit mgl_pas;\n\n\ {$IFDEF FPC}\n\ {$MODE DELPHI }\n\ {$PACKENUM 4} (* use 4-byte enums *)\n\ {$PACKRECORDS C} (* C/C++-compatible record packing *)\n\ {$ELSE}\n\ {$MINENUMSIZE 4} (* use 4-byte enums *)\n\ {$ENDIF}\n\n\ {$IFDEF DARWIN}\n\ {$linklib libmgl}\n\ {$ENDIF}\n\n\ interface\n\n\ uses\n\ {$IFDEF MSWINDOWS}\n\ Windows, Graphics,\n\ {$ENDIF}\n\ Math;\n\n\ const MGL_VER2 = 2.2;\n\ //* This define enables double precision in MathGL */\n\ MGL_USE_DOUBLE = 1;\n\n\ const\n\ {$IFDEF MSWINDOWS}\n\ //win - .dll\n\ libmgl = 'libmgl.dll';\n\ libmglglut = 'libmgl-glut.dll';\n\ libmglfltk = 'libmgl-fltk.dll';\n\ libmglqt = 'libmgl-qt.dll';\n\ {$ELSE}\n\ {$IFDEF LINUX}\n\ //linux - .so\n\ libmgl = 'libmgl.so';\n\ libmglglut = 'libmgl-glut.so';\n\ libmglfltk = 'libmgl-fltk.so';\n\ libmglqt = 'libmgl-qt.so';\n\ {$ELSE}\n\ {$IFDEF DARWIN}\n\ //darwin - .dylib\n\ libmgl = 'libmgl.dylib';\n\ libmglglut = 'libmgl-glut.dylib';\n\ libmglfltk = 'libmgl-fltk.dylib';\n\ libmglqt = 'libmgl-qt.dylib';\n\ {$ELSE}\n\ // other platforms?\n\n\ {$ENDIF}\n\ {$ENDIF}\n\ {$ENDIF}\n\n\ {$IF (MGL_USE_DOUBLE = 0)}\n\ type mreal = double;\n\ {$ELSE}\n\ type mreal = real;\n\ {$IFEND}\n\ {$IFDEF FPC}\n\ {$ELSE}\n\ type QWord = Int64;\n\ {$ENDIF}\n\n\ Pmreal = ^mreal;\n\n\ type TNGLDraw = record\n\ end;\n\ type TMGLGraph = record\n\ end;\n\ type TMGLData = record\n\ end;\n\ type TMGLParse = record\n\ end;\n\ type TMGLFormula = record\n\ end;\n\ type TMGLFormulaC = record\n\ end;\n\ type TMGLDataC = record\n\ end;\n\ type HMDR = ^TNGLDraw;\n\ type HMGL = ^TMGLGraph;\n\ type HMDT = ^TMGLData;\n\ type HMPR = ^TMGLParse;\n\ type PPChar = ^PChar;\n\ type HMEX = ^TMGLFormula;\n\ type HAEX = ^TMGLFormulaC;\n\ type HADT = ^TMGLDataC;\n\n\ type Preal = ^single;\n\ type Pdouble = ^double;\n\ type Pint = ^integer;\n\ type dual = record\n\ re, im: mreal;\n\ end;\n\ type Pdual = ^dual;\n\ type TGSLVector = record\n\ end;\n\ type TGSLMatrix = record\n\ end;\n\ type PGSLVector = ^TGSLVector;\n\ type PGSLMatrix = ^TGSLMatrix;\n\n\ type TMglDrawFunction = function (gr: HMGL; p: pointer): integer; cdecl;\n\ function mgl_create_graph_gl(): HMGL; cdecl; external libmgl;\n\ function mgl_create_graph_glut(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglglut;\n\ function mgl_create_graph_fltk(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglfltk;\n\ procedure mgl_fltk_run(); cdecl; external libmglfltk;\n\ function mgl_create_graph_qt(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglqt;\n\ procedure mgl_qt_run(); cdecl; external libmglqt;\n"; const char *footer = "\n\ \n\ {$IFDEF MSWINDOWS}\n\ //*****************************************************************************/\n\ // Delphi - specific\n\ //*****************************************************************************/\n\ procedure mgl_begin();\n\ procedure mgl_end();\n\ \n\ procedure mgl_draw_on_canvas(gr: HMGL; width, height: integer; canvas: TCanvas; switchXY: boolean = false);\n\ \n\ implementation\n\ \n\ var _FPUCW: word;\n\ \n\ procedure mgl_begin();\n\ begin\n\ _FPUCW := Get8087CW(); // backup current FPU CW\n\ Set8087CW(_FPUCW or $3F); // masking all FPU exceptions\n\ end;\n\ \n\ procedure mgl_end();\n\ begin\n\ Set8087CW(_FPUCW); // restore old FPU CW\n\ end;\n\ \n\ procedure mgl_draw_on_canvas(gr: HMGL; width, height: integer; canvas: TCanvas; switchXY: boolean = false);\n\ var i, j: integer;\n\ bytes: PByte;\n\ col: TColor;\n\ begin\n\ bytes := mgl_get_rgb(gr);\n\ \n\ if (not switchXY) then\n\ for j := 0 to height - 1 do\n\ for i := 0 to width - 1 do\n\ begin\n\ col := 0;\n\ col := col or (bytes^);\n\ inc(bytes);\n\ col := col or (bytes^) shl 8;\n\ inc(bytes);\n\ col := col or (bytes^) shl 16;\n\ inc(bytes);\n\ canvas.Pixels[i, j] := col;\n\ end\n\ else\n\ for j := height - 1 downto 0 do\n\ for i := 0 to width - 1 do\n\ begin\n\ col := 0;\n\ col := col or (bytes^);\n\ inc(bytes);\n\ col := col or (bytes^) shl 8;\n\ inc(bytes);\n\ col := col or (bytes^) shl 16;\n\ inc(bytes);\n\ canvas.Pixels[j, i] := col;\n\ end;\n\ end;\n\ \n\ {$ENDIF}\n\ end.\n"; bool processArgument(char *dest, const char *arg, const char *prefix, const char *format) { const int prefixLen = strlen(prefix); if ( strncmp(arg, prefix, prefixLen) == 0 ) { char argname[32]; strcpy(argname, arg + prefixLen); if (strcmp(argname, "to") == 0) { int argNameLen = strlen(argname); argname[argNameLen] = '_'; argname[argNameLen + 1] = 0; } sprintf(dest, format, argname); return true; } return false; } const char *parse_name(char *name, bool &needOverload) { const int MAX_ARG = 20; // TODO check if 20 arguments is enough static char res[1024]; char *ptr, *arg[MAX_ARG], nul = 0; unsigned i, j; needOverload = false; for ( i = 0; name[i] != '('; ++i ) { res[i] = name[i]; } // res[i] = 0; // printf("'%s'\n", res); //TODO: special case, invent some general way to handle overloads, i.e. functions with same names. Still would require re-doing whole parser.. if (strncmp(res, " mgl_expi", i - 1) == 0) { needOverload = true; } res[i] = '('; res[i + 1] = 0; ++i; while ( name[i] <= ' ' ) { ++i; } for ( j = 0; j < MAX_ARG; ++j ) { arg[j] = &nul; } for ( j = 0; j < MAX_ARG; ++j ) { arg[j] = (name[i] <= ' ' ? name + i + 1 : name + i); ptr = strchr(name + i, ','); if ( !ptr ) { break; } *ptr = 0; i = ptr - name + 1; } ptr = strchr(name + i, ')'); if ( ptr ) { *ptr = 0; } if ( arg[0][0] == 0 ) { strcat(res, " "); } for ( j = 0; j < MAX_ARG; ++j ) { if ( arg[j][0] == 0 ) { break; } ptr = res + strlen(res); if ( processArgument(ptr, arg[j], "HMGL ", "%s: HMGL;") || processArgument(ptr, arg[j], "HCDT ", "const %s: HMDT;") || processArgument(ptr, arg[j], "HMDT ", "%s: HMDT;") || processArgument(ptr, arg[j], "mglDataA *", "%s: HMDT;") || processArgument(ptr, arg[j], "HADT ", "%s: HADT;") || processArgument(ptr, arg[j], "HAEX ", "%s: HAEX;") || processArgument(ptr, arg[j], "HMPR ", "%s: HMPR;") || processArgument(ptr, arg[j], "HMEX ", "%s: HMEX;") || processArgument(ptr, arg[j], "const float *", "const %s: Preal;") || processArgument(ptr, arg[j], "const double *", "const %s: Pdouble;") || processArgument(ptr, arg[j], "mreal *", "%s: Pmreal;") || processArgument(ptr, arg[j], "double *", "%s: Pdouble;") || processArgument(ptr, arg[j], "char *", "%s: PChar;") || processArgument(ptr, arg[j], "unsigned char *", "%s: PByte;") || processArgument(ptr, arg[j], "int *", "%s: Pint;") || processArgument(ptr, arg[j], "long *", "%s: Pint;") || processArgument(ptr, arg[j], "const char *", "const %s: PChar;") || processArgument(ptr, arg[j], "const unsigned char *", "const %s: PByte;") || processArgument(ptr, arg[j], "const wchar_t *", "const %s: PWideChar;") || processArgument(ptr, arg[j], "char ", "%s: char;") || processArgument(ptr, arg[j], "long ", "%s: integer;") || processArgument(ptr, arg[j], "uint32_t ", "%s: LongWord;") || processArgument(ptr, arg[j], "uint64_t ", "%s: QWord;") || processArgument(ptr, arg[j], "int ", "%s: integer;") || processArgument(ptr, arg[j], "mreal ", "%s: mreal;") || processArgument(ptr, arg[j], "const dual *", "const %s: Pdual;") || processArgument(ptr, arg[j], "dual *", "%s: Pdual;") || processArgument(ptr, arg[j], "dual ", "%s: dual;") || processArgument(ptr, arg[j], "double ", "%s: double;") || processArgument(ptr, arg[j], "gsl_vector *", "%s: PGSLVector;") || processArgument(ptr, arg[j], "gsl_matrix *", "%s: PGSLMatrix;") ) { //already procedded in processArgument } else { sprintf(ptr, " !!! %s;", arg[j]); } } i = strlen(res); res[i - 1] = ')'; return res; } bool processDeclaration(FILE *out, char *declaration, const char *prefix, const char *format) { const int prefixLen = strlen(prefix); if ( strncmp(declaration, prefix, prefixLen) == 0 ) { bool needOverload = false; fprintf(out, format, parse_name(declaration + prefixLen, needOverload)); if (needOverload) { fprintf(out, "overload;\n"); } return true; } return false; } bool parse_file(const char *fname, FILE *out) { if ( !fname || fname[0] == 0 ) { return false; } FILE *fp = fopen(fname, "rt"); if ( !fp ) { return false; } fprintf(out, "{== %s ==}\n", fname); char buf[1024], *ptr; while ( !feof(fp) ) { if(!fgets(buf, 1024, fp)) break; // first filter unwanted strings if ( buf[0] == 0 || buf[0] == '\n' || buf[1] == '\n' ) { continue; } if ( buf[0] == '#' || buf[0] == '}' ) { continue; } if ( !strncmp(buf, "extern", 6) ) { continue; } if ( !strncmp(buf, "class", 5) ) { continue; } if ( !strncmp(buf, "struct", 6) ) { continue; } if ( !strncmp(buf, "typedef", 7) ) { continue; } if ( strstr(buf, "void *") ) { continue; } if ( strstr(buf, "_(") ) { continue; } if ( strstr(buf, "FILE") ) { continue; } if ( strstr(buf, "TODO") ) { continue; } if ( strstr(buf, "...)") ) { continue; } // TODO enable later if ( strstr(buf, "* const *") ) { continue; } // now filter comments if ( buf[0] == '/' && buf[1] == '*' ) { do { fgets(buf, 1024, fp); } while ( !strstr(buf, "*/") ); continue; } ptr = strchr(buf, ';'); if ( ptr ) { *ptr = ' '; } for ( unsigned i = strlen(buf) - 1; buf[i] <= ' '; i-- ) { buf[i] = 0; } if ( buf[0] == '/' && buf[1] == '/' ) { fprintf(out, "%s\n", buf); } else if ( processDeclaration(out, buf, "void MGL_EXPORT_PURE", "procedure %s; cdecl; external libmgl;\n") || processDeclaration(out, buf, "int MGL_EXPORT_PURE", "function %s: integer; cdecl; external libmgl;\n") || processDeclaration(out, buf, "double MGL_EXPORT_PURE", "function %s: double; cdecl; external libmgl;\n") || processDeclaration(out, buf, "mreal MGL_EXPORT_PURE", "function %s: mreal; cdecl; external libmgl;\n") || processDeclaration(out, buf, "long MGL_EXPORT_PURE", "function %s: integer; cdecl; external libmgl;\n") || processDeclaration(out, buf, "mdual MGL_EXPORT_PURE", "function %s: dual; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_PURE dual *", "function %s: PDual; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMDT MGL_EXPORT_PURE", "function %s: HMDT; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMGL MGL_EXPORT_PURE", "function %s: HMGL; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_PURE const char *", "function %s: PChar; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_PURE mreal *", "function %s: Pmreal; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_PURE const unsigned char *", "function %s: PByte; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMPR MGL_EXPORT_PURE", "function %s: HMPR; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMEX MGL_EXPORT_PURE", "function %s: HMEX; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HADT MGL_EXPORT_PURE", "function %s: HADT; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HAEX MGL_EXPORT_PURE", "function %s: HAEX; cdecl; external libmgl;\n") || processDeclaration(out, buf, "void MGL_EXPORT_CONST", "procedure %s; cdecl; external libmgl;\n") || processDeclaration(out, buf, "int MGL_EXPORT_CONST", "function %s: integer; cdecl; external libmgl;\n") || processDeclaration(out, buf, "double MGL_EXPORT_CONST", "function %s: double; cdecl; external libmgl;\n") || processDeclaration(out, buf, "mreal MGL_EXPORT_CONST", "function %s: mreal; cdecl; external libmgl;\n") || processDeclaration(out, buf, "long MGL_EXPORT_CONST", "function %s: integer; cdecl; external libmgl;\n") || processDeclaration(out, buf, "mdual MGL_EXPORT_CONST", "function %s: dual; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_CONST dual *", "function %s: PDual; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMDT MGL_EXPORT_CONST", "function %s: HMDT; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMGL MGL_EXPORT_CONST", "function %s: HMGL; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_CONST const char *", "function %s: PChar; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_CONST mreal *", "function %s: Pmreal; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT_CONST const unsigned char *", "function %s: PByte; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMPR MGL_EXPORT_CONST", "function %s: HMPR; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMEX MGL_EXPORT_CONST", "function %s: HMEX; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HADT MGL_EXPORT_CONST", "function %s: HADT; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HAEX MGL_EXPORT_CONST", "function %s: HAEX; cdecl; external libmgl;\n") || processDeclaration(out, buf, "void MGL_EXPORT", "procedure %s; cdecl; external libmgl;\n") || processDeclaration(out, buf, "int MGL_EXPORT", "function %s: integer; cdecl; external libmgl;\n") || processDeclaration(out, buf, "double MGL_EXPORT", "function %s: double; cdecl; external libmgl;\n") || processDeclaration(out, buf, "mreal MGL_EXPORT", "function %s: mreal; cdecl; external libmgl;\n") || processDeclaration(out, buf, "long MGL_EXPORT", "function %s: integer; cdecl; external libmgl;\n") || processDeclaration(out, buf, "mdual MGL_EXPORT", "function %s: dual; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT dual *", "function %s: PDual; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMDT MGL_EXPORT", "function %s: HMDT; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMGL MGL_EXPORT", "function %s: HMGL; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT const char *", "function %s: PChar; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT mreal *", "function %s: Pmreal; cdecl; external libmgl;\n") || processDeclaration(out, buf, "MGL_EXPORT const unsigned char *", "function %s: PByte; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMPR MGL_EXPORT", "function %s: HMPR; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HMEX MGL_EXPORT", "function %s: HMEX; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HADT MGL_EXPORT", "function %s: HADT; cdecl; external libmgl;\n") || processDeclaration(out, buf, "HAEX MGL_EXPORT", "function %s: HAEX; cdecl; external libmgl;\n") ) { //already processed by processDeclaration } /* else // comment this -- it looks as it hangs on classes only, which should be omitted by anyway { fprintf(out, "{!!!!\t%s}\n", buf); // NOTE should be never here! }*/ } fclose(fp); return true; } int main() { FILE *fout = fopen("../../include/mgl2/mgl_pas.pas", "wt"); fprintf(fout, "%s\n", head); for ( int i = 0; parse_file(files[i], fout); i++ ) {} fprintf(fout, "%s\n", footer); fclose(fout); return 0; } mathgl-2.4.4/utils/mgl_test.html0000644000175000017500000000111713513030041017011 0ustar alastairalastair MathGL - library for scientific graphics

Enter script below



mathgl-2.4.4/texinfo/0000755000175000017500000000000013513030041014621 5ustar alastairalastairmathgl-2.4.4/texinfo/web_fr.texi0000644000175000017500000007522513513030041016773 0ustar alastairalastair\input texinfo @setfilename mgl_web_en.info @include version.texi @settitle MathGL @value{VERSION} @syncodeindex pg cp @comment %**end of header @copying This website demonstrates the Mathematical Graphic Library (MathGL) version @value{VERSION}, a collection of classes and routines for scientific plotting. Please report any errors in this manual to @email{mathgl.abalakin@@gmail.org}. @include copyright.texi @end copying @titlepage @title MathGL website @subtitle for version @value{VERSION} @author A.A. Balakin (@uref{http://mathgl.sourceforge.net/}) @page @vskip 0pt plus 1filll @insertcopying @end titlepage @contents @ifnottex @node Top @top MathGL This website demonstrates the Mathematical Graphic Library (MathGL), a collection of classes and routines for scientific plotting. It corresponds to release @value{VERSION} of the library. Please report any errors in this manual to @email{mathgl.abalakin@@gmail.org}. More information about MathGL can be found at the project homepage, @uref{http://mathgl.sourceforge.net/}. @include copyright.texi @end ifnottex @menu * Main:: * News:: * Features:: * Pictures:: * MGL scripts:: * Download:: * Other projects:: @end menu @ifhtml @macro external {} @comment @html @comment @comment @comment
@html
SourceForge.net Logo thefreecountry.com: Free Programmers' Resources, Free Webmasters' Resources, Free Security Resources, Free Software Support This Project @end html @end macro @macro fig {plot,text} @uref{../\text\, @image{../small/\plot\-sm,3cm, , , .png}} @end macro @end ifhtml @ifnothtml @macro external {} @end macro @macro fig {plot,text} @uref{http://mathgl.sourceforge.net/\text\, @image{small/\plot\-sm,3cm, , , .png}} @end macro @end ifnothtml @node Main, News, , Top @section MathGL is ... @ifhtml @html Surface in fog @end html @end ifhtml @itemize @bullet @item a library for making high-quality scientific graphics under Linux and Windows; @item a library for the fast data plotting and data processing of large data arrays; @item a library for working in window and console modes and for easy embedding into other programs; @item a library with large and growing set of graphics. @end itemize Now MathGL has more than 35000 lines of code, more than 55 general types of graphics for 1d, 2d and 3d data arrays, including special ones for chemical and statistical graphics. It can export graphics to raster and vector (EPS or SVG) formats. It has Qt, FLTK, OpenGL interfaces and can be used even from console programs. It has functions for data processing and script MGL language for simplification of data plotting. Also it has several types of transparency and smoothed lightning, vector fonts and TeX-like symbol parsing, arbitrary curvilinear coordinate system and many over useful things. It can be used from code written on C++/C/Fortran/Python/Octave and many other languages. Finally it is platform independent and free (under GPL v.2.0 license). There is a @uref{http://sourceforge.net/forum/?group_id=152187, forum} where you can ask a question or suggest an improvement. However the @uref{http://groups.google.com/group/mathgl, MathGL group} is preferable for quicker answer. For subscribing to @uref{http://groups.google.com/group/mathgl, MathGL group} you can use form below @ifhtml @html
Email:
@end html @end ifhtml @strong{About LGPL and GPL licenses.} Generally, MathGL is GPL library. However, you can use LGPL license for MathGL core and widgets if you don't use SWIG-based interfaces and disable GSL features. This can be done by using @code{lgpl} option at build time. According this, I've added the LGPL win32 binaries into @ref{Download} page. @strong{Latest news} @itemize @item @emph{13 December 2012.} New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new plots, advanced color schemes, @uref{../json.html, JavaScript drawing}, and many other improvements in both MathGL core and UDAV, which partially denoted @ref{News, here}. Note, there are @strong{incompatible with v.2.0.* changes} in the arguments of some functions. @item @emph{I'm sorry for making incompatible changes in v.2.1. It was done for introducing unified interface for all functions. I promise that I will not break API for v.2.* later, i.e. I'll only add new features or bug fixes.} @end itemize There is detailed @ref{News, news list}. Sourceforge project page @uref{http://sourceforge.net/projects/mathgl/, here}. @ifhtml @html DATADVANCE @end html @end ifhtml Javascript interface was developed with support of @url{http://www.datadvance.net, DATADVANCE} company. @external{} @node News, Features, Main, Top @section News @itemize @item @strong{13 December 2012.} New version (v.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are speeding up and many improvements and bugfixes: @itemize @bullet @item Add class mglDataC for complex data arrays. @item Add Vect3() plot for drawing vectors on slice of 3d vector field. See @url{../doc_en/doc_en_17.html#Vect3-sample, sample}. @item Add Table() function for drawing table with data values. See @url{../doc_en/doc_en_14.html#Table-sample, sample}. @item Add ZoomAxis() for zooming/shifting axis range as whole. @item Add WriteJSON() function for exporting in JSON format suitable for later drawing by JavaScript @item Add JavaScript code for visualizing JSON data. See @uref{../json.html, samples}. @item Add mgl.cgi tool which return PNG image for CGI request in form of MGL script. @item Add mglData::Solve() for finding x-value where dat(x)=val. See @url{../doc_en/doc_en_12.html#Solve-sample, sample}. @item Add mglData::Clean() for removing rows with duplicate values for given column. @item Add MGL commands 'errbox', 'face' @item Color can be specified as its RGB[A] values, i.e. like @samp{@{xFFFFFF@}} or @samp{@{xFFFFFFFF@}}. See @url{../doc_en/doc_en_23.html#Line-styles, sample}. @item Color in color scheme may have position in range [0,1]. Format is @samp{@{CN,pos@}} or @samp{@{xFFFFFF,pos@}}. See @url{../doc_en/doc_en_24.html#Color-scheme, sample}. @item Now pen width for marks is proportional to pen width of line multiplied by size of marks. @item Now you can use different font-faces in the plot simultaneously. See @url{../doc_en/doc_en_11.html#Text-features, sample}. @item Now Legend() automatically use several columns if it contain too many legend entries. @item Add style '-' for legend for drawing them horizontally. See @url{../doc_en/doc_en_11.html#Legend-sample, sample}. @item Vectors is drawn now even if only starting or ending points are placed in bounding box. @item Strongly rewrite the algorithm of vector field plotting. @item Grid lines for NAN origin values are always located at far-away edges. @item Try correctly place axis and tick labels even for axis with inverse range (i.e. for v2' b'} will give string @samp{'a + b'} (here @samp{
} is newline). @item Usually variable have a name which is arbitrary combination of symbols (except spaces and @samp{'}) started from a letter and with length less than 64. A temporary array can be used as variable: @itemize @bullet @item sub-arrays (like in @code{subdata} command) as command argument. For example, @code{a(1)} or @code{a(1,:)} or @code{a(1,:,:)} is second row, @code{a(:,2)} or @code{a(:,2,:)} is third column, @code{a(:,:,0)} is first slice and so on. Also you can extract a part of array from m-th to n-th element by code @code{a(m:n,:,:)} or just @code{a(m:n)}. @item any column combinations defined by formulas, like @code{a('n*w^2/exp(t)')} if names for data columns was specified (by @code{idset} command or in the file at string started with @code{##}). @item any expression (without spaces) of existed variables produce temporary variable. For example, @samp{sqrt(dat(:,5)+1)} will produce temporary variable with data values equal to @code{tmp[i,j] = sqrt(dat[i,5,j]+1)}. @item temporary variable of higher dimensions by help of []. For example, @samp{[1,2,3]} will produce a temporary vector of 3 elements @{1, 2, 3@}; @samp{[[11,12],[21,22]]} will produce matrix 2*2 and so on. Here you can join even an arrays of the same dimensions by construction like @samp{[v1,v2,...,vn]}. @item result of code for making new data inside @{@}. For example, @samp{@{sum dat 'x'@}} produce temporary variable which contain result of summation of @var{dat} along direction 'x'. This is the same array @var{tmp} as produced by command @samp{sum tmp dat 'x'}. You can use nested constructions, like @samp{@{sum @{max dat 'z'@} 'x'@}}. @end itemize Temporary variables can not be used as 1st argument for commands which create (return) the data (like @samp{new}, @samp{read}, @samp{hist} and so on). @item Special names @code{nan=#QNAN, pi=3.1415926..., on=1, off=0, :=-1} are treated as number if they were not redefined by user. Variables with suffixes are treated as numbers. Names defined by @code{define} command are treated as number. Also results of formulas with sizes 1x1x1 are treated as number (for example, @samp{pi/dat.nx}). @end itemize Before the first using all variables must be defined with the help of commands, like, @code{new}, @code{var}, @code{list}, @code{copy}, @code{read}, @code{hist}, @code{sum} and so on. Command may have several set of possible arguments (for example, @code{plot ydat} and @code{plot xdat ydat}). All command arguments for a selected set must be specified. However, some arguments can have default values. These argument are printed in [], like @code{text ydat ['stl'='']} or @code{text x y 'txt' ['fnt'='' size=-1]}. At this, the record @code{[arg1 arg2 arg3 ...]} means @code{[arg1 [arg2 [arg3 ...]]]}, i.e. you can omit only tailing arguments if you agree with its default values. For example, @code{text x y 'txt' '' 1} or @code{text x y 'txt' ''} is correct, but @code{text x y 'txt' 1} is incorrect (argument @code{'fnt'} is missed). For more details see @uref{../doc_en/doc_en_64.html#MGL-scripts, MathGL documentation} @external{} @node Download, Other projects, MGL scripts, Top @section Download @strong{Stable version (v.@value{VERSION})} You may download current version of MathGL for following configurations: @itemize @bullet @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}.tar.gz,source} file with cmake build system. @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}-mingw.i686.7z,Win32 GPL} binaries for MinGW (build for i686) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}.LGPL-mingw.i686.7z,Win32 LGPL} binaries for MinGW (build for i686, no GSL and HDF5 support) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}.LGPL-win64.7z,Win64 LGPL} binaries for MSVS 2010 (no GSL and HDF5 support) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}-1.DevPack,DevPak} package for Dev-C++ or Code::Blocks (GPL version) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}.eng.pdf,PDF} documentation in English @item @uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}.7z,utilities} with all required DLL files (build for i686) @c HTML documentation in English @c HTML documentation in Russian @c @item @c @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features @end itemize @strong{Previous version (v.1.11.2)} You may download current version of MathGL for following configurations: @itemize @bullet @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2.tar.gz,source} file with autoconf/automake script. @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2-mingw.i686.zip,Win32 GPL} binaries for MinGW (build for i686) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.1.1.LGPL-mingw.i686.zip,Win32 LGPL} binaries for MinGW (build for i686, no GSL and HDF5 support) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2-1.DevPack,DevPak} package for Dev-C++ or Code::Blocks (GPL version) @item @uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2.eng.pdf,PDF} documentation in English @c HTML documentation in English @c HTML documentation in Russian @item @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features @end itemize @strong{Font files} There are a set of @uref{http://sourceforge.net/project/showfiles.php?group_id=152187&package_id=267177,font files} for MathGL with following typefaces. Note, that the set of glyphs can be less than in default font. As result not all TeX symbols can be displayed. @itemize @bullet @item @uref{http://downloads.sourceforge.net/mathgl/STIX_font.tgz,STIX} font -- default font for MathGL. @item @uref{http://downloads.sourceforge.net/mathgl/adventor_font.tgz,Adventor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Gothic L family (like Avant Garde Gothic). @item @uref{http://downloads.sourceforge.net/mathgl/bonum_font.tgz,Bonum font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Bookman L family. @item @uref{http://downloads.sourceforge.net/mathgl/chorus_font.tgz,Chorus font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} font based on the URW Chancery L Medium Italic. @item @uref{http://downloads.sourceforge.net/mathgl/cursor_font.tgz,Cursor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} monospaced serif font based on the URW Nimbus Mono L (like Courier). @item @uref{http://downloads.sourceforge.net/mathgl/heros_font.tgz,Heros font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Nimbus Sans L (like Helvetica). @item @uref{http://downloads.sourceforge.net/mathgl/heroscn_font.tgz,HerosCN font} -- the "compressed" version of previous one. @item @uref{http://downloads.sourceforge.net/mathgl/pagella_font.tgz,Pagella font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Palladio L (like Palatino). @item @uref{http://downloads.sourceforge.net/mathgl/schola_font.tgz,Schola font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the URW Century Schoolbook L. @item @uref{http://downloads.sourceforge.net/mathgl/termes_font.tgz,Termes font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the Nimbus Roman No9 L (like Times). @end itemize @external{} @node Other projects, , Download, Top @section Other projects Except scientific (non public) projects I also have some general interest projects: @itemize @bullet @item @uref{http://sourceforge.net/projects/pocketmk/, PocketMK} is small program for PocketPC which simulate famous Russian calculators MK-61 and slightly extend it. @item @uref{http://udav.sourceforge.net/,UDAV} is front-end for MGL scripts. It has windows interface for data viewing, changing and plotting. Also it can execute MGL scripts, setup and rotating graphics and so on. @end itemize Also I recommend to look at: @itemize @bullet @item @uref{http://englab.bugfest.net/,EngLab} is a cross-compile mathematical platform with a C like syntax intended to be used both by engineers and users with small programming knowledge. It is extremely scalable and allows users and the community to easily compile their own functions as shared objects. @item @uref{http://threedepict.sourceforge.net/,3Depict} is software for analysis of scientific datasets commonly encountered in atom probe tomography. You can manipulate, interact with and analyse point based datasets. @item @uref{http://www.sourceforge.net/projects/graphplot/,Graphplot} is function plotter based on MathGL. @item @uref{http://www.sourceforge.net/projects/graphplot/,OscillViewer} is oscilloscope monitoring program. Working with L-Card 14-140 AD-Convertor. Based on Qt and MathGL libraries. @end itemize Finally, few links to free software and libraries: @itemize @bullet @item @uref{http://www.thefreecountry.com/,thefreecountry.com} have a lot of Free Programmers', Webmasters' and Security Resources @item @uref{http://gnuwin32.sourceforge.net/,GnuWin} provides ports of tools with a GNU or similar open source license, to modern MS-Windows. @item @uref{http://loll.sourceforge.net/,LLoL} is project collecting, organising, classifying, and maintaining important URLs about Linux and the Open Source movement for all levels of Linux users. The LoLL project now has 4000+ links which are updated usually on a daily basis. @end itemize @external{} @bye mathgl-2.4.4/texinfo/appendix_en.texi0000644000175000017500000010416513513030041020015 0ustar alastairalastair@nav{} The full list of TeX-like commands recognizable by MathGL is shown below. If command is not recognized then it will be printed as is by ommitting @samp{\} symbol. For example, @samp{\#} produce ``#'', @samp{\\} produce ``\'', @samp{\qq} produce ``qq''. @c All commands are typed without @samp{\} sign. @strong{Change case}: _, ^, @@. @strong{Text style}: \big, \b, \textbf, \i, \textit, \bi, \r, \textrm, \a, \overline, \u, \underline, \w, \wire, #, \color[wkrgbcymhRGBCYMHWlenupqLENUPQ] @strong{Roots}: \sqrt, \sqrt3, \sqrt4 @strong{Fractions}: \frac, \dfrac, \stack, \overset, \underset, \stackr, \stackl @strong{Accents}: \hat, \tilde, \dot, \ddot, \dddot, \ddddot, \acute, \check, \grave, \vec, \bar, \breve @strong{Special symbols}: \# (#), \% (%), \& (&), \^ (^). \AA (Å), \AE (Æ), \APLboxquestion (⍰), \APLboxupcaret (⍓), \APLnotbackslash (⍀), \APLnotslash (⌿), \Alpha (Α), \And (&), \Angstrom (Å), \Barv (⫧), \BbbC (ℂ), \BbbGamma (ℾ), \BbbH (ℍ), \BbbN (ℕ), \BbbP (ℙ), \BbbPi (ℿ), \BbbQ (ℚ), \BbbR (ℝ), \BbbZ (ℤ), \Bbbgamma (ℽ), \Bbbpi (ℼ), \Bbbsum (⅀), \Beta (Β), \Bumpeq (≎), \Cap (⋒), \Chi (Χ), \Colon (∷), \Coloneq (⩴), \Cup (⋓), \DDownarrow (⟱), \DH (Ð), \DJ (Đ), \DashV (⫥), \DashVDash (⟚), \Dashv (⫤), \Ddownarrow (⤋), \Delta (Δ), \Digamma (Ϝ), \Doteq (≑), \Downarrow (⇓), \Epsilon (Ε), \Equiv (≣), \Eta (Η), \Eulerconst (ℇ), \Exclam (‼), \Finv (Ⅎ), \Game (⅁), \Gamma (Γ), \Gt (⪢), \Hermaphrodite (⚥), \Im (ℑ), \Iota (Ι), \Kappa (Κ), \Koppa (Ϟ), \L (Ł), \LLeftarrow (⭅), \Lambda (Λ), \Lbrbrak (⟬), \Ldsh (↲), \Leftarrow (⇐), \Leftrightarrow (⇔), \Lleftarrow (⇚), \Longleftarrow (⟸), \Longleftrightarrow (⟺), \Longmapsfrom (⟽), \Longmapsto (⟾), \Longrightarrow (⟹), \Lparengtr (⦕), \Lsh (↰), \Lt (⪡), \Lvzigzag (⧚), \Mapsfrom (⤆), \Mapsto (⤇), \Mu (Μ), \NG (Ŋ), \Nearrow (⇗), \Not (⫬), \Nu (Ν), \Nwarrow (⇖), \O (Ø), \OE (Œ), \Ohorn (Ơ), \Omega (Ω), \Omicron (Ο), \Otimes (⨷), \P (¶), \Phi (Φ), \Pi (Π), \Planckconst (ℎ), \Prec (⪻), \PropertyLine (⅊), \Psi (Ψ), \QED (∎), \Question (⁇), \RRightarrow (⭆), \Rbrbrak (⟭), \Rdsh (↳), \Re (ℜ), \Rho (Ρ), \Rightarrow (⇒), \Rparenless (⦖), \Rrightarrow (⇛), \Rsh (↱), \Rvzigzag (⧛), \S (§), \Sc (⪼), \Searrow (⇘), \Sigma (Σ), \Sqcap (⩎), \Sqcup (⩏), \Stigma (Ϛ), \Subset (⋐), \Supset (⋑), \Swarrow (⇙), \TH (Þ), \Tau (Τ), \Theta (Θ), \UUparrow (⟰), \Uhorn (Ư), \Uparrow (⇑), \Updownarrow (⇕), \Uuparrow (⤊), \VDash (⊫), \Vbar (⫫), \Vdash (⊩), \Vee (⩔), \Vert (‖), \Vvdash (⊪), \Vvert (⦀), \Wedge (⩓), \XBox (☒), \Xi (Ξ), \Yup (⅄), \Zbar (Ƶ), \Zeta (Ζ). \aa (å), \ac (∾), \accurrent (⏦), \acidfree (♾), \acwcirclearrow (⥀), \acwgapcirclearrow (⟲), \acwleftarcarrow (⤹), \acwopencirclearrow (↺), \acwoverarcarrow (⤺), \acwundercurvearrow (⤻), \adots (⋰), \ae (æ), \aleph (ℵ), \alpha (α), \amalg (⨿), \angdnr (⦟), \angle (∠), \angles (⦞), \angleubar (⦤), \approx (≈), \approxeq (≊), \approxeqq (⩰), \approxident (≋), \arceq (≘), \aries (♈), \assert (⊦), \ast (∗), \asteq (⩮), \astrosun (☉), \asymp (≍), \awint (⨑). \bNot (⫭), \backcong (≌), \backdprime (‶), \backepsilon (϶), \backprime (‵), \backsim (∽), \backsimeq (⋍), \backslash (\), \backtrprime (‷), \bagmember (⋿), \barV (⫪), \barcap (⩃), \barcup (⩂), \bardownharpoonleft (⥡), \bardownharpoonright (⥝), \barleftarrow (⇤), \barleftarrowrightarrowbar (↹), \barleftharpoondown (⥖), \barleftharpoonup (⥒), \barovernorthwestarrow (↸), \barrightarrowdiamond (⤠), \barrightharpoondown (⥟), \barrightharpoonup (⥛), \baruparrow (⤒), \barupharpoonleft (⥘), \barupharpoonright (⥔), \barvee (⊽), \barwedge (⊼), \bbrktbrk (⎶), \bdHrule (═), \bdVrule (║), \bdbVbH (╬), \bdbVbh (╫), \bdbVlH (╣), \bdbVlh (╢), \bdbVrH (╠), \bdbVrh (╟), \bdbvbH (╪), \bdbvbh (┼), \bdbvlH (╡), \bdbvlh (┤), \bdbvrH (╞), \bdbvrh (├), \bddVbH (╦), \bddVbh (╥), \bddVlH (╗), \bddVlh (╖), \bddVrH (╔), \bddVrh (╓), \bddvbH (╤), \bddvbh (┬), \bddvlH (╕), \bddvlh (┐), \bddvrH (╒), \bddvrh (┌), \bdhrule (─), \bdnesw (╱), \bdnwse (╲), \bdquadhdash (┈), \bdquadvdash (┊), \bdtriplevdash (┆), \bduVbH (╩), \bduVbh (╨), \bduVlH (╝), \bduVlh (╜), \bduVrH (╚), \bduVrh (╙), \bduvbH (╧), \bduvbh (┴), \bduvlH (╛), \bduvlh (┘), \bduvrH (╘), \bduvrh (└), \bdvrule (│), \because (∵), \benzenr (⏣), \beta (β), \beth (ℶ), \between (≬), \bigblacktriangledown (▼), \bigblacktriangleup (▲), \bigbot (⟘), \bigcap (⋂), \bigcup (⋃), \bigslopedvee (⩗), \bigslopedwedge (⩘), \bigstar (★), \bigtop (⟙), \bigtriangledown (▽), \bigtriangleup (△), \bigvee (⋁), \bigwedge (⋀), \bigwhitestar (☆), \blackcircledownarrow (⧭), \blackcircledrightdot (⚈), \blackcircledsanseight (➑), \blackcircledsansfive (➎), \blackcircledsansfour (➍), \blackcircledsansnine (➒), \blackcircledsansone (➊), \blackcircledsansseven (➐), \blackcircledsanssix (➏), \blackcircledsansten (➓), \blackcircledsansthree (➌), \blackcircledsanstwo (➋), \blackcircledtwodots (⚉), \blackcircleulquadwhite (◕), \blackdiamonddownarrow (⧪), \blackhourglass (⧗), \blackinwhitediamond (◈), \blackinwhitesquare (▣), \blacklefthalfcircle (◖), \blackpointerleft (◄), \blackpointerright (►), \blackrighthalfcircle (◗), \blacksmiley (☻), \blacktriangle (▴), \blacktriangledown (▾), \blacktriangleleft (◀), \blacktriangleright (▶), \blkhorzoval (⬬), \blkvertoval (⬮), \blockfull (█), \blockhalfshaded (▒), \blocklefthalf (▌), \blocklowhalf (▄), \blockqtrshaded (░), \blockrighthalf (▐), \blockthreeqtrshaded (▓), \blockuphalf (▀), \bot (⊥), \botsemicircle (◡), \bowtie (⋈), \box (◻), \boxast (⧆), \boxbar (◫), \boxbox (⧈), \boxbslash (⧅), \boxcircle (⧇), \boxdiag (⧄), \boxdot (⊡), \boxminus (⊟), \boxonbox (⧉), \boxplus (⊞), \boxtimes (⊠), \bsimilarleftarrow (⭁), \bsimilarrightarrow (⭇), \bsolhsub (⟈), \btimes (⨲), \bullet (∙), \bullseye (◎), \bumpeq (≏), \bumpeqq (⪮). \calB (ℬ), \calE (ℰ), \calF (ℱ), \calH (ℋ), \calM (ℳ), \calR (ℛ), \cap (∩), \capdot (⩀), \capwedge (⩄), \caretinsert (‸), \carreturn (⏎), \carriagereturn (↵), \ccwundercurvearrow (⤿), \cdot (⋅), \cdotp (·), \cdots (⋯), \cdprime (ʺ), \checkmark (✓), \chi (χ), \cirE (⧃), \cirbot (⟟), \circ (∘), \circeq (≗), \circfint (⨐), \circlebottomhalfblack (◒), \circledA (Ⓐ), \circledB (Ⓑ), \circledC (Ⓒ), \circledD (Ⓓ), \circledE (Ⓔ), \circledF (Ⓕ), \circledG (Ⓖ), \circledH (Ⓗ), \circledI (Ⓘ), \circledJ (Ⓙ), \circledK (Ⓚ), \circledL (Ⓛ), \circledM (Ⓜ), \circledN (Ⓝ), \circledO (Ⓞ), \circledP (Ⓟ), \circledQ (Ⓠ), \circledR (Ⓡ), \circledS (Ⓢ), \circledT (Ⓣ), \circledU (Ⓤ), \circledV (Ⓥ), \circledW (Ⓦ), \circledX (Ⓧ), \circledY (Ⓨ), \circledZ (Ⓩ), \circleda (ⓐ), \circledast (⊛), \circledb (ⓑ), \circledbullet (⦿), \circledc (ⓒ), \circledcirc (⊚), \circledd (ⓓ), \circleddash (⊝), \circlede (ⓔ), \circledeight (⑧), \circledequal (⊜), \circledf (ⓕ), \circledfive (⑤), \circledfour (④), \circledg (ⓖ), \circledh (ⓗ), \circledi (ⓘ), \circledj (ⓙ), \circledk (ⓚ), \circledl (ⓛ), \circledm (ⓜ), \circledn (ⓝ), \circlednine (⑨), \circledo (ⓞ), \circledone (①), \circledownarrow (⧬), \circledp (ⓟ), \circledparallel (⦷), \circledq (ⓠ), \circledr (ⓡ), \circledrightdot (⚆), \circleds (ⓢ), \circledsanseight (➇), \circledsansfive (➄), \circledsansfour (➃), \circledsansnine (➈), \circledsansone (➀), \circledsansseven (➆), \circledsanssix (➅), \circledsansten (➉), \circledsansthree (➂), \circledsanstwo (➁), \circledseven (⑦), \circledsix (⑥), \circledstar (✪), \circledt (ⓣ), \circledthree (③), \circledtwo (②), \circledtwodots (⚇), \circledu (ⓤ), \circledv (ⓥ), \circledvert (⦶), \circledw (ⓦ), \circledwhitebullet (⦾), \circledx (ⓧ), \circledy (ⓨ), \circledz (ⓩ), \circledzero (⓪), \circlehbar (⦵), \circlelefthalfblack (◐), \circlellquad (◵), \circlelrquad (◶), \circleonleftarrow (⬰), \circleonrightarrow (⇴), \circlerighthalfblack (◑), \circletophalfblack (◓), \circleulquad (◴), \circleurquad (◷), \circleurquadblack (◔), \circlevertfill (◍), \cirmid (⫯), \cirscir (⧂), \clangle (〈), \closedvarcap (⩍), \closedvarcup (⩌), \closedvarcupsmashprod (⩐), \closure (⁐), \cloverleaf (⌘), \clubsuit (♣), \colon (:), \colon (∶), \coloneq (≔), \commaminus (⨩), \complement (∁), \concavediamond (⟡), \concavediamondtickleft (⟢), \concavediamondtickright (⟣), \cong (≅), \congdot (⩭), \conictaper (⌲), \conjunction (☌), \coprod (∐), \cprime (ʹ), \crangle (〉), \csub (⫏), \csube (⫑), \csup (⫐), \csupe (⫒), \cuberoot (∛), \cup (∪), \cupdot (⊍), \cupleftarrow (⊌), \cupvee (⩅), \curlyeqprec (⋞), \curlyeqsucc (⋟), \curlyvee (⋎), \curlywedge (⋏), \curvearrowleft (↶), \curvearrowleftplus (⤽), \curvearrowright (↷), \curvearrowrightminus (⤼), \cwcirclearrow (⥁), \cwgapcirclearrow (⟳), \cwopencirclearrow (↻), \cwrightarcarrow (⤸), \cwundercurvearrow (⤾), \cylcty (⌭). \dag (†), \dagger (†), \daleth (ℸ), \danger (☡), \dashV (⫣), \dashVdash (⟛), \dashcolon (∹), \dashleftharpoondown (⥫), \dashrightharpoondown (⥭), \dashv (⊣), \dbkarow (⤏), \ddag (‡), \ddagger (‡), \ddots (⋱), \ddotseq (⩷), \delta (δ), \dh (ð), \diameter (⌀), \diamond (◇), \diamondbotblack (⬙), \diamondcdot (⟐), \diamondleftarrow (⤝), \diamondleftarrowbar (⤟), \diamondleftblack (⬖), \diamondrightblack (⬗), \diamondsuit (♢), \diamondtopblack (⬘), \dicei (⚀), \diceii (⚁), \diceiii (⚂), \diceiv (⚃), \dicev (⚄), \dicevi (⚅), \digamma (ϝ), \dingasterisk (✽), \dircurrent (⎓), \disin (⋲), \div (÷), \divideontimes (⋇), \dj (đ), \dlcrop (⌍), \doteq (≐), \dotequiv (⩧), \dotminus (∸), \dotplus (∔), \dots (…), \dotsim (⩪), \dotsminusdots (∺), \dottedcircle (◌), \dottedsquare (⬚), \dottimes (⨰), \doublebarvee (⩢), \doublebarwedge (⩞), \doubleplus (⧺), \downarrow (↓), \downarrowbar (⤓), \downarrowbarred (⤈), \downdasharrow (⇣), \downdownarrows (⇊), \downfishtail (⥿), \downharpoonleft (⇃), \downharpoonleftbar (⥙), \downharpoonright (⇂), \downharpoonrightbar (⥕), \downharpoonsleftright (⥥), \downrightcurvedarrow (⤵), \downtriangleleftblack (⧨), \downtrianglerightblack (⧩), \downuparrows (⇵), \downupharpoonsleftright (⥯), \downwhitearrow (⇩), \downzigzagarrow (↯), \dprime (″), \draftingarrow (➛), \drbkarow (⤐), \drcrop (⌌), \dsol (⧶), \dsub (⩤), \dualmap (⧟). \earth (♁), \egsdot (⪘), \eighthnote (♪), \elinters (⏧), \ell (ℓ), \elsdot (⪗), \emdash (—), \emptyset (∅), \emptysetoarr (⦳), \emptysetoarrl (⦴), \emptysetobar (⦱), \emptysetocirc (⦲), \endash (–), \enleadertwodots (‥), \envelope (✉), \eparsl (⧣), \epsilon (ϵ), \eqcirc (≖), \eqcolon (≕), \eqdef (≝), \eqdot (⩦), \eqeq (⩵), \eqeqeq (⩶), \eqgtr (⋝), \eqless (⋜), \eqqgtr (⪚), \eqqless (⪙), \eqqplus (⩱), \eqqsim (⩳), \eqqslantgtr (⪜), \eqqslantless (⪛), \eqsim (≂), \eqslantgtr (⪖), \eqslantless (⪕), \equalleftarrow (⭀), \equalparallel (⋕), \equalrightarrow (⥱), \equiv (≡), \equivDD (⩸), \equivVert (⩨), \equivVvert (⩩), \eqvparsl (⧥), \errbarblackcircle (⧳), \errbarblackdiamond (⧱), \errbarblacksquare (⧯), \errbarcircle (⧲), \errbardiamond (⧰), \errbarsquare (⧮), \eta (η), \euro (€), \exists (∃). \fallingdotseq (≒), \fbowtie (⧓), \fcmp (⨾), \fdiagovnearrow (⤯), \fdiagovrdiag (⤬), \female (♀), \figdash (‒), \fint (⨏), \fisheye (◉), \flat (♭), \fltns (⏥), \forall (∀), \forks (⫝̸), \forksnot (⫝), \forkv (⫙), \fourthroot (∜), \fourvdots (⦙), \fracfiveeighths (⅝), \fracfivesixths (⅚), \fracfourfifths (⅘), \fraconeeighth (⅛), \fraconefifth (⅕), \fraconesixth (⅙), \fraconethird (⅓), \fracseveneights (⅞), \fracslash (⁄), \fracthreeeighths (⅜), \fracthreefifths (⅗), \fractwofifths (⅖), \fractwothirds (⅔), \frakC (ℭ), \frakH (ℌ), \frakZ (ℨ), \frown (⌢), \frownie (☹), \fullouterjoin (⟗). \gamma (γ), \ge (≥), \geq (≥), \geqq (≧), \geqslant (⩾), \gescc (⪩), \gesdot (⪀), \gesdoto (⪂), \gesdotol (⪄), \gesles (⪔), \gets (←), \gg (≫), \ggg (⋙), \gggnest (⫸), \gimel (ℷ), \glE (⪒), \gla (⪥), \gleichstark (⧦), \glj (⪤), \gnapprox (⪊), \gneq (⪈), \gneqq (≩), \gnsim (⋧), \greater (>), \gsime (⪎), \gsiml (⪐), \gtcc (⪧), \gtcir (⩺), \gtlpar (⦠), \gtquest (⩼), \gtrapprox (⪆), \gtrarr (⥸), \gtrdot (⋗), \gtreqless (⋛), \gtreqqless (⪌), \gtrless (≷), \gtrsim (≳), \guillemotleft («), \guillemotright (»), \guilsinglleft (‹), \guilsinglright (›). \harrowextender (⎯), \hatapprox (⩯), \hbar (ℏ), \heartsuit (♡), \hermitmatrix (⊹), \hexagon (⎔), \hexagonblack (⬣), \hiraganano (の), \hknearrow (⤤), \hknwarrow (⤣), \hksearow (⤥), \hkswarow (⤦), \hookleftarrow (↩), \hookrightarrow (↪), \horizbar (―), \hourglass (⧖), \house (⌂), \hrectangle (▭), \hrectangleblack (▬), \hslash (ℏ), \hyphenbullet (⁃), \hzigzag (〰). \iiiint (⨌), \iiint (∭), \iinfin (⧜), \iint (∬), \imageof (⊷), \in (∈), \incare (℅), \increment (∆), \infty (∞), \int (∫), \intBar (⨎), \intbar (⨍), \intbottom (⌡), \intcap (⨙), \intclockwise (∱), \intcup (⨚), \intercal (⊺), \interleave (⫴), \intextender (⎮), \intlharhk (⨗), \intprod (⨼), \intprodr (⨽), \inttop (⌠), \intx (⨘), \inversebullet (◘), \inversewhitecircle (◙), \invnot (⌐), \invwhitelowerhalfcircle (◛), \invwhiteupperhalfcircle (◚), \iota (ι), \ipasupgamma (ˠ), \ipasupl (ˡ), \ipasuprerglotstpp (ˤ), \ipasups (ˢ), \ipasupx (ˣ), \ipaunaspirated (˭), \ipavoicing (ˬ), \isinE (⋹), \isindot (⋵), \isinobar (⋷), \isins (⋴), \isinvb (⋸), \itBbbD (ⅅ), \itBbbd (ⅆ), \itBbbe (ⅇ), \itBbbi (ⅈ), \itBbbj (ⅉ). \jupiter (♃), \kappa (κ), \kernelcontraction (∻), \koppa (ϟ). \l (ł), \lAngle (⟪), \lBrace (⦃), \lBrack (⟦), \lParen (⦅), \lambda (λ), \lambdabar (ƛ), \langle (⟨), \langledot (⦑), \laplac (⧠), \lasp (ʽ), \lat (⪫), \late (⪭), \lbag (⟅), \lblkbrbrak (⦗), \lbrace (@{), \lbracelend (⎩), \lbracemid (⎨), \lbraceuend (⎧), \lbrack ([), \lbrackextender (⎢), \lbracklend (⎣), \lbracklltick (⦏), \lbrackubar (⦋), \lbrackuend (⎡), \lbrackultick (⦍), \lbrbrak (❲), \lceil (⌈), \lcurvyangle (⧼), \ldasharrhead (⇠), \le (≤), \leadsto (↝), \leftarrow (←), \leftarrowapprox (⭊), \leftarrowbackapprox (⭂), \leftarrowbsimilar (⭋), \leftarrowless (⥷), \leftarrowonoplus (⬲), \leftarrowplus (⥆), \leftarrowshortrightarrow (⥃), \leftarrowsimilar (⥳), \leftarrowsubset (⥺), \leftarrowtail (↢), \leftarrowtriangle (⇽), \leftarrowx (⬾), \leftbkarrow (⤌), \leftcurvedarrow (⬿), \leftdasharrow (⇠), \leftdasharrowhead (⇡), \leftdbkarrow (⤎), \leftdbltail (⤛), \leftdotarrow (⬸), \leftdowncurvedarrow (⤶), \leftfishtail (⥼), \leftharpoondown (↽), \leftharpoondownbar (⥞), \leftharpoonsupdown (⥢), \leftharpoonup (↼), \leftharpoonupbar (⥚), \leftharpoonupdash (⥪), \leftleftarrows (⇇), \leftmoon (☾), \leftouterjoin (⟕), \leftrightarrow (↔), \leftrightarrowcircle (⥈), \leftrightarrows (⇆), \leftrightarrowtriangle (⇿), \leftrightharpoondowndown (⥐), \leftrightharpoondownup (⥋), \leftrightharpoons (⇋), \leftrightharpoonsdown (⥧), \leftrightharpoonsup (⥦), \leftrightharpoonupdown (⥊), \leftrightharpoonupup (⥎), \leftrightsquigarrow (↭), \leftsquigarrow (↜), \leftsquigarrow (⇜), \lefttail (⤙), \leftthreearrows (⬱), \leftthreetimes (⋋), \leftwhitearrow (⇦), \leq (≤), \leqq (≦), \leqqslant (⫹), \leqqslant (⫺), \leqslant (⩽), \lescc (⪨), \lesdot (⩿), \lesdoto (⪁), \lesdotor (⪃), \lesges (⪓), \less (<), \lessapprox (⪅), \lessdot (⋖), \lesseqgtr (⋚), \lesseqqgtr (⪋), \lessgtr (≶), \lesssim (≲), \lfbowtie (⧑), \lfloor (⌊), \lftimes (⧔), \lgE (⪑), \lgblkcircle (⬤), \lgblksquare (⬛), \lgwhtcircle (◯), \lgwhtsquare (⬜), \lhd (⊲), \linefeed (↴), \ll (≪), \llangle (⦉), \llarc (◟), \llblacktriangle (◣), \llcorner (⌞), \lll (⋘), \lllnest (⫷), \llparenthesis (⦇), \lltriangle (◺), \lmoustache (⎰), \lnapprox (⪉), \lneq (⪇), \lneqq (≨), \lnsim (⋦), \longdashv (⟞), \longdivision (⟌), \longleftarrow (⟵), \longleftrightarrow (⟷), \longleftsquigarrow (⬳), \longmapsfrom (⟻), \longmapsto (⟼), \longrightarrow (⟶), \longrightsquigarrow (⟿), \looparrowleft (↫), \looparrowright (↬), \lowint (⨜), \lozenge (◊), \lozengeminus (⟠), \lparenextender (⎜), \lparenlend (⎝), \lparenless (⦓), \lparenuend (⎛), \lq (‘), \lrarc (◞), \lrblacktriangle (◢), \lrcorner (⌟), \lrtriangle (◿), \lrtriangleeq (⧡), \lsime (⪍), \lsimg (⪏), \lsqhook (⫍), \ltcc (⪦), \ltcir (⩹), \ltimes (⋉), \ltlarr (⥶), \ltquest (⩻), \ltrivb (⧏), \lvboxline (⎸), \lvzigzag (⧘). \male (♂), \maltese (✠), \mapsdown (↧), \mapsfrom (↤), \mapsto (↦), \mapsup (↥), \mdblkdiamond (⬥), \mdblklozenge (⬧), \mdblkrcl (⚫), \mdblksquare (◼), \mdlgblkcircle (●), \mdlgblkdiamond (◆), \mdlgblklozenge (⧫), \mdlgblksquare (■), \mdlgwhtcircle (○), \mdlgwhtdiamond (◇), \mdlgwhtsquare (□), \mdsmblkcircle (⦁), \mdsmblksquare (◾), \mdsmwhtcircl (⚬), \mdsmwhtsquare (◽), \mdwhtcircl (⚪), \mdwhtdiamond (⬦), \mdwhtlozenge (⬨), \mdwhtsquare (◻), \measangledltosw (⦯), \measangledrtose (⦮), \measangleldtosw (⦫), \measanglelutonw (⦩), \measanglerdtose (⦪), \measanglerutone (⦨), \measangleultonw (⦭), \measangleurtone (⦬), \measeq (≞), \measuredangle (∡), \measuredangleleft (⦛), \measuredrightangle (⊾), \medblackstar (⭑), \medmathspace ( ), \medwhitestar (⭐), \mercury (☿), \mho (℧), \mid (∣), \midbarvee (⩝), \midbarwedge (⩜), \midcir (⫰), \minus (−), \minusdot (⨪), \minusfdots (⨫), \minusrdots (⨬), \mlcp (⫛), \models (⊧), \mp (∓), \mu (μ), \multimap (⊸), \multimapinv (⟜). \nHdownarrow (⇟), \nHuparrow (⇞), \nLeftarrow (⇍), \nLeftrightarrow (⇎), \nRightarrow (⇏), \nVDash (⊯), \nVdash (⊮), \nVleftarrow (⇺), \nVleftarrowtail (⬺), \nVleftrightarrow (⇼), \nVrightarrow (⇻), \nVrightarrowtail (⤕), \nVtwoheadleftarrow (⬵), \nVtwoheadleftarrowtail (⬽), \nVtwoheadrightarrow (⤁), \nVtwoheadrightarrowtail (⤘), \nabla (∇), \napprox (≉), \nasymp (≭), \natural (♮), \ncong (≇), \ne (≠), \nearrow (↗), \neg (¬), \neovnwarrow (⤱), \neovsearrow (⤮), \neptune (♆), \neq (≠), \nequiv (≢), \neswarrow (⤢), \neuter (⚲), \nexists (∄), \ng (ŋ), \ngeq (≱), \ngtr (≯), \ngtrless (≹), \ngtrsim (≵), \nhVvert (⫵), \nhpar (⫲), \ni (∋), \niobar (⋾), \nis (⋼), \nisd (⋺), \nleftarrow (↚), \nleftrightarrow (↮), \nleq (≰), \nless (≮), \nlessgtr (≸), \nlesssim (≴), \nmid (∤), \nni (∌), \nobreakhyphen (‑), \notin (∉), \nparallel (∦), \npolint (⨔), \nprec (⊀), \npreccurlyeq (⋠), \nrightarrow (↛), \nsim (≁), \nsime (≄), \nsqsubseteq (⋢), \nsqsupseteq (⋣), \nsubset (⊄), \nsubseteq (⊈), \nsucc (⊁), \nsucccurlyeq (⋡), \nsupset (⊅), \nsupseteq (⊉), \ntriangleleft (⋪), \ntrianglelefteq (⋬), \ntriangleright (⋫), \ntrianglerighteq (⋭), \nu (ν), \nvDash (⊭), \nvLeftarrow (⤂), \nvLeftrightarrow (⤄), \nvRightarrow (⤃), \nvdash (⊬), \nvinfty (⧞), \nvleftarrow (⇷), \nvleftarrowtail (⬹), \nvleftrightarrow (⇹), \nvrightarrow (⇸), \nvrightarrowtail (⤔), \nvtwoheadleftarrow (⬴), \nvtwoheadleftarrowtail (⬼), \nvtwoheadrightarrow (⤀), \nvtwoheadrightarrowtail (⤗), \nwarrow (↖), \nwovnearrow (⤲), \nwsearrow (⤡). \o (ø), \obar (⌽), \obot (⦺), \obrbrak (⏠), \obslash (⦸), \odiv (⨸), \odot (⊙), \odotslashdot (⦼), \oe (œ), \ogreaterthan (⧁), \ohorn (ơ), \oiiint (∰), \oiint (∯), \oint (∮), \ointctrclockwise (∳), \olcross (⦻), \oldKoppa (Ϙ), \oldkoppa (ϙ), \olessthan (⧀), \omega (ω), \omicron (ο), \ominus (⊖), \operp (⦹), \oplus (⊕), \opluslhrim (⨭), \oplusrhrim (⨮), \origof (⊶), \oslash (⊘), \otimes (⊗), \otimeshat (⨶), \otimeslhrim (⨴), \otimesrhrim (⨵), \overbrace (⏞), \overbracket (⎴), \overline (‾), \overparen (⏜), \owns (∋). \parallel (∥), \parallelogram (▱), \parallelogramblack (▰), \parsim (⫳), \partial (∂), \partialmeetcontraction (⪣), \pentagon (⬠), \pentagonblack (⬟), \perp (⟂), \perps (⫡), \phi (ϕ), \phone (☎), \pi (π), \pitchfork (⋔), \plusdot (⨥), \pluseqq (⩲), \plushat (⨣), \plussim (⨦), \plussubtwo (⨧), \plustrif (⨨), \pluto (♇), \pm (±), \pointnt (⨕), \postalmark (〒), \prec (≺), \precapprox (⪷), \preccurlyeq (≼), \preceq (⪯), \preceqq (⪳), \precnapprox (⪹), \precneq (⪱), \precneqq (⪵), \precnsim (⋨), \precsim (≾), \prime (′), \prod (∏), \profalar (⌮), \profline (⌒), \profsurf (⌓), \propto (∝), \prurel (⊰), \psi (ψ), \pullback (⟓), \pushout (⟔). \qprime (⁗), \quarternote (♩), \questeq (≟), \quotdblbase („), \quotdblright (‟), \quotsinglbase (‚), \quotsinglright (‛). \rAngle (⟫), \rBrace (⦄), \rBrack (⟧), \rParen (⦆), \rangle (⟩), \rangledot (⦒), \rangledownzigzagarrow (⍼), \rasp (ʼ), \rbag (⟆), \rblkbrbrak (⦘), \rbrace (@}), \rbracelend (⎭), \rbracemid (⎬), \rbraceuend (⎫), \rbrack (]), \rbrackextender (⎥), \rbracklend (⎦), \rbracklrtick (⦎), \rbrackubar (⦌), \rbrackuend (⎤), \rbrackurtick (⦐), \rbrbrak (❳), \rceil (⌉), \rcurvyangle (⧽), \rdiagovfdiag (⤫), \rdiagovsearrow (⤰), \recorder (⌕), \revangle (⦣), \revangleubar (⦥), \revemptyset (⦰), \revnmid (⫮), \rfbowtie (⧒), \rfloor (⌋), \rftimes (⧕), \rhd (⊳), \rho (ρ), \righarrowbsimilar (⭌), \rightangle (∟), \rightanglemdot (⦝), \rightanglesqr (⦜), \rightarrow (→), \rightarrowapprox (⥵), \rightarrowbackapprox (⭈), \rightarrowbar (⇥), \rightarrowdiamond (⤞), \rightarrowgtr (⭃), \rightarrowonoplus (⟴), \rightarrowplus (⥅), \rightarrowshortleftarrow (⥂), \rightarrowsimilar (⥴), \rightarrowsupset (⭄), \rightarrowtail (↣), \rightarrowtriangle (⇾), \rightarrowx (⥇), \rightbkarrow (⤍), \rightcurvedarrow (⤳), \rightdasharrow (⇢), \rightdbltail (⤜), \rightdotarrow (⤑), \rightdowncurvedarrow (⤷), \rightfishtail (⥽), \rightharpoondown (⇁), \rightharpoondownbar (⥗), \rightharpoonsupdown (⥤), \rightharpoonup (⇀), \rightharpoonupbar (⥓), \rightharpoonupdash (⥬), \rightimply (⥰), \rightleftarrows (⇄), \rightleftharpoons (⇌), \rightleftharpoonsdown (⥩), \rightleftharpoonsup (⥨), \rightmoon (☽), \rightouterjoin (⟖), \rightpentagon (⭔), \rightpentagonblack (⭓), \rightrightarrows (⇉), \rightsquigarrow (↝), \rightsquigarrow (⇝), \righttail (⤚), \rightthreearrows (⇶), \rightthreetimes (⋌), \rightwhitearrow (⇨), \ringplus (⨢), \risingdotseq (≓), \rmoustache (⎱), \rparenextender (⎟), \rparengtr (⦔), \rparenlend (⎠), \rparenuend (⎞), \rppolint (⨒), \rq (’), \rrangle (⦊), \rrparenthesis (⦈), \rsolbar (⧷), \rsqhook (⫎), \rsub (⩥), \rtimes (⋊), \rtriltri (⧎), \ruledelayed (⧴), \rvboxline (⎹), \rvzigzag (⧙). \sampi (ϡ), \sansLmirrored (⅃), \sansLturned (⅂), \saturn (♄), \scissors (✂), \scpolint (⨓), \scrB (ℬ), \scrE (ℰ), \scrF (ℱ), \scrH (ℋ), \scrI (ℐ), \scrL (ℒ), \scrM (ℳ), \scrR (ℛ), \scre (ℯ), \scrg (ℊ), \scro (ℴ), \scurel (⊱), \searrow (↘), \seovnearrow (⤭), \setminus (∖), \setminus (⧵), \sharp (♯), \shortdowntack (⫟), \shortleftarrow (←), \shortlefttack (⫞), \shortrightarrow (→), \shortrightarrowleftarrow (⥄), \shortuptack (⫠), \shuffle (⧢), \sigma (σ), \silon (υ), \silon (ϒ), \sim (∼), \simeq (≃), \simgE (⪠), \simgtr (⪞), \similarleftarrow (⭉), \similarrightarrow (⥲), \simlE (⪟), \simless (⪝), \simminussim (⩬), \simneqq (≆), \simplus (⨤), \simrdots (⩫), \sinewave (∿), \slash (∕), \smallblacktriangleleft (◂), \smallblacktriangleright (▸), \smalldiamond (⋄), \smallin (∊), \smallint (∫), \smallni (∍), \smallsetminus (∖), \smalltriangleleft (◃), \smalltriangleright (▹), \smashtimes (⨳), \smblkdiamond (⬩), \smblklozenge (⬪), \smblksquare (▪), \smeparsl (⧤), \smile (⌣), \smiley (☺), \smt (⪪), \smte (⪬), \smwhitestar (⭒), \smwhtcircle (◦), \smwhtlozenge (⬫), \smwhtsquare (▫), \spadesuit (♠), \sphericalangle (∢), \sphericalangleup (⦡), \sqcap (⊓), \sqcup (⊔), \sqint (⨖), \sqlozenge (⌑), \sqrt (√), \sqrt3 (∛), \sqrt4 (∜), \sqrtbottom (⎷), \sqsubset (⊏), \sqsubseteq (⊑), \sqsubsetneq (⋤), \sqsupset (⊐), \sqsupseteq (⊒), \sqsupsetneq (⋥), \squarecrossfill (▩), \squaregrayfill (▩), \squarehfill (▤), \squarehvfill (▦), \squareleftblack (◧), \squareleftblack (◨), \squarellblack (⬕), \squarellquad (◱), \squarelrblack (◪), \squarelrquad (◲), \squareneswfill (▨), \squarenwsefill (▧), \squareulblack (◩), \squareulquad (◰), \squareurblack (⬔), \squareurquad (◳), \squarevfill (▥), \squoval (▢), \ss (ß), \star (⋆), \stareq (≛), \sterling (£), \stigma (ϛ), \strns (⏤), \subedot (⫃), \submult (⫁), \subrarr (⥹), \subset (⊂), \subsetapprox (⫉), \subsetcirc (⟃), \subsetdot (⪽), \subseteq (⊆), \subseteqq (⫅), \subsetneq (⊊), \subsetneqq (⫋), \subsetplus (⪿), \subsim (⫇), \subsub (⫕), \subsup (⫓), \succ (≻), \succapprox (⪸), \succcurlyeq (≽), \succeq (⪰), \succeqq (⪴), \succnapprox (⪺), \succneq (⪲), \succneqq (⪶), \succnsim (⋩), \succsim (≿), \sum (∑), \sumbottom (⎳), \sumint (⨋), \sumtop (⎲), \sun (☼), \supdsub (⫘), \supedot (⫄), \suphsol (⟉), \suphsub (⫗), \suplarr (⥻), \supmult (⫂), \supn (ⁿ), \supset (⊃), \supsetapprox (⫊), \supsetcirc (⟄), \supsetdot (⪾), \supseteq (⊇), \supseteqq (⫆), \supsetneq (⊋), \supsetneqq (⫌), \supsetplus (⫀), \supsim (⫈), \supsub (⫔), \supsup (⫖), \surd (√), \swarrow (↙). \talloblong (⫾), \target (⌖), \tau (τ), \taurus (♉), \testhookx (ᶍ), \textAsterisks (⁑), \textacute (ˊ), \textadvanced (˖), \textain (ʿ), \textasciiacute (´), \textasciicircum (^), \textasciidieresis (¨), \textasciigrave (`), \textasciimacron (¯), \textasciitilde (~), \textasterisklow (⁎), \textbackdprime (‶), \textbackprime (‵), \textbacktrprime (‷), \textbardotlessj (ɟ), \textbardotlessjvar (ʄ), \textbarglotstop (ʡ), \textbari (ɨ), \textbarl (ƚ), \textbaro (ɵ), \textbarrevglotstop (ʢ), \textbaru (ʉ), \textbeltl (ɬ), \textbenttailyogh (ƺ), \textbreve (˘), \textbrokenbar (¦), \textbullet (•), \textbullseye (ʘ), \textcent (¢), \textcircledP (℗), \textcloseepsilon (ʚ), \textcloseomega (ɷ), \textcloserevepsilon (ɞ), \textcopyright (©), \textcrb (ƀ), \textcrh (ħ), \textcrinvglotstop (ƾ), \textcrlambda (ƛ), \textcrtwo (ƻ), \textctc (ɕ), \textctd (ȡ), \textctesh (ʆ), \textctj (ʝ), \textctl (ȴ), \textctn (ȵ), \textctt (ȶ), \textctyogh (ʓ), \textctz (ʑ), \textcurrency (¤), \textdctzlig (ʥ), \textdegree (°), \textdiscount (⁒), \textdollar ($), \textdotaccent (˙), \textdotlessj (ȷ), \textdoubleacute (˝), \textdoublebarpipe (ǂ), \textdoublepipe (ǁ), \textdprime (″), \textdptr (˅), \textdyoghlig (ʤ), \textdzlig (ʣ), \textepsilon (ɛ), \textesh (ʃ), \textestimated (℮), \textexclam (ǃ), \textexclamdown (¡), \textfishhookr (ɾ), \textflorin (ƒ), \textfranc (₣), \textgamma (ɣ), \textglotstop (ʔ), \textgrave (ˋ), \texthalflength (ˑ), \texthamza (ʾ), \texthen (ꜧ), \textheng (ꜧ), \texthooks (ᶊ), \texthookz (ᶎ), \texthtb (ɓ), \texthtc (ƈ), \texthtd (ɗ), \texthtg (ɠ), \texthth (ɦ), \texththeng (ɧ), \texthtk (ƙ), \texthtp (ƥ), \texthtq (ʠ), \texthtscg (ʛ), \texthtt (ƭ), \texthvlig (ƕ), \texthyphen (‐), \textinvglotstop (ʖ), \textinvscr (ʁ), \textiota (ɩ), \textlengthmark (ː), \textlhalfring (˓), \textlhookd (ᶁ), \textlhookk (ᶄ), \textlhookl (ᶅ), \textlhookt (ƫ), \textlhti (ɿ), \textlira (₤), \textlonglegr (ɼ), \textlongy (ʮ), \textlongy (ʯ), \textlooptoprevesh (ƪ), \textlowacute (ˏ), \textlowered (˕), \textlowgrave (ˎ), \textlowmacron (ˍ), \textlptr (˂), \textltailm (ɱ), \textltailn (ɲ), \textltilde (ɫ), \textlyoghlig (ɮ), \textmacron (ˉ), \textmu (µ), \textnumero (№), \textogonek (˛), \textohm (Ω), \textonehalf (½), \textonequarter (¼), \textonesuperior (¹), \textopeno (ɔ), \textordfeminine (ª), \textordmasculine (º), \textovercross (˟), \textoz (℥), \textpertenthousand (‱), \textperthousand (‰), \textpesetas (₧), \textphi (ɸ), \textpipe (ǀ), \textprime (′), \textprimstress (ˈ), \textqprime (⁗), \textquestiondown (¿), \textquotedbl ("), \textquotedblleft (“), \textquotedblright (”), \textraised (˔), \textraiseglotstop (ˀ), \textraiserevglotstop (ˁ), \textramshorns (ɤ), \textrecipe (℞), \textreferencemark (※), \textregistered (®), \textretracted (˗), \textreve (ɘ), \textrevepsilon (ɜ), \textrevglotstop (ʕ), \textrhalfring (˒), \textrhookrevepsilon (ɝ), \textrhookschwa (ɚ), \textrhoticity (˞), \textringaccent (˚), \textrptr (˃), \textrtaild (ɖ), \textrtaill (ɭ), \textrtailn (ɳ), \textrtailr (ɽ), \textrtails (ʂ), \textrtailt (ʈ), \textrtailz (ʐ), \textsca (ᴀ), \textscb (ʙ), \textsce (ᴇ), \textscg (ɢ), \textsch (ʜ), \textschwa (ə), \textsci (ɪ), \textscl (ʟ), \textscn (ɴ), \textscoelig (ɶ), \textscr (ʀ), \textscripta (ɑ), \textscriptg (ɡ), \textscriptv (ʋ), \textscu (ᴜ), \textscy (ʏ), \textsecstress (ˌ), \textsemicolonreversed (⁏), \textsilon (Υ), \textsmalltilde (˜), \textstretchcvar (ʗ), \textsubw (w), \textsuph (ʰ), \textsuphth (ʱ), \textsupinvscr (ʶ), \textsupj (ʲ), \textsupr (ʳ), \textsupturnr (ʴ), \textsupturnrrtail (ʵ), \textsupw (ʷ), \textsupy (ʸ), \texttctctlig (ʧ), \texttctctlig (ʨ), \textthreequarters (¾), \textthreesuperior (³), \texttrademark (™), \texttrprime (‴), \texttslig (ʦ), \textturna (ɐ), \textturncomma (ʻ), \textturnh (ɥ), \textturnk (ʞ), \textturnlonglegr (ɺ), \textturnm (ɯ), \textturnmrleg (ɰ), \textturnr (ɹ), \textturnrrtail (ɻ), \textturnscripta (ɒ), \textturnt (ʇ), \textturnv (ʌ), \textturnw (ʍ), \textturny (ʎ), \texttwosuperior (²), \textupsilon (ʊ), \textuptr (˄), \textvibyi (ʅ), \textvisiblespace (␣), \textyogh (ʒ), \th (þ), \therefore (∴), \thermod (⧧), \theta (θ), \thickapprox (≈), \thicksim (∼), \threedangle (⟀), \threedotcolon (⫶), \tieconcat (⁀), \tieinfty (⧝), \times (×), \timesbar (⨱), \tminus (⧿), \to (→), \toea (⤨), \tona (⤧), \tonebarextrahigh (˥), \tonebarextralow (˩), \tonebarhigh (˦), \tonebarlow (˨), \tonebarmid (˧), \top (⊤), \topbot (⌶), \topcir (⫱), \topfork (⫚), \topsemicircle (◠), \tosa (⤩), \towa (⤪), \tplus (⧾), \trapezium (⏢), \trianglecdot (◬), \triangledown (▿), \triangleexclam (⚠), \triangleleft (◁), \triangleleftblack (◭), \trianglelefteq (⊴), \triangleminus (⨺), \triangleodot (⧊), \triangleplus (⨹), \triangleq (≜), \triangleright (▷), \trianglerightblack (◮), \trianglerighteq (⊵), \triangles (⧌), \triangleserifs (⧍), \triangletimes (⨻), \triangleubar (⧋), \tripleplus (⧻), \trprime (‴), \turnangle (⦢), \turnediota (℩), \turnednot (⌙), \twocaps (⩋), \twocups (⩊), \twoheaddownarrow (↡), \twoheadleftarrow (↞), \twoheadleftarrowtail (⬻), \twoheadleftdbkarrow (⬷), \twoheadmapsfrom (⬶), \twoheadmapsto (⤅), \twoheadrightarrow (↠), \twoheadrightarrowtail (⤖), \twoheaduparrow (↟), \twoheaduparrowcircle (⥉), \twolowline (‗), \twonotes (♫), \typecolon (⦂). \ubrbrak (⏡), \uhorn (ư), \ularc (◜), \ulblacktriangle (◤), \ulcorner (⌜), \ulcrop (⌏), \ultriangle (◸), \uminus (⩁), \underbrace (⏟), \underbracket (⎵), \underparen (⏝), \unlhd (⊴), \unrhd (⊵), \upand (⅋), \uparrow (↑), \uparrowbarred (⤉), \uparrowoncircle (⦽), \updasharrow (⇢), \updownarrow (↕), \updownarrowbar (↨), \updownarrows (⇅), \updownharpoonleftleft (⥑), \updownharpoonleftright (⥍), \updownharpoonrightleft (⥌), \updownharpoonrightright (⥏), \updownharpoonsleftright (⥮), \upfishtail (⥾), \upharpoonleft (↿), \upharpoonleftbar (⥠), \upharpoonright (↾), \upharpoonrightbar (⥜), \upharpoonsleftright (⥣), \upin (⟒), \upint (⨛), \uplus (⊎), \uprightcurvearrow (⤴), \upuparrows (⇈), \upwhitearrow (⇧), \urarc (◝), \urblacktriangle (◥), \urcorner (⌝), \urcrop (⌎), \urtriangle (◹). \v (ˇ), \vBar (⫨), \vBarv (⫩), \vDash (⊨), \vDdash (⫢), \varTheta (ϴ), \varVdash (⫦), \varbarwedge (⌅), \varbeta (ϐ), \varclubsuit (♧), \vardiamondsuit (♦), \vardoublebarwedge (⌆), \varepsilon (ε), \varheartsuit (♥), \varhexagon (⬡), \varhexagonblack (⬢), \varhexagonlrbonds (⌬), \varin (∈), \varisinobar (⋶), \varisins (⋳), \varkappa (ϰ), \varlrtriangle (⊿), \varni (∋), \varniobar (⋽), \varnis (⋻), \varnothing (∅), \varointclockwise (∲), \varphi (φ), \varpi (ϖ), \varpropto (∝), \varrho (ϱ), \varrowextender (⏐), \varsigma (ς), \varspadesuit (♤), \varstar (✶), \vartheta (ϑ), \vartriangle (▵), \vartriangleleft (⊲), \vartriangleright (⊳), \varveebar (⩡), \vbraceextender (⎪), \vbrtri (⧐), \vdash (⊢), \vdots (⋮), \vectimes (⨯), \vee (∨), \veebar (⊻), \veedot (⟇), \veedoublebar (⩣), \veeeq (≚), \veemidvert (⩛), \veeodot (⩒), \veeonvee (⩖), \veeonwedge (⩙), \vert (|), \viewdata (⌗), \vlongdash (⟝), \vrectangle (▯), \vrectangleblack (▮), \vysmlblksquare (⬝), \vysmlwhtsquare (⬞), \vzigzag (⦚). \watchicon (⌚), \wedge (∧), \wedgebar (⩟), \wedgedot (⟑), \wedgedoublebar (⩠), \wedgemidvert (⩚), \wedgeodot (⩑), \wedgeonwedge (⩕), \wedgeq (≙), \whitearrowupfrombar (⇪), \whiteinwhitetriangle (⟁), \whitepointerleft (◅), \whitepointerright (▻), \whitesquaretickleft (⟤), \whitesquaretickright (⟥), \whthorzoval (⬭), \whtvertoval (⬯), \wideangledown (⦦), \wideangleup (⦧), \wp (℘), \wr (≀). \xbsol (⧹), \xi (ξ), \xsol (⧸), \yen (¥), \zeta (ζ), \zpipe (⨠), IF ANYBODY WILL CHECK WHETHER ALL NAMES CORRESPOND TO RIGHT TEX SYMBOLS I SHALL APPRECIATE IT GREATLY. mathgl-2.4.4/texinfo/CMakeLists.txt0000644000175000017500000002577613513030041017402 0ustar alastairalastairconfigure_file(${MathGL2_SOURCE_DIR}/texinfo/version.texi.in ${MathGL2_BINARY_DIR}/texinfo/version.texi) #set(MGL_EXTRA light pendelta) set(MGL_EXTRA ) set(MGL_PNG_ONLY quality0 quality1 quality2 quality4 quality5 quality6 quality8 pendelta fexport) set(MGL_PNG 3wave alpha apde area aspect axial axis barh bars belt bifurcation box boxplot boxs candle chart cloud colorbar combined cones cont cont_xyz cont3 contd contf contf_xyz contf3 conts contv correl curvcoor cut dat_diff dat_extra data1 data2 dens dens_xyz dens3 detect dew diffract dilate dots earth error error2 export fall fit flame2d flow flow3 fog fonts grad hist ifs2d ifs3d indirect inplot iris label lamerey legend light loglog map mark mask mesh minmax mirror molecule ode ohlc param1 param2 param3 paramv parser pde pipe plot pmap primitives projection projection5 pulse qo2d radar refill region scanfile schemes section several_light solve stem step stereo stfa style surf surf3 surf3a surf3c surf3ca surfa surfc surfca table tape tens ternary text text2 textmark ticks tile tiles torus traj triangulation triplot tube type0 type1 type2 vect vect3 venn ) set(MGL_PNG_N ) set(MGL_PNG_S ) set(MGL_PNG_J ) set(MGL_PNG_D ) set(MGL_OUT ${CMAKE_BINARY_DIR}/texinfo) set(MGL_TEX ${CMAKE_SOURCE_DIR}/texinfo) file(MAKE_DIRECTORY ${MGL_OUT}/udav) file(MAKE_DIRECTORY ${MGL_OUT}/png) file(MAKE_DIRECTORY ${MGL_OUT}/small) file(MAKE_DIRECTORY ${MGL_OUT}/json) file(MAKE_DIRECTORY ${MGL_OUT}/pdf) file(COPY ${MGL_TEX}/qt.png ${MGL_TEX}/fltk.png ${MGL_TEX}/classes.png ${MGL_TEX}/emblem_sm.png ${MGL_TEX}/datadvance.png DESTINATION ${MGL_OUT}) file(COPY ${MGL_TEX}/index.html ${MGL_TEX}/json.html ${MGL_TEX}/mathgl.js DESTINATION ${MGL_OUT}) file(COPY ${CMAKE_SOURCE_DIR}/examples/iris.dat DESTINATION ${MGL_OUT}/png) file(COPY ${CMAKE_SOURCE_DIR}/examples/iris.dat DESTINATION ${MGL_OUT}/small) file(COPY ${CMAKE_SOURCE_DIR}/examples/iris.dat DESTINATION ${MGL_OUT}/json) file(COPY ${CMAKE_SOURCE_DIR}/examples/iris.dat DESTINATION ${MGL_OUT}/pdf) file(COPY ${CMAKE_SOURCE_DIR}/examples/Equirectangular-projection.jpg DESTINATION ${MGL_OUT}/png) file(COPY ${CMAKE_SOURCE_DIR}/examples/Equirectangular-projection.jpg DESTINATION ${MGL_OUT}/small) file(COPY ${CMAKE_SOURCE_DIR}/examples/Equirectangular-projection.jpg DESTINATION ${MGL_OUT}/json) file(COPY ${CMAKE_SOURCE_DIR}/examples/Equirectangular-projection.jpg DESTINATION ${MGL_OUT}/pdf) file(COPY ${CMAKE_SOURCE_DIR}/examples/samples.cpp DESTINATION ${MGL_OUT}) file(COPY ${CMAKE_SOURCE_DIR}/examples/wnd_samples.cpp DESTINATION ${MGL_OUT}) set(UDAV_IMG udav_arg.png udav_calc.png udav_cmd.png udav_data.png udav_mask.png udav_gen_set.png udav_help.png udav_light.png udav_main.png udav_opt.png udav_inplot.png udav_pen.png udav_prop.png udav_sch.png udav_txt.png udav_var.png) foreach(SAMPLE ${UDAV_IMG}) file(COPY ${MGL_TEX}/udav/${SAMPLE} DESTINATION ${MGL_OUT}/udav/) endforeach(SAMPLE) add_custom_command(OUTPUT ${MGL_OUT}/samples.texi COMMAND mgl_example -texi DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT} ) #add_custom_command(OUTPUT ${MGL_OUT}/time.texi # COMMAND mgl_example -time # DEPENDS mgl_example # WORKING_DIRECTORY ${MGL_OUT} ) #add_custom_command(OUTPUT ${MGL_OUT}/time_big.texi # COMMAND mgl_example -time -big # DEPENDS mgl_example # WORKING_DIRECTORY ${MGL_OUT} ) foreach(SAMPLE ${MGL_PNG_ONLY}) set(MGL_PNG_N ${MGL_PNG_N} ${MGL_OUT}/png/${SAMPLE}.png) add_custom_command(OUTPUT ${MGL_OUT}/png/${SAMPLE}.png COMMAND mgl_example -kind=${SAMPLE} DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/png ) set(MGL_PNG_S ${MGL_PNG_S} ${MGL_OUT}/small/${SAMPLE}-sm.png) add_custom_command(OUTPUT ${MGL_OUT}/small/${SAMPLE}-sm.png COMMAND mgl_example -kind=${SAMPLE} -mini DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/small ) endforeach(SAMPLE) foreach(SAMPLE ${MGL_PNG}) set(MGL_PNG_N ${MGL_PNG_N} ${MGL_OUT}/png/${SAMPLE}.png) add_custom_command(OUTPUT ${MGL_OUT}/png/${SAMPLE}.png COMMAND mgl_example -kind=${SAMPLE} DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/png ) set(MGL_PNG_S ${MGL_PNG_S} ${MGL_OUT}/small/${SAMPLE}-sm.png) add_custom_command(OUTPUT ${MGL_OUT}/small/${SAMPLE}-sm.png COMMAND mgl_example -kind=${SAMPLE} -mini DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/small ) if(MGL_HAVE_DOC_JSON) set(MGL_PNG_J ${MGL_PNG_J} ${MGL_OUT}/json/${SAMPLE}.json) add_custom_command(OUTPUT ${MGL_OUT}/json/${SAMPLE}.json COMMAND mgl_example -json -kind=${SAMPLE} DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/json ) endif(MGL_HAVE_DOC_JSON) if(MGL_HAVE_DOC_PRC) set(MGL_PNG_D ${MGL_PNG_D} ${MGL_OUT}/pdf/${SAMPLE}.pdf) add_custom_command(OUTPUT ${MGL_OUT}/pdf/${SAMPLE}.pdf COMMAND mgl_example -pdf -kind=${SAMPLE} DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/pdf ) endif(MGL_HAVE_DOC_PRC) endforeach(SAMPLE) foreach(SAMPLE ${MGL_EXTRA}) set(MGL_PNG_N ${MGL_PNG_N} ${MGL_OUT}/png/${SAMPLE}.png) add_custom_command(OUTPUT ${MGL_OUT}/png/${SAMPLE}.png COMMAND mgl_example -kind=${SAMPLE} DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/png ) set(MGL_PNG_S ${MGL_PNG_S} ${MGL_OUT}/small/${SAMPLE}-sm.png) add_custom_command(OUTPUT ${MGL_OUT}/small/${SAMPLE}-sm.png COMMAND mgl_example -kind=${SAMPLE} -mini DEPENDS mgl_example WORKING_DIRECTORY ${MGL_OUT}/small ) endforeach(SAMPLE) # NOTE: direct generation of time*.texi is too slow :( set(list_texi_files_en overview_en.texi example_en.texi ex_mgl_en.texi parse_en.texi formats_en.texi udav_en.texi symbols_en.texi core_en.texi concept_en.texi widget_en.texi data_en.texi other_en.texi appendix_en.texi fdl.texi ${MathGL2_BINARY_DIR}/texinfo/version.texi time.texi time_big.texi ${MGL_OUT}/samples.texi ) set(list_texi_files_ru overview_ru.texi example_ru.texi ex_mgl_ru.texi parse_ru.texi formats_ru.texi udav_ru.texi symbols_ru.texi core_ru.texi concept_ru.texi widget_ru.texi data_ru.texi other_ru.texi appendix_ru.texi fdl.texi ${MathGL2_BINARY_DIR}/texinfo/version.texi time.texi time_big.texi ${MGL_OUT}/samples.texi ) add_custom_command(OUTPUT ${MGL_OUT}/mathgl_en.info COMMAND ${findmi} ${MGL_TEX}/mathgl_en.texi DEPENDS ${list_texi_files_en} mathgl_en.texi #${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mathgl_ru.info COMMAND ${findmi} ${MGL_TEX}/mathgl_ru.texi DEPENDS ${list_texi_files_ru} mathgl_ru.texi #${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mathgl_en.html COMMAND ${findth} ${th_opt} -I ${MGL_OUT} --no-split ${MGL_TEX}/mathgl_en.texi DEPENDS ${list_texi_files_en} mathgl_en.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mgl_en.html COMMAND ${findth} ${th_opt} --set-customization-variable 'BODYTEXT ' -I ${MGL_OUT} --no-split ${MGL_TEX}/mgl_en.texi # following line bypass FLTK bugs COMMAND sed "'s/–/-/g'" -i ${MGL_OUT}/mgl_en.html COMMAND sed "'s/‘/`/g'" -i ${MGL_OUT}/mgl_en.html COMMAND sed "'s/’/`/g'" -i ${MGL_OUT}/mgl_en.html DEPENDS ${list_texi_files_en} mgl_en.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mathgl_ru.html COMMAND ${findth} ${th_opt} -I=${MGL_OUT} --no-split ${MGL_TEX}/mathgl_ru.texi DEPENDS ${list_texi_files_ru} mathgl_ru.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mgl_ru.html COMMAND ${findth} ${th_opt} --set-customization-variable 'BODYTEXT ' -I=${MGL_OUT} --no-split ${MGL_TEX}/mgl_ru.texi # following line bypass FLTK bugs COMMAND sed "'s/–/-/g'" -i ${MGL_OUT}/mgl_ru.html COMMAND sed "'s/‘/`/g'" -i ${MGL_OUT}/mgl_ru.html COMMAND sed "'s/’/`/g'" -i ${MGL_OUT}/mgl_ru.html DEPENDS ${list_texi_files_ru} mgl_ru.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${site_en} COMMAND ${findth} ${th_opt} -I=${MGL_OUT}/png --split=node -o doc_en ${MGL_TEX}/doc_en.texi DEPENDS ${list_texi_files_en} doc_en.texi ${MGL_PNG_N} web_en.texi ${MGL_PNG_S} ${MGL_PNG_J} ${MGL_PNG_D} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${site_ru} COMMAND ${findth} ${th_opt} -I=${MGL_OUT}/png --split=node -o doc_ru ${MGL_TEX}/doc_ru.texi DEPENDS ${list_texi_files_ru} doc_ru.texi ${MGL_PNG_N} web_ru.texi ${MGL_PNG_S} ${MGL_PNG_J} ${MGL_PNG_D} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mathgl_en.pdf COMMAND ${findtp} ${MGL_TEX}/mathgl_en.texi COMMAND ${findtp} ${MGL_TEX}/mathgl_en.texi COMMAND ${findtp} ${MGL_TEX}/mathgl_en.texi DEPENDS ${list_texi_files_en} mathgl_en.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mgl_en.pdf COMMAND ${findtp} ${MGL_TEX}/mgl_en.texi COMMAND ${findtp} ${MGL_TEX}/mgl_en.texi COMMAND ${findtp} ${MGL_TEX}/mgl_en.texi DEPENDS ${list_texi_files_en} mgl_en.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mathgl_ru.pdf COMMAND ${findtp} ${MGL_TEX}/mathgl_ru.texi COMMAND ${findtp} ${MGL_TEX}/mathgl_ru.texi COMMAND ${findtp} ${MGL_TEX}/mathgl_ru.texi DEPENDS ${list_texi_files_ru} mathgl_ru.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) add_custom_command(OUTPUT ${MGL_OUT}/mgl_ru.pdf COMMAND ${findtp} ${MGL_TEX}/mgl_ru.texi COMMAND ${findtp} ${MGL_TEX}/mgl_ru.texi COMMAND ${findtp} ${MGL_TEX}/mgl_ru.texi DEPENDS ${list_texi_files_en} mgl_ru.texi ${MGL_PNG_N} WORKING_DIRECTORY ${MGL_OUT} ) if(MGL_HAVE_DOC_INFO) add_custom_target(doc_info ALL DEPENDS ${MGL_OUT}/mathgl_en.info DEPENDS ${MGL_OUT}/mathgl_ru.info ) # TODO: try to install all mathgl*.info* in future!!! install(FILES ${MGL_OUT}/mathgl_en.info ${MGL_OUT}/mathgl_en.info-1 ${MGL_OUT}/mathgl_en.info-2 ${MGL_OUT}/mathgl_en.info-3 DESTINATION ${MGL_INFO_PATH}) endif(MGL_HAVE_DOC_INFO) if(MGL_HAVE_DOC_HTML) add_custom_target(doc_html ALL DEPENDS ${MGL_OUT}/mgl_en.html DEPENDS ${MGL_OUT}/mathgl_en.html DEPENDS ${MGL_OUT}/mgl_ru.html DEPENDS ${MGL_OUT}/mathgl_ru.html ) install(FILES ${MGL_TEX}/qt.png ${MGL_TEX}/fltk.png ${MGL_TEX}/classes.png ${MGL_TEX}/datadvance.png DESTINATION ${MGL_DOC_PATH}) install(FILES ${MGL_OUT}/mathgl_en.html ${MGL_OUT}/mgl_en.html ${MGL_OUT}/mathgl_ru.html ${MGL_OUT}/mgl_ru.html DESTINATION ${MGL_DOC_PATH}) install(DIRECTORY ${MGL_OUT}/png DESTINATION ${MGL_DOC_PATH}) install(DIRECTORY ${MGL_OUT}/udav DESTINATION ${MGL_DOC_PATH}) endif(MGL_HAVE_DOC_HTML) if(MGL_HAVE_DOC_SITE) add_custom_target(doc_site ALL DEPENDS ${site_en} DEPENDS ${site_ru} ) endif(MGL_HAVE_DOC_SITE) if(MGL_HAVE_DOC_PDF_EN) add_custom_target(doc_en ALL DEPENDS ${MGL_OUT}/mgl_en.pdf DEPENDS ${MGL_OUT}/mathgl_en.pdf ) install(FILES ${MGL_OUT}/mathgl_en.pdf ${MGL_OUT}/mgl_en.pdf DESTINATION ${MGL_DOC_PATH}) endif(MGL_HAVE_DOC_PDF_EN) if(MGL_HAVE_DOC_PDF_RU) add_custom_target(doc_ru ALL # DEPENDS ${MGL_OUT}/mgl_ru.pdf # DEPENDS ${MGL_OUT}/mathgl_ru.pdf ) # install(FILES ${MGL_OUT}/mathgl_ru.pdf DESTINATION ${MGL_DOC_PATH}) endif(MGL_HAVE_DOC_PDF_RU) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "doc_en;doc_ru;./mathgl*.*;./mgl*.*") install(FILES ${MGL_TEX}/mglconv.1 ${MGL_TEX}/mglview.1 ${MGL_TEX}/udav.1 ${MGL_TEX}/mgl.cgi.1 DESTINATION ${MGL_MAN_PATH}/man1) install(FILES ${MGL_TEX}/mgl.5 DESTINATION ${MGL_MAN_PATH}/man5) mathgl-2.4.4/texinfo/gplv3-127x51.png0000644000175000017500000001051513513030041017231 0ustar alastairalastairPNG  IHDR3'bKGDC pHYs  tIME%/VVIDATxyT?u5ЍaP41C =fS1D::htF㐘Ɉar1j\0Ը0 ]݈ MFfUW_jiZ9sPU/?Up"p@ 4),䑪_^Z"Rs$}-G_-2\ൃx-:}n6|-Ha036 .0$t2a =IP/J=7+<”d vȅ.¤P=W)/]@C<Vujz1 հS#0OC*M_M@i kEV*";;V($} \Q}HtN@8U uX ~ j3' jo') 8äڨuXlAvvaUvuhy8 ~p3Rv= # PnkPx\V`_ gm&pL|o &05&28 ǫ9> j X` ~ G`\bNZ+ bi#U7^b2EI)j?"g5@l\êkqMu TJuSo* ,ƽ&_iP5J5彼$R v슪~d:2 4'>P&{8$ |>VٰW"e3|V߹_jV;z~B/| |HטVuk9-lNQ,)0AԾ->_`HZqj0GCvޮR ǹb%_"Rs̽@O'K%y))W(v5"{7%:-{ZS *z" }LS-E#էsUXu7-)i,)&?GTD6{u1hu EM;\ 'w7e 4dx`@m> NR>R *(c&U5ƹ"a_VU`1=jA) g*fR6P1VT#r5Pa |1:V캿8K[g1lNMJILd"O-rH=wM^ZF t̲a 8WiOiX,>]`N.N'1 HxujC>{ŗHgf<)g+5'USxk 0V0w 0ZR e:5"y}X'lH>۶}evvTar;=gg>&%0ZJ^ZQ}v υjrV-9-dw7}28xWvaT}V?Gkkwɐp:k hhKs ,Ti-pZ;JՏdMO37@4A9Z_k.ſo"]nh/D LvQLd}2Tb U !p/^zj2IֈDD$dpi3DJGhW)>L9ö KW>w\B3&vLMTUs.NRLvsPY8x~ 4π<;SeD>Z1Wdc$odTU3yEx:wP83DJzd[XR ~R܁.\ JT<>v l*,)ڹrVjzI78u_*ցc8BM$(no3ͅI@4]V)scsDWT43W|+}{P6^g]{^7õp.<U mK= !0/ hc "Kyי%B™|e鴼'm͛PT N,&o];(o}9 }6yOWnw 0ށ[G_ q8&\xˎ>îR^Z-B<ˠgpds gé;i.| pn) 9^6>'p*&xD>Ci s)8bif2U#_pjD)<)a(m@Exܵ Hjo`O 28#Nt6R8cTi(fJ`ל{lD,&[f1ϽpOtaV}o/& ,r*qW.Q^>rJ'OSJe^T'RTo Ş>v΅:}LH O͞ӁݝL#7}˫ߨ7Pޙq= xs@K XhS0Msb.!X0\Xt JxbTwHKG9kњ-a/c۟3Xk{LLp fjll5f&#cGVA޾;Kn W QXqىZ+'΅~!cnXfSFRlb*38_kEU<(=K#SͧT1˼ߖc_K5”{at̄mRxJsR V/{k=@Hy56x;v"[%ihagV+̩R]ex@_IENDB`mathgl-2.4.4/texinfo/udav.10000644000175000017500000000107013513030041015640 0ustar alastairalastair.\" Process this file with .\" groff -man -Tascii udav.1 .\" .TH UDAV 1 "MARCH 2012" MathGL "User Manuals" .SH NAME udav \- program for data visualization based on MathGL library .SH SYNOPSIS .B udav [scriptfile] .SH DESCRIPTION .B udav reads MGL scripts from .I scriptfile to produce plots of specified functions or data. The program will create a GUI window which show the script result and allow to edit the script itself. .SH AUTHOR mglview was written by Alexey Balakin, http://mathgl.sourceforge.net/ .SH "SEE ALSO" .BR mglview (1), .BR mglconv (1), .BR mgl (5) mathgl-2.4.4/texinfo/json.html0000644000175000017500000001052213513030041016460 0ustar alastairalastair Select sample

You can use mouse with pressed left button for rotation; with pressed middle button for shift; mouse wheel for zoom in/out. Double click will restore original view.

mathgl-2.4.4/texinfo/widget_en.texi0000644000175000017500000010436013513030041017465 0ustar alastairalastair @c ------------------------------------------------------------------ @chapter Widget classes @nav{} @cindex mglWnd @cindex mglGLUT @cindex Fl_MathGL @cindex QMathGL @cindex window @cindex widgets There are set of ``window'' classes for making a window with MathGL graphics: @code{mglWindow}, @code{mglFLTK}, @code{mglQT} and @code{mglGLUT} for whole window, @code{Fl_MathGL} and @code{QMathGL} as widgets. All these classes allow user to show, rotate, export, and change view of the plot using keyboard. Most of them (except @code{mglGLUT}) also have toolbar and menu for simplifying plot manipulation. All window classes have mostly the same set of functions derived from @ref{mglWnd class}. For drawing you can use: @code{NULL} pointer if you'll update plot manually, global callback function of type @code{int draw(@code{HMGL} gr, @code{void *}p)} or @code{int draw(@code{mglGraph *}gr)}, or instance of class derived from @ref{mglDraw class}. Basically, this class have 2 main virtual methods: @verbatim class mglDraw { public: virtual int Draw(mglGraph *) { return 0; }; virtual void Reload() {}; }; @end verbatim You should inherit yours class from @code{mglDraw} and re-implement one or both functions for drawing. The window can be constructed using one of following classes (see @ref{Using MathGL window} for examples). @deftypefn {Constructor on @code{mglFLTK}} {} mglFLTK (@code{const char *}title=@code{"MathGL"}) @deftypefnx {Constructor on @code{mglFLTK}} {} mglFLTK (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0) @deftypefnx {Constructor on @code{mglFLTK}} {} mglFLTK (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"}) @deftypefnx {Constructor on @code{mglFLTK}} {} mglFLTK (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"}) @deftypefnx {C function} @code{HMGL} mgl_create_graph_fltk (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)) Creates a FLTK-based window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @ref{mglDraw class}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no animation or slides). Parameter @var{title} sets the title of the window. Parameter @var{par} contains pointer to data for the plotting function @var{draw}. FLTK-based windows is a bit faster than Qt ones, and provide better support of multi-threading. @end deftypefn @deftypefn {Method on @code{mglFLTK}} @code{int} RunThr () @deftypefnx {C function} @code{int} mgl_fltk_thr () Run main loop for event handling in separate thread. Note, right now it work for FLTK windows only. @end deftypefn @deftypefn {Constructor on @code{mglQT}} {} mglQT (@code{const char *}title=@code{"MathGL"}) @deftypefnx {Constructor on @code{mglQT}} {} mglQT (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0) @deftypefnx {Constructor on @code{mglQT}} {} mglQT (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"}) @deftypefnx {Constructor on @code{mglQT}} {} mglQT (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"}) @deftypefnx {C function} @code{HMGL} mgl_create_graph_qt (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)) Creates a FLTK-based window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @ref{mglDraw class}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no animation or slides). Parameter @var{title} sets the title of the window. Parameter @var{par} contains pointer to data for the plotting function @var{draw}. @end deftypefn @deftypefn {Constructor on @code{mglGLUT}} {} mglGLUT (@code{const char *}title=@code{"MathGL"}) @deftypefnx {Constructor on @code{mglGLUT}} {} mglGLUT (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0) @deftypefnx {Constructor on @code{mglGLUT}} {} mglGLUT (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"}) @deftypefnx {Constructor on @code{mglGLUT}} {} mglGLUT (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"}) @deftypefnx {C function} @code{HMGL} mgl_create_graph_glut (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)) Creates a GLUT-based window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @code{mglDraw} class. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no animation or slides). Parameter @var{title} sets the title of the window. Parameter @var{par} contains pointer to data for the plotting function @var{draw}. GLUT-based windows are fastest one but there is no toolbar, and plot have some issues due to OpenGL limitations. There are some keys handles for manipulating by the plot: 'a', 'd', 'w', 's' for the rotating; ',', '.' for viewing of the previous or next frames in the list; 'r' for the switching of transparency; 'f' for the switching of lightning; 'x' for hiding (closing) the window. @end deftypefn @menu * mglWnd class:: * mglDraw class:: * Fl_MathGL class:: * QMathGL class:: * wxMathGL class:: @end menu @c ------------------------------------------------------------------ @external{} @node mglWnd class, mglDraw class, , Widget classes @section mglWnd class @nav{} @cindex mglWnd @cindex window @c @cindex mglDraw This class is abstract class derived from mglGraph class (see @ref{MathGL core}). It is defined in @code{#include } and provide base methods for handling window with MathGL graphics. Inherited classes are exist for QT and FLTK widget libraries: @code{mglQT} in @code{#include }, @code{mglFLTK} in @code{#include }. @deftypefn {Method on @code{mglWnd}} @code{int} Run () @deftypefnx {C function} @code{int} mgl_qt_run () @deftypefnx {C function} @code{int} mgl_fltk_run () Run main loop for event handling. Usually it should be called in a separate thread or as last function call in @code{main()}. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{void *}p)=@code{NULL}) @deftypefnx {Method on @code{mglWnd}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{mglGraph *}gr)) @deftypefnx {Method on @code{mglWnd}} @code{void} SetDrawFunc (@code{mglDraw *}obj) @deftypefnx {C function} @code{void} mgl_wnd_set_func (@code{HMGL} gr, @code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par, @code{void} (*reload)(@code{void *}p)) Set callback functions for drawing (@var{draw}) and data reloading (@var{reload}), or instance @var{obj} of a class derived from @code{mglDraw}. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} SetClickFunc (@code{void} (*func)(@code{HMGL} gr, @code{void *}p)) @deftypefnx {C function} @code{void} mgl_set_click_func (@code{void} (*func)(@code{HMGL} gr, @code{void *}p)) Set callback function @var{func} which will be called on mouse click. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} SetMutex(@code{pthread_mutex_t *}mutex) @deftypefnx {C function} @code{void} mgl_wnd_set_mutex(@code{HMGL} gr, @code{pthread_mutex_t *}mutex) Set external mutex for lock/unlock external calculations by widget. This functions is called automatically at using @ref{mglDraw class}. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} ToggleAlpha () @deftypefnx {C function} @code{void} mgl_wnd_toggle_alpha (@code{HMGL} gr) Switch on/off transparency but do not overwrite switches in user drawing function. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} ToggleLight () @deftypefnx {C function} @code{void} mgl_wnd_toggle_light (@code{HMGL} gr) Switch on/off lighting but do not overwrite switches in user drawing function. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} ToggleRotate () @deftypefnx {C function} @code{void} mgl_wnd_toggle_rotate (@code{HMGL} gr) Switch on/off rotation by mouse. Usually, left button is used for rotation, middle button for shift, right button for zoom/perspective. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} ToggleZoom () @deftypefnx {C function} @code{void} mgl_wnd_toggle_zoom (@code{HMGL} gr) Switch on/off zooming by mouse. Just select rectangular region by mouse and it will be zoomed in. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} ToggleNo () @deftypefnx {C function} @code{void} mgl_wnd_toggle_no (@code{HMGL} gr) Switch off all zooming and rotation and restore initial state. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} Update () @deftypefnx {C function} @code{void} mgl_wnd_update (@code{HMGL} gr) Update window contents. This is very useful function for manual updating the plot while long calculation was running in parallel thread. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} ReLoad () @deftypefnx {C function} @code{void} mgl_wnd_reload (@code{HMGL} gr) Reload user data and update picture. This function also update number of frames which drawing function can create. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} Adjust () @deftypefnx {C function} @code{void} mgl_wnd_adjust (@code{HMGL} gr) Adjust size of bitmap to window size. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} NextFrame () @deftypefnx {C function} @code{void} mgl_wnd_next_frame (@code{HMGL} gr) Show next frame if one. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} PrevFrame () @deftypefnx {C function} @code{void} mgl_wnd_prev_frame (@code{HMGL} gr) Show previous frame if one. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} Animation () @deftypefnx {C function} @code{void} mgl_wnd_animation (@code{HMGL} gr) Run/stop slideshow (animation) of frames. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} SetDelay (@code{double} dt) @deftypefnx {C function} @code{void} mgl_wnd_set_delay (@code{HMGL} gr, @code{double} dt) Sets delay for animation in seconds. Default value is 1 sec. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{double} GetDelay () @deftypefnx {C function} @code{double} mgl_wnd_get_delay (@code{HMGL} gr) Gets delay for animation in seconds. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void} Setup (@code{bool} clfupd=@code{true}, @code{bool} showpos=@code{false}) @deftypefnx {C function} @code{void} mgl_setup_window (@code{HMGL} gr, @code{bool} clfupd, @code{bool} showpos) Enable/disable flags for: @itemize @bullet @item clearing plot before Update(); @item showing the last mouse click position in the widget. @end itemize @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{mglPoint} LastMousePos () @deftypefnx {C function} @code{void} mgl_get_last_mouse_pos (@code{HMGL} gr, @code{mreal *}x, @code{mreal *}y, @code{mreal *}z) Gets last position of mouse click. @end deftypefn @deftypefn {Method on @code{mglWnd}} @code{void *} Widget () @deftypefnx {C function} @code{void *} mgl_fltk_widget (@code{HMGL} gr) @deftypefnx {C function} @code{void *} mgl_qt_widget (@code{HMGL} gr) Return pointer to widget (@ref{Fl_MathGL class} or @ref{QMathGL class}) used for plotting. @end deftypefn @c ------------------------------------------------------------------ @external{} @node mglDraw class, Fl_MathGL class, mglWnd class, Widget classes @section mglDraw class @nav{} @cindex mglDraw This class provide base functionality for callback drawing and running calculation in separate thread. It is defined in @code{#include }. You should make inherited class and implement virtual functions if you need it. @deftypefn {Virtual method on @code{mglDraw}} @code{int} Draw (@code{mglGraph *}gr) This is callback drawing function, which will be called when any redrawing is required for the window. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. @end deftypefn @deftypefn {Virtual method on @code{mglDraw}} @code{void} Reload () This is callback function, which will be called if user press menu or toolbutton to reload data. @end deftypefn @deftypefn {Virtual method on @code{mglDraw}} @code{void} Click () This is callback function, which will be called if user click mouse. @end deftypefn @deftypefn {Virtual method on @code{mglDraw}} @code{void} Calc () This is callback function, which will be called if user start calculations in separate thread by calling @code{mglDraw::Run()} function. It should periodically call @code{mglDraw::Check()} function to check if calculations should be paused. @end deftypefn @deftypefn {Method on @code{mglDraw}} @code{void} Run () Runs @code{mglDraw::Calc()} function in separate thread. It also initialize @code{mglDraw::thr} variable and unlock @code{mglDraw::mutex}. Function is present only if FLTK support for widgets was enabled. @end deftypefn @deftypefn {Method on @code{mglDraw}} @code{void} Cancel () Cancels thread with calculations. Function is present only if FLTK support for widgets was enabled. @end deftypefn @deftypefn {Method on @code{mglDraw}} @code{void} Pause () Pauses thread with calculations by locking @code{mglDraw::mutex}. You should call @code{mglDraw::Continue()} to continue calculations. Function is present only if FLTK support for widgets was enabled. @end deftypefn @deftypefn {Method on @code{mglDraw}} @code{void} Continue () Continues calculations by unlocking @code{mglDraw::mutex}. Function is present only if FLTK support for widgets was enabled. @end deftypefn @deftypefn {Method on @code{mglDraw}} @code{void} Continue () Checks if calculations should be paused and pause it. Function is present only if FLTK support for widgets was enabled. @end deftypefn @c ------------------------------------------------------------------ @external{} @node Fl_MathGL class, QMathGL class, mglDraw class, Widget classes @section Fl_MathGL class @nav{} @cindex Fl_MathGL @cindex widgets Class is FLTK widget which display MathGL graphics. It is defined in @code{#include }. @fig{fltk, Example of FLTK window with MathGL plot.} @deftypemethod Fl_MathGL @code{void} set_draw (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p)) @deftypemethodx Fl_MathGL @code{void} set_draw (@code{int} (*draw)(@code{mglGraph *}gr)) @deftypemethodx Fl_MathGL @code{void} set_draw (@code{mglDraw *}draw) Sets drawing function as global function or as one from a class @code{mglDraw}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Parameter @var{par} contains pointer to data for the plotting function @var{draw}. @end deftypemethod @deftypemethod Fl_MathGL @code{mglDraw *}get_class () Get pointer to @code{mglDraw} class or @code{NULL} if absent. @end deftypemethod @deftypemethod Fl_MathGL @code{void} update () Update (redraw) plot. @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_angle (@code{mreal} t, @code{mreal} p) Set angles for additional plot rotation @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_flag (@code{int} f) Set bitwise flags for general state (1-Alpha, 2-Light) @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_state (@code{bool} r, @code{bool} z) Set flags for handling mouse: @var{z}=@code{true} allow zooming, @var{r}=@code{true} allow rotation/shifting/perspective and so on. @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_zoom (@code{mreal} X1, @code{mreal} Y1, @code{mreal} X2, @code{mreal} Y2) Set zoom in/out region @end deftypemethod @deftypemethod Fl_MathGL @code{void} get_zoom (@code{mreal *}X1, @code{mreal *}Y1, @code{mreal *}X2, @code{mreal *}Y2) Get zoom in/out region @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_popup (@code{const Fl_Menu_Item *}pmenu, @code{Fl_Widget *}w, @code{void *}v) Set popup menu pointer @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_graph (@code{HMGL} gr) @deftypemethodx Fl_MathGL @code{void} set_graph (@code{mglGraph *}gr) Set new grapher instead of built-in one. Note that Fl_MathGL will automatically delete this object at destruction or at new @code{set_graph()} call. @end deftypemethod @deftypemethod Fl_MathGL @code{HMGL} get_graph () Get pointer to grapher. @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_show_warn (@code{bool} val) Show window with warnings after script parsing. @end deftypemethod @deftypemethod Fl_MathGL @code{void} stop (@code{bool} stop=@code{true}) Ask to stop of script parsing. @end deftypemethod @deftypemethod Fl_MathGL @code{void} set_handle_key (@code{bool} val) Enable/disable key handling as in mglview (default is false). @end deftypemethod @deftypemethod Fl_MathGL @code{int} get_last_id () Get id of last clicked object. @end deftypemethod @deftypemethod Fl_MathGL @code{bool} running () Check if script is parsing now or not. @end deftypemethod @deftypecv {Fl_MathGL option} Fl_MathGL @code{Fl_Valuator *} tet_val Pointer to external tet-angle validator. @end deftypecv @deftypecv {Fl_MathGL option} Fl_MathGL @code{Fl_Valuator *} phi_val Pointer to external phi-angle validator. @end deftypecv @c ------------------------------------------------------------------ @external{} @node QMathGL class, wxMathGL class, Fl_MathGL class, Widget classes @section QMathGL class @nav{} @cindex QMathGL @cindex widgets Class is Qt widget which display MathGL graphics. It is defined in @code{#include }. @fig{qt, Example of Qt window with MathGL plot.} @deftypemethod QMathGL @code{void} setDraw (@code{mglDraw *}dr) Sets drawing functions from a class inherited from @code{mglDraw}. @end deftypemethod @deftypemethod QMathGL @code{void} setDraw (@code{int (*}draw@code{)(mglBase *}gr, @code{void *}p@code{)}, @code{void *}par=@code{NULL}) @deftypemethodx QMathGL @code{void} setDraw (@code{int (*}draw@code{)(mglGraph *}gr@code{)}) Sets the drawing function @var{draw}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Parameter @var{par} contains pointer to data for the plotting function @var{draw}. @end deftypemethod @deftypemethod QMathGL @code{void} setGraph (@code{HMGL} gr) @deftypemethodx QMathGL @code{void} setGraph (@code{mglGraph *}gr) Set pointer to external grapher (instead of built-in one). Note that QMathGL will automatically delete this object at destruction or at new @code{setGraph()} call. @end deftypemethod @deftypemethod QMathGL @code{HMGL} getGraph () Get pointer to grapher. @end deftypemethod @deftypemethod QMathGL @code{void} setPopup (@code{QMenu *}p) Set popup menu pointer. @end deftypemethod @deftypemethod QMathGL @code{void} setSize (@code{int} w, @code{int} h) Set widget/picture sizes @end deftypemethod @deftypemethod QMathGL @code{double} getRatio () Return aspect ratio of the picture. @end deftypemethod @deftypemethod QMathGL @code{int} getPer () Get perspective value in percents. @end deftypemethod @deftypemethod QMathGL @code{int} getPhi () Get Phi-angle value in degrees. @end deftypemethod @deftypemethod QMathGL @code{int} getTet () Get Theta-angle value in degrees. @end deftypemethod @deftypemethod QMathGL @code{bool} getAlpha () Get transparency state. @end deftypemethod @deftypemethod QMathGL @code{bool} getLight () Get lightning state. @end deftypemethod @deftypemethod QMathGL @code{bool} getZoom () Get mouse zooming state. @end deftypemethod @deftypemethod QMathGL @code{bool} getRotate () Get mouse rotation state. @end deftypemethod @deftypefn {Slot on @code{QMathGL}} @code{void} refresh () Redraw saved bitmap without executing drawing function. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} update () Update picture by executing drawing function. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} copy () Copy graphics to clipboard. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} copyClickCoor () Copy coordinates of click (as text). @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} print () Print current picture. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} stop () Send signal to stop drawing. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} adjust () Adjust image size to fit whole widget. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} nextSlide () Show next slide. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} prevSlide () Show previous slide. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} animation (@code{bool} st=@code{true}) Start/stop animation. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setPer (@code{int} val) Set perspective value. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setPhi (@code{int} val) Set Phi-angle value. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setTet (@code{int} val) Set Theta-angle value. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setAlpha (@code{bool} val) Switch on/off transparency. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setLight (@code{bool} val) Switch on/off lightning. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setGrid (@code{bool} val) Switch on/off drawing of grid for absolute coordinates. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setZoom (@code{bool} val) Switch on/off mouse zooming. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setRotate (@code{bool} val) Switch on/off mouse rotation. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} zoomIn () Zoom in graphics. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} zoomOut () Zoom out graphics. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} shiftLeft () Shift graphics to left direction. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} shiftRight () Shift graphics to right direction. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} shiftUp () Shift graphics to up direction. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} shiftDown () Shift graphics to down direction. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} restore () Restore zoom and rotation to default values. @end deftypefn @c @deftypefn {Slot on @code{QMathGL}} @code{void} reload () @c Reload data and redraw graphics. @c @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportPNG (@code{QString} fname=@code{""}) Export current picture to PNG file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportPNGs (@code{QString} fname=@code{""}) Export current picture to PNG file (no transparency). @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportJPG (@code{QString} fname=@code{""}) Export current picture to JPEG file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportBPS (@code{QString} fname=@code{""}) Export current picture to bitmap EPS file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportEPS (@code{QString} fname=@code{""}) Export current picture to vector EPS file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportSVG (@code{QString} fname=@code{""}) Export current picture to SVG file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportGIF (@code{QString} fname=@code{""}) Export current picture to GIF file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportTEX (@code{QString} fname=@code{""}) Export current picture to LaTeX/Tikz file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportTGA (@code{QString} fname=@code{""}) Export current picture to TGA file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportXYZ (@code{QString} fname=@code{""}) Export current picture to XYZ/XYZL/XYZF file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportOBJ (@code{QString} fname=@code{""}) Export current picture to OBJ/MTL file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportSTL (@code{QString} fname=@code{""}) Export current picture to STL file. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} exportOFF (@code{QString} fname=@code{""}) Export current picture to OFF file. @end deftypefn @c @deftypefn {Slot on @code{QMathGL}} @code{void} exportX3D (@code{QString} fname=@code{""}) @c Export current picture to X3D file. @c @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void}setUsePrimitives (@code{bool} use) Enable using list of primitives for frames. This allows frames transformation/zoom but requires much more memory. Default value is @code{true}. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} setMGLFont (@code{QString} path) Restore (@var{path}=@code{""}) or load font for graphics. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} about () Show about information. @end deftypefn @deftypefn {Slot on @code{QMathGL}} @code{void} aboutQt () Show information about Qt version. @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} phiChanged (@code{int} val) Phi angle changed (by mouse or by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} tetChanged (@code{int} val) Tet angle changed (by mouse or by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} perChanged (@code{int} val) Perspective changed (by mouse or by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} alphaChanged (@code{bool} val) Transparency changed (by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} lightChanged (@code{bool} val) Lighting changed (by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} gridChanged (@code{bool} val) Grid drawing changed (by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} zoomChanged (@code{bool} val) Zooming changed (by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} rotateChanged (@code{bool} val) Rotation changed (by toolbar). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} mouseClick (@code{mreal} x, @code{mreal} y, @code{mreal} z) Mouse click take place at position @{x,y,z@}. @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} frameChanged (@code{int} val) Need another frame to show. @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} showWarn (@code{QString} warn) Need to show warning. @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} posChanged (@code{QString} pos) Position of mouse click is changed. @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} objChanged (@code{int} id) Object id is changed (due to mouse click). @end deftypefn @deftypefn {Signal on @code{QMathGL}} @code{void} refreshData () Data can be changed (drawing is finished). @end deftypefn @deftypecv {QMathGL option} QMathGL @code{QString} appName Application name for message boxes. @end deftypecv @deftypecv {QMathGL option} QMathGL @code{bool} autoResize Allow auto resizing (default is false). @end deftypecv @c ------------------------------------------------------------------ @external{} @node wxMathGL class, , QMathGL class, Widget classes @section wxMathGL class @nav{} @cindex wxMathGL @cindex widgets Class is WX widget which display MathGL graphics. It is defined in @code{#include }. @deftypemethod wxMathGL @code{void} SetDraw (@code{mglDraw *}dr) Sets drawing functions from a class inherited from @code{mglDraw}. @end deftypemethod @deftypemethod wxMathGL @code{void} SetDraw (@code{int (*}draw@code{)(mglBase *}gr, @code{void *}p@code{)}, @code{void *}par=@code{NULL}) @deftypemethodx wxMathGL @code{void} SetDraw (@code{int (*}draw@code{)(mglGraph *}gr@code{)}) Sets the drawing function @var{draw}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Parameter @var{par} contains pointer to data for the plotting function @var{draw}. @end deftypemethod @deftypemethod wxMathGL @code{void} SetGraph (@code{HMGL} gr) @deftypemethodx wxMathGL @code{void} SetGraph (@code{mglGraph *}gr) Set pointer to external grapher (instead of built-in one). Note that wxMathGL will automatically delete this object at destruction or at new @code{setGraph()} call. @end deftypemethod @deftypemethod wxMathGL @code{HMGL} GetGraph () Get pointer to grapher. @end deftypemethod @deftypemethod wxMathGL @code{void} SetPopup (@code{wxMenu *}p) Set popup menu pointer. @end deftypemethod @deftypemethod wxMathGL @code{void} SetSize (@code{int} w, @code{int} h) Set widget/picture sizes @end deftypemethod @deftypemethod wxMathGL @code{double} GetRatio () Return aspect ratio of the picture. @end deftypemethod @deftypemethod wxMathGL @code{int} GetPer () Get perspective value in percents. @end deftypemethod @deftypemethod wxMathGL @code{int} GetPhi () Get Phi-angle value in degrees. @end deftypemethod @deftypemethod wxMathGL @code{int} GetTet () Get Theta-angle value in degrees. @end deftypemethod @deftypemethod wxMathGL @code{bool} GetAlpha () Get transparency state. @end deftypemethod @deftypemethod wxMathGL @code{bool} GetLight () Get lightning state. @end deftypemethod @deftypemethod wxMathGL @code{bool} GetZoom () Get mouse zooming state. @end deftypemethod @deftypemethod wxMathGL @code{bool} GetRotate () Get mouse rotation state. @end deftypemethod @deftypemethod wxMathGL @code{void} Repaint () Redraw saved bitmap without executing drawing function. @end deftypemethod @deftypemethod wxMathGL @code{void} Update () Update picture by executing drawing function. @end deftypemethod @deftypemethod wxMathGL @code{void} Copy () Copy graphics to clipboard. @end deftypemethod @deftypemethod wxMathGL @code{void} Print () Print current picture. @end deftypemethod @comment @deftypemethod wxMathGL @code{void} Stop () @comment Send signal to stop drawing. @comment @end deftypemethod @deftypemethod wxMathGL @code{void} Adjust () Adjust image size to fit whole widget. @end deftypemethod @deftypemethod wxMathGL @code{void} NextSlide () Show next slide. @end deftypemethod @deftypemethod wxMathGL @code{void} PrevSlide () Show previous slide. @end deftypemethod @deftypemethod wxMathGL @code{void} Animation (@code{bool} st=@code{true}) Start/stop animation. @end deftypemethod @deftypemethod wxMathGL @code{void} SetPer (@code{int} val) Set perspective value. @end deftypemethod @deftypemethod wxMathGL @code{void} SetPhi (@code{int} val) Set Phi-angle value. @end deftypemethod @deftypemethod wxMathGL @code{void} SetTet (@code{int} val) Set Theta-angle value. @end deftypemethod @deftypemethod wxMathGL @code{void} SetAlpha (@code{bool} val) Switch on/off transparency. @end deftypemethod @deftypemethod wxMathGL @code{void} SetLight (@code{bool} val) Switch on/off lightning. @end deftypemethod @comment @deftypemethod wxMathGL @code{void} SetGrid (@code{bool} val) @comment Switch on/off drawing of grid for absolute coordinates. @comment @end deftypemethod @deftypemethod wxMathGL @code{void} SetZoom (@code{bool} val) Switch on/off mouse zooming. @end deftypemethod @deftypemethod wxMathGL @code{void} SetRotate (@code{bool} val) Switch on/off mouse rotation. @end deftypemethod @deftypemethod wxMathGL @code{void} ZoomIn () Zoom in graphics. @end deftypemethod @deftypemethod wxMathGL @code{void} ZoomOut () Zoom out graphics. @end deftypemethod @deftypemethod wxMathGL @code{void} ShiftLeft () Shift graphics to left direction. @end deftypemethod @deftypemethod wxMathGL @code{void} ShiftRight () Shift graphics to right direction. @end deftypemethod @deftypemethod wxMathGL @code{void} ShiftUp () Shift graphics to up direction. @end deftypemethod @deftypemethod wxMathGL @code{void} ShiftDown () Shift graphics to down direction. @end deftypemethod @deftypemethod wxMathGL @code{void} Restore () Restore zoom and rotation to default values. @end deftypemethod @c @deftypemethod wxMathGL @code{void} reload () @c Reload data and redraw graphics. @c @end deftypemethod @deftypemethod wxMathGL @code{void} About () Show about information. @end deftypemethod @deftypemethod wxMathGL @code{void} ExportPNG (@code{QString} fname=@code{""}) Export current picture to PNG file. @end deftypemethod @deftypemethod wxMathGL @code{void} ExportPNGs (@code{QString} fname=@code{""}) Export current picture to PNG file (no transparency). @end deftypemethod @deftypemethod wxMathGL @code{void} ExportJPG (@code{QString} fname=@code{""}) Export current picture to JPEG file. @end deftypemethod @deftypemethod wxMathGL @code{void} ExportBPS (@code{QString} fname=@code{""}) Export current picture to bitmap EPS file. @end deftypemethod @deftypemethod wxMathGL @code{void} ExportEPS (@code{QString} fname=@code{""}) Export current picture to vector EPS file. @end deftypemethod @deftypemethod wxMathGL @code{void} ExportSVG (@code{QString} fname=@code{""}) Export current picture to SVG file. @end deftypemethod @external{} mathgl-2.4.4/texinfo/other_ru.texi0000644000175000017500000006145513513030041017356 0ustar alastairalastair@c ------------------------------------------------------------------ @chapter Other classes @nav{} There are few end-user classes: @code{mglGraph} (see @ref{MathGL core}), @code{mglWindow} and @code{mglGLUT} (see @ref{Widget classes}), @code{mglData} (see @ref{Data processing}), @code{mglParse} (see @ref{MGL scripts}). Exactly these classes I recommend to use in most of user programs. All methods in all of these classes are inline and have exact C/Fortran analogue functions. This give compiler independent binary libraries for MathGL. However, sometimes you may need to extend MathGL by writing yours own plotting functions or handling yours own data structures. In these cases you may need to use low-level API. This chapter describes it. @fig{classes, Class diagram for MathGL} The internal structure of MathGL is rather complicated. There are C++ classes @code{mglBase}, @code{mglCanvas}, ... for drawing primitives and positioning the plot (blue ones in the figure). There is a layer of C functions, which include interface for most important methods of these classes. Also most of plotting functions are implemented as C functions. After it, there are ``inline'' front-end classes which are created for user convenience (yellow ones in the figure). Also there are widgets for FLTK, Qt and other libraries (green ones in the figure). Below I show how this internal classes can be used. @menu * mglBase class:: * mglDataA class:: * mglColor class:: * mglPoint class:: @end menu @c ------------------------------------------------------------------ @external{} @node mglBase class, mglDataA class, , Other classes @section Define new kind of plot (mglBase class) @nav{} Basically most of new kinds of plot can be created using just MathGL primitives (see @ref{Primitives}). However the usage of @code{mglBase} methods can give you higher speed of drawing and better control of plot settings. All plotting functions should use a pointer to @code{mglBase} class (or @code{HMGL} type in C functions) due to compatibility issues. Exactly such type of pointers are used in front-end classes (@code{mglGraph, mglWindow}) and in widgets (@code{QMathGL, Fl_MathGL}). MathGL tries to remember all vertexes and all primitives and plot creation stage, and to use them for making final picture by demand. Basically for making plot, you need to add vertexes by @code{AddPnt()} function, which return index for new vertex, and call one of primitive drawing function (like @code{mark_plot(), arrow_plot(), line_plot(), trig_plot(), quad_plot(), text_plot()}), using vertex indexes as argument(s). @code{AddPnt()} function use 2 mreal numbers for color specification. First one is positioning in textures -- integer part is texture index, fractional part is relative coordinate in the texture. Second number is like a transparency of plot (or second coordinate in the 2D texture). I don't want to put here detailed description of @code{mglBase} class. It was rather well documented in @code{mgl2/base.h} file. I just show and example of its usage on the base of circle drawing. First, we should prototype new function @code{circle()} as C function. @verbatim #ifdef __cplusplus extern "C" { #endif void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt); #ifdef __cplusplus } #endif @end verbatim This is done for generating compiler independent binary. Because only C-functions have standard naming mechanism, the same for any compilers. Now, we create a C++ file and put the code of function. I'll write it line by line and try to comment all important points. @verbatim void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) { @end verbatim First, we need to check all input arguments and send warnings if something is wrong. In our case it is negative value of @var{r} argument. We just send warning, since it is not critical situation -- other plot still can be drawn. @verbatim if(r<=0) { gr->SetWarn(mglWarnNeg,"Circle"); return; } @end verbatim Next step is creating a group. Group keep some general setting for plot (like options) and useful for export in 3d files. @verbatim static int cgid=1; gr->StartGroup("Circle",cgid++); @end verbatim Now let apply options. Options are rather useful things, generally, which allow one easily redefine axis range(s), transparency and other settings (see @ref{Command options}). @verbatim gr->SaveState(opt); @end verbatim I use global setting for determining the number of points in circle approximation. Note, that user can change @code{MeshNum} by options easily. @verbatim const int n = gr->MeshNum>1?gr->MeshNum : 41; @end verbatim Let try to determine plot specific flags. MathGL functions expect that most of flags will be sent in string. In our case it is symbol @samp{@@} which set to draw filled circle instead of border only (last will be default). Note, you have to handle @code{NULL} as string pointer. @verbatim bool fill = mglchr(stl,'@'); @end verbatim Now, time for coloring. I use palette mechanism because circle have few colors: one for filling and another for border. @code{SetPenPal()} function parse input string and write resulting texture index in @var{pal}. Function return the character for marker, which can be specified in string @var{str}. Marker will be plotted at the center of circle. I'll show on next sample how you can use color schemes (smooth colors) too. @verbatim long pal=0; char mk=gr->SetPenPal(stl,&pal); @end verbatim Next step, is determining colors for filling and for border. First one for filling. @verbatim mreal c=gr->NextColor(pal), d; @end verbatim Second one for border. I use black color (call @code{gr->AddTexture('k')}) if second color is not specified. @verbatim mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); @end verbatim If user want draw only border (@code{fill=false}) then I use first color for border. @verbatim if(!fill) k=c; @end verbatim Now we should reserve space for vertexes. This functions need @code{n} for border, @code{n+1} for filling and @code{1} for marker. So, maximal number of vertexes is @code{2*n+2}. Note, that such reservation is not required for normal work but can sufficiently speed up the plotting. @verbatim gr->Reserve(2*n+2); @end verbatim We've done with setup and ready to start drawing. First, we need to add vertex(es). Let define NAN as normals, since I don't want handle lighting for this plot, @verbatim mglPoint q(NAN,NAN); @end verbatim and start adding vertexes. First one for central point of filling. I use @code{-1} if I don't need this point. The arguments of @code{AddPnt()} function is: @code{mglPoint(x,y,z)} -- coordinate of vertex, @code{c} -- vertex color, @code{q} -- normal at vertex, @code{-1} -- vertex transparency (@code{-1} for default), @code{3} bitwise flag which show that coordinates will be scaled (@code{0x1}) and will not be cutted (@code{0x2}). @verbatim long n0,n1,n2,m1,m2,i; n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; @end verbatim Similar for marker, but we use different color @var{k}. @verbatim n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; @end verbatim Draw marker. @verbatim if(mk) gr->mark_plot(n2,mk); @end verbatim Time for drawing circle itself. I use @code{-1} for @var{m1}, @var{n1} as sign that primitives shouldn't be drawn for first point @code{i=0}. @verbatim for(i=0,m1=n1=-1;iStop) return; @end verbatim Let find coordinates of vertex. @verbatim mreal t = i*2*M_PI/(n-1.); mglPoint p(x+r*cos(t), y+r*sin(t), z); @end verbatim Save previous vertex and add next one @verbatim n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); @end verbatim and copy it for border but with different color. Such copying is much faster than adding new vertex using @code{AddPnt()}. @verbatim m2 = m1; m1 = gr->CopyNtoC(n1,k); @end verbatim Now draw triangle for filling internal part @verbatim if(fill) gr->trig_plot(n0,n1,n2); @end verbatim and draw line for border. @verbatim gr->line_plot(m1,m2); } @end verbatim Drawing is done. Let close group and return. @verbatim gr->EndGroup(); } @end verbatim Another sample I want to show is exactly the same function but with smooth coloring using color scheme. So, I'll add comments only in the place of difference. @verbatim void circle_cs(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) { @end verbatim In this case let allow negative radius too. Formally it is not the problem for plotting (formulas the same) and this allow us to handle all color range. @verbatim //if(r<=0) { gr->SetWarn(mglWarnNeg,"Circle"); return; } static int cgid=1; gr->StartGroup("CircleCS",cgid++); gr->SaveState(opt); const int n = gr->MeshNum>1?gr->MeshNum : 41; bool fill = mglchr(stl,'@'); @end verbatim Here is main difference. We need to create texture for color scheme specified by user @verbatim long ss = gr->AddTexture(stl); @end verbatim But we need also get marker and color for it (if filling is enabled). Let suppose that marker and color is specified after @samp{:}. This is standard delimiter which stop color scheme entering. So, just lets find it and use for setting pen. @verbatim const char *pen=0; if(stl) pen = strchr(stl,':'); if(pen) pen++; @end verbatim The substring is placed in @var{pen} and it will be used as line style. @verbatim long pal=0; char mk=gr->SetPenPal(pen,&pal); @end verbatim Next step, is determining colors for filling and for border. First one for filling. @verbatim mreal c=gr->GetC(ss,r); @end verbatim Second one for border. @verbatim mreal k=gr->NextColor(pal); @end verbatim The rest part is the same as in previous function. @verbatim if(!fill) k=c; gr->Reserve(2*n+2); mglPoint q(NAN,NAN); long n0,n1,n2,m1,m2,i; n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; if(mk) gr->mark_plot(n2,mk); for(i=0,m1=n1=-1;iStop) return; mreal t = i*2*M_PI/(n-1.); mglPoint p(x+r*cos(t), y+r*sin(t), z); n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); m2 = m1; m1 = gr->CopyNtoC(n1,k); if(fill) gr->trig_plot(n0,n1,n2); gr->line_plot(m1,m2); } gr->EndGroup(); } @end verbatim The last thing which we can do is derive our own class with new plotting functions. Good idea is to derive it from @code{mglGraph} (if you don't need extended window), or from @code{mglWindow} (if you need to extend window). So, in our case it will be @verbatim class MyGraph : public mglGraph { public: inline void Circle(mglPoint p, mreal r, const char *stl="", const char *opt="") { circle(p.x,p.y,p.z, r, stl, opt); } inline void CircleCS(mglPoint p, mreal r, const char *stl="", const char *opt="") { circle_cs(p.x,p.y,p.z, r, stl, opt); } }; @end verbatim Note, that I use @code{inline} modifier for using the same binary code with different compilers. So, the complete sample will be @verbatim #include //--------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt); void circle_cs(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt); #ifdef __cplusplus } #endif //--------------------------------------------------------- class MyGraph : public mglGraph { public: inline void CircleCF(mglPoint p, mreal r, const char *stl="", const char *opt="") { circle(p.x,p.y,p.z, r, stl, opt); } inline void CircleCS(mglPoint p, mreal r, const char *stl="", const char *opt="") { circle_cs(p.x,p.y,p.z, r, stl, opt); } }; //--------------------------------------------------------- void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) { if(r<=0) { gr->SetWarn(mglWarnNeg,"Circle"); return; } static int cgid=1; gr->StartGroup("Circle",cgid++); gr->SaveState(opt); const int n = gr->MeshNum>1?gr->MeshNum : 41; bool fill = mglchr(stl,'@'); long pal=0; char mk=gr->SetPenPal(stl,&pal); mreal c=gr->NextColor(pal), d; mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); if(!fill) k=c; gr->Reserve(2*n+2); mglPoint q(NAN,NAN); long n0,n1,n2,m1,m2,i; n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; if(mk) gr->mark_plot(n2,mk); for(i=0,m1=n1=-1;iStop) return; mreal t = i*2*M_PI/(n-1.); mglPoint p(x+r*cos(t), y+r*sin(t), z); n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); m2 = m1; m1 = gr->CopyNtoC(n1,k); if(fill) gr->trig_plot(n0,n1,n2); gr->line_plot(m1,m2); } gr->EndGroup(); } //--------------------------------------------------------- void circle_cs(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) { static int cgid=1; gr->StartGroup("CircleCS",cgid++); gr->SaveState(opt); const int n = gr->MeshNum>1?gr->MeshNum : 41; bool fill = mglchr(stl,'@'); long ss = gr->AddTexture(stl); const char *pen=0; if(stl) pen = strchr(stl,':'); if(pen) pen++; long pal=0; char mk=gr->SetPenPal(pen,&pal); mreal c=gr->GetC(ss,r); mreal k=gr->NextColor(pal); if(!fill) k=c; gr->Reserve(2*n+2); mglPoint q(NAN,NAN); long n0,n1,n2,m1,m2,i; n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; if(mk) gr->mark_plot(n2,mk); for(i=0,m1=n1=-1;iStop) return; mreal t = i*2*M_PI/(n-1.); mglPoint p(x+r*cos(t), y+r*sin(t), z); n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); m2 = m1; m1 = gr->CopyNtoC(n1,k); if(fill) gr->trig_plot(n0,n1,n2); gr->line_plot(m1,m2); } gr->EndGroup(); } //--------------------------------------------------------- int main() { MyGraph gr; gr.Box(); // first let draw circles with fixed colors for(int i=0;i<10;i++) gr.CircleCF(mglPoint(2*mgl_rnd()-1, 2*mgl_rnd()-1), mgl_rnd()); // now let draw circles with color scheme for(int i=0;i<10;i++) gr.CircleCS(mglPoint(2*mgl_rnd()-1, 2*mgl_rnd()-1), 2*mgl_rnd()-1); } @end verbatim @c ------------------------------------------------------------------ @external{} @node mglDataA class, mglColor class, mglBase class, Other classes @section User defined types (mglDataA class) @nav{} @code{mglData} class have abstract predecessor class @code{mglDataA}. Exactly the pointers to @code{mglDataA} instances are used in all plotting functions and some of data processing functions. This was done for taking possibility to define yours own class, which will handle yours own data (for example, complex numbers, or differently organized data). And this new class will be almost the same as @code{mglData} for plotting purposes. However, the most of data processing functions will be slower as if you used @code{mglData} instance. This is more or less understandable -- I don't know how data in yours particular class will be organized, and couldn't optimize the these functions generally. There are few virtual functions which must be provided in derived classes. This functions give: @itemize @bullet @item the sizes of the data (@code{GetNx}, @code{GetNy}, @code{GetNz}), @item give data value and numerical derivatives for selected cell (@code{v}, @code{dvx}, @code{dvy}, @code{dvz}), @item give maximal and minimal values (@code{Maximal}, @code{Minimal}) -- you can use provided functions (like @code{mgl_data_max} and @code{mgl_data_min}), but yours own realization can be more efficient, @item give access to all element as in single array (@code{vthr}) -- you need this only if you want using MathGL's data processing functions. @end itemize Let me, for example define class @code{mglComplex} which will handle complex number and draw its amplitude or phase, depending on flag @var{use_abs}: @verbatim #include #include #define dual std::complex class mglComplex : public mglDataA { public: long nx; ///< number of points in 1st dimensions ('x' dimension) long ny; ///< number of points in 2nd dimensions ('y' dimension) long nz; ///< number of points in 3d dimensions ('z' dimension) dual *a; ///< data array bool use_abs; ///< flag to use abs() or arg() inline mglComplex(long xx=1,long yy=1,long zz=1) { a=0; use_abs=true; Create(xx,yy,zz); } virtual ~mglComplex() { if(a) delete []a; } /// Get sizes inline long GetNx() const { return nx; } inline long GetNy() const { return ny; } inline long GetNz() const { return nz; } /// Create or recreate the array with specified size and fill it by zero inline void Create(long mx,long my=1,long mz=1) { nx=mx; ny=my; nz=mz; if(a) delete []a; a = new dual[nx*ny*nz]; } /// Get maximal value of the data inline mreal Maximal() const { return mgl_data_max(this); } /// Get minimal value of the data inline mreal Minimal() const { return mgl_data_min(this); } protected: inline mreal v(long i,long j=0,long k=0) const { return use_abs ? abs(a[i+nx*(j+ny*k)]) : arg(a[i+nx*(j+ny*k)]); } inline mreal vthr(long i) const { return use_abs ? abs(a[i]) : arg(a[i]); } inline mreal dvx(long i,long j=0,long k=0) const { long i0=i+nx*(j+ny*k); std::complex res=i>0? (i res=j>0? (j res=k>0? (k}. There are two ways to set the color in MathGL. First one is using of mreal values of red, green and blue channels for precise color definition. The second way is the using of character id. There are a set of characters specifying frequently used colors. Normally capital letter gives more dark color than lowercase one. @xref{Line styles}. @deftypecv {Parameter} mglColor @code{mreal} {r, g, b, a} Reg, green and blue component of color. @end deftypecv @deftypemethod mglColor @code{} mglColor (@code{mreal} R, @code{mreal} G, @code{mreal} B, @code{mreal} A=@code{1}) Constructor sets the color by mreal values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1]. @end deftypemethod @deftypemethod mglColor @code{} mglColor (@code{char} c=@code{'k'}, @code{mreal} bright=@code{1}) Constructor sets the color from character id. The black color is used by default. Parameter @var{br} set additional ``lightness'' of color. @end deftypemethod @deftypemethod mglColor @code{void} Set (@code{mreal} R, @code{mreal} G, @code{mreal} B, @code{mreal} A=@code{1}) Sets color from values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1]. @end deftypemethod @deftypemethod mglColor @code{void} Set (@code{mglColor} c, @code{mreal} bright=@code{1}) Sets color as ``lighted'' version of color @var{c}. @end deftypemethod @deftypemethod mglColor @code{void} Set (@code{char} p, @code{mreal} bright=@code{1}) Sets color from symbolic id. @end deftypemethod @deftypemethod mglColor @code{bool} Valid () Checks correctness of the color. @end deftypemethod @deftypemethod mglColor @code{mreal} Norm () Gets maximal of spectral component. @end deftypemethod @deftypemethod mglColor @code{bool} operator== (@code{const mglColor &}c) @deftypemethodx mglColor @code{bool} operator!= (@code{const mglColor &}c) Compare with another color @end deftypemethod @deftypemethod mglColor @code{bool} operator*= (@code{mreal} v) Multiplies color components by number @var{v}. @end deftypemethod @deftypemethod mglColor @code{bool} operator+= (@code{const mglColor &}c) Adds color @var{c} component by component. @end deftypemethod @deftypemethod mglColor @code{bool} operator-= (@code{const mglColor &}c) Subtracts color @var{c} component by component. @end deftypemethod @deftypefn {Library Function} {mglColor} operator+ (@code{const mglColor &}a, @code{const mglColor &}b) Adds colors by its RGB values. @end deftypefn @deftypefn {Library Function} @code{mglColor} operator- (@code{const mglColor &}a, @code{const mglColor &}b) Subtracts colors by its RGB values. @end deftypefn @deftypefn {Library Function} @code{mglColor} operator* (@code{const mglColor &}a, @code{mreal} b) @deftypefnx {Library Function} @code{mglColor} operator* (@code{mreal} a, @code{const mglColor &}b) Multiplies color by number. @end deftypefn @deftypefn {Library Function} @code{mglColor} operator/ (@code{const mglColor &}a, @code{mreal} b) Divide color by number. @end deftypefn @deftypefn {Library Function} @code{mglColor} operator! (@code{const mglColor &}a) Return inverted color. @end deftypefn @c ------------------------------------------------------------------ @external{} @node mglPoint class, , mglColor class, Other classes @section mglPoint class @nav{} @cindex mglPoint Structure describes point in space. This structure is defined in @code{#include } @deftypecv {Parameter} mglPoint @code{mreal} {x, y, z, c} Point coordinates @{x,y,z@} and one extra value @var{c} used for amplitude, transparency and so on. By default all values are zero. @end deftypecv @deftypemethod mglPoint @code{} mglPoint (@code{mreal} X=@code{0}, @code{mreal} Y=@code{0}, @code{mreal} Z=@code{0}, @code{mreal} C=@code{0}) Constructor sets the color by mreal values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1]. @end deftypemethod @deftypemethod mglPoint @code{bool} IsNAN () Returns @code{true} if point contain NAN values. @end deftypemethod @deftypemethod mglPoint @code{mreal} norm () Returns the norm @math{\sqrt@{x^2+y^2+z^2@}} of vector. @end deftypemethod @deftypemethod mglPoint @code{void} Normalize () Normalizes vector to be unit vector. @end deftypemethod @deftypemethod mglPoint @code{mreal} val (@code{int} i) Returns point component: @var{x} for @var{i}=0, @var{y} for @var{i}=1, @var{z} for @var{i}=2, @var{c} for @var{i}=3. @end deftypemethod @deftypefn {Library Function} @code{mglPoint} operator+ (@code{const mglPoint &}a, @code{const mglPoint &}b) Point of summation (summation of vectors). @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator- (@code{const mglPoint &}a, @code{const mglPoint &}b) Point of difference (difference of vectors). @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator* (@code{mreal} a, @code{const mglPoint &}b) @deftypefnx {Library Function} @code{mglPoint} operator* (@code{const mglPoint &}a, @code{mreal} b) Multiplies (scale) points by number. @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator/ (@code{const mglPoint &}a, @code{mreal} b) Multiplies (scale) points by number 1/b. @end deftypefn @deftypefn {Library Function} @code{mreal} operator* (@code{const mglPoint &}a, @code{const mglPoint &}b) Scalar product of vectors. @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator/ (@code{const mglPoint &}a, @code{const mglPoint &}b) Return vector of element-by-element product. @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator^ (@code{const mglPoint &}a, @code{const mglPoint &}b) Cross-product of vectors. @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator& (@code{const mglPoint &}a, @code{const mglPoint &}b) The part of @var{a} which is perpendicular to vector @var{b}. @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator| (@code{const mglPoint &}a, @code{const mglPoint &}b) The part of @var{a} which is parallel to vector @var{b}. @end deftypefn @deftypefn {Library Function} @code{mglPoint} operator! (@code{const mglPoint &}a) Return vector perpendicular to vector @var{a}. @end deftypefn @deftypefn {Library Function} @code{mreal} mgl_norm (@code{const mglPoint &}a) Return the norm sqrt(|@var{a}|^2) of vector @var{a}. @end deftypefn @deftypefn {Library Function} @code{bool} operator== (@code{const mglPoint &}a, @code{const mglPoint &}b) Return true if points are the same. @end deftypefn @deftypefn {Library Function} @code{bool} operator!= (@code{const mglPoint &}a, @code{const mglPoint &}b) Return true if points are different. @end deftypefn @external{} mathgl-2.4.4/texinfo/overview_ru.texi0000644000175000017500000005362713513030041020105 0ustar alastairalastair@chapter Обзор MathGL @nav{} @cindex Обзор MathGL MathGL это ... @itemize @bullet @item библиотека для создания высококачественной научной графики под Linux и Windows; @item библиотека для быстрого обработки и отображения больших массивов данных; @item библиотека для работы в оконном и консольном режимах; @item библиотека с большим набором базовых типов графиков. @end itemize @menu * What is MathGL?:: * MathGL features:: * Installation:: * Quick guide:: * Changes from v.1:: * Utilities:: * Thanks:: @end menu @external{} @node What is MathGL?, MathGL features, , Overview @section Что такое MathGL? @nav{} Код для создания качественной научной графики на различных платформах. Код для быстрой обработки и отображения больших массивов данных. Код для работы в графическом и консольном режимах и легкого интегрирования в другие программы. Код с большим обновляемым набором графиков и инструментами обработки данных. Именно такого кода мне не хватало в последние годы при работе на персональных компьютерах и на кластерах. И именно такой код я постарался создать в библиотеке MathGL. На данный момент (версия @value{VERSION}) MathGL это более 50 основных типов графиков для одно-, двух- и трехмерных массивов, возможность экспорта в растровые и векторные (EPS или SVG) файлы, интерфейс для OpenGL и возможность запуска в консольном режиме, функции для обработки данных и даже простейший командный (интерпретируемый) язык MGL для упрощения построения графиков. Кроме того, есть несколько типов прозрачности, гладкое освещение, векторные шрифты, TeX-ие команды в надписях, произвольные криволинейные системы координат и прочие полезные мелочи (см. раздел pictures на @uref{http://mathgl.sf.net/, домашней странице}). Ну, и, естественно, полная переносимость библиотеки и ее свободное распространение под лицензией GPL v.2.0 или более поздней. @external{} @node MathGL features, Installation, What is MathGL?, Overview @section Возможности MathGL @nav{} Библиотека MathGL позволяет строить широкий класс графиков, включая: @itemize @bullet @item рисование одномерных массивов (Plot, Area, Bars, Step, Stem, Torus, Chart, Error, Tube, Mark, @pxref{1D plotting}); @item рисование двумерных массивов (Mesh, Surf, Dens, Cont, ContF, Boxs, Axial, Fall, Belt, Tile, @pxref{2D plotting}); @item рисование трехмерных массивов (Surf3, Dens3, Cont3, ContF3, Cloud-like, @pxref{3D plotting}); @item рисование нескольких связанных массивов: векторные поля Vect, линии тока Flow, точечное отображение Map, поверхности с прозрачностью или цветом, определяемым другим массивом SurfA, SurfC, Surf3A, Surf3C (@pxref{Dual plotting}); @item и другие (см. @pxref{MathGL core}). @end itemize Фактически, я постарался реализовать все известные мне типы научных графиков. Список графиков постоянно пополняется, и если Вам нужен какой-то новый вариант, пишите на @email{mathgl.abalakin@@gmail.com, e-mail}, и в новой версии библиотеки этот график появится. Я постарался сделать графики максимально красивыми -- поверхности могут быть прозрачными и освещены произвольно расположенными источниками света (максимальное их количество 10). Большинство функций рисования имеет два варианта: простой для быстрого построения картинки и более сложный для детальной настройки отображения, включающего в том числе возможность параметрического задания всех массивов. Получившееся изображение можно сохранить в растровом формате PNG, JPEG, GIF, TGA или BMP; в векторном EPS, SVG или TeX формате, или в 3D формате OBJ, OFF, STL, или в PRC формате, который может быть конвертирован U3D. Все надписи выводятся векторным шрифтом, что обеспечивает их хорошую масштабируемость и переносимость. Текст может содержать команды для большинства ТеХ-их символов, изменения положения (верхний и нижний индексы) и стиля шрифта внутри строки текста (@pxref{Font styles}). Текст меток поворачивается вместе с осями. На график можно вывести описание кривых (легенду) и поместить надпись в произвольную точку экрана или пустить ее вдоль кривой. Поддерживаются произвольные кодировки текста (с помощью стандартной функции @code{setlocale()}) и текст в кодировке UTF-16. Для представления данных используется специальный класс mglData (@pxref{Data processing}). Помимо безопасного создания и удаления массивов, он включает функции по их обработке (дифференцированию, интегрированию, сглаживанию, интерполяции и т.д.) и чтению текстового файла с автоматическим определением размеров данных. Класс mglData позволяет работать с массивами размерности вплоть до 3 (массивы, зависящие от трех независимых индексов @math{a_@{ijk@}}). Использование массивов с большим числом размерностей нецелесообразно, поскольку я не представляю, как их можно отобразить на экране. Заполнение или изменение значений массива можно выполнить как вручную, так и по формуле, заданной текстовой строкой. Для @emph{быстрого} вычисления значения выражения, заданного текстовой строкой (@pxref{Textual formulas}). Он основан на компиляции строки в древоподобную структуру при создании экземпляра класса. На этапе вычисления происходит быстрый обход дерева с выдачей результата для конкретных значений переменных. Помимо изменения значений массива данных, текстовые формулы используются для рисования в @emph{произвольной} криволинейной системе координат. Набор таких координат ограничивается только фантазией пользователя, а не фиксированным числом (типа полярной, параболической, цилиндрической и т.д.). @external{} @node Installation, Quick guide, MathGL features, Overview @section Установка MathGL @nav{} Установка библиотеки возможна 4-мя способами. @enumerate @item Скомпилировать библиотеку непосредственно из исходных файлов. С библиотекой поставляется файлы для системы сборки CMake. Для его запуска достаточно в командной строке выполнить 3 команды: сначала @code{cmake .} дважды, далее @code{make} и, наконец, с правами суперпользователя @code{make install}. Иногда после компиляции библиотеки может потребоваться обновление списка библиотека в системе -- выполните команду @code{ldconfig} с правами суперпользователя. Есть несколько дополнительных опций, которые по умолчанию отключены. К их числу относятся: @code{enable-fltk, enable-glut, enable-qt4, enable-qt5} для поддержки FLTK, GLUT и/или Qt окон; @code{enable-jpeg, enable-gif, enable-hdf5} для поддержки соответствующих форматов; @code{enable-all} для включения всех возможностей. Для использования типа @code{double} для внутреннего хранения данных используйте опцию @code{enable-double}. Для создания интерфейсов к другим языкам (кроме С/Фортран/MGL) используйте опции @code{enable-python, enable-octave} или @code{enable-all-swig} для всех поддерживаемых языков. Вы можете воспользоваться WYSIWYG утилитой (@code{cmake-gui}) для просмотра и изменения всех опций, или выполнить @code{cmake -D enable-all=on -D enable-all-widgets=on -D enable-all-swig=on .} в командной строке для включения всех опций. При сборке с помощью MinGW необходимо дополнительно установить опцию сборки @code{-fopenmp} (т.е. @code{CMAKE_EXE_LINKER_FLAGS:STRING='-fopenmp'} и @code{CMAKE_SHARED_LINKER_FLAGS:STRING='-fopenmp'}) если включена поддержка OpenMP (@code{enable-openmp=ON}). @item Использовать предварительно скомпилированные файлы -- с библиотекой поставляются файлы для MinGW (платформа Win32). В скомпилированной версии достаточно распаковать заголовочные файлы в папку с заголовочными файлами и библиотеку libmgl.a в папку с библиотеками. По умолчанию, скомпилированная версия включают поддержку GSL (www.gsl.org), PNG, GIF и JPEG. Соответственно, при сборке программы эти библиотеки должны быть установлены (их можно найти на @uref{http://gnuwin32.sourceforge.net/packages.html}). @item Установить из стандартных пакетов (RPM, deb, DevPak и пр.). @end enumerate Последнюю версию (которая может быть не стабильна) можно загрузить с sourceforge.net SVN с помощью команды @verbatim svn checkout http://svn.code.sf.net/p/mathgl/code/mathgl-2x mathgl-code @end verbatim @strong{ВАЖНО!} MathGL использует набор defines, определяемых на этапе конфигурирования библиотеки. Это @code{MGL_SYS_NAN, MGL_HAVE_TYPEOF, MGL_HAVE_PTHREAD, MGL_HAVE_ATTRIBUTE, MGL_HAVE_C99_COMPLEX, MGL_HAVE_RVAL}. Они могут отличаться при использовании бинарников скомпилированных другим компилятором (например при использовании скомпилированных MinGW бинарников в VisualStudio). Я специально устанавливаю их в @code{0} для компиляторов Borland и Microsoft из соображений совместимости. Кроме того, настройки по умолчанию подходят для компиляторов GNU (gcc, mingw) и clang. Однако, для прочих компиляторов может потребоваться ручная установка defines в @code{0} в файле @code{include/mgl2/config.h} если вы используете предварительно скомпилированные файлы. @c TODO Translate it! @c ------------------------------------------------------------------ @external{} @node Quick guide, Changes from v.1, Installation, Overview @section Quick guide @nav{} There are 3 steps to prepare the plot in MathGL: (1) prepare data to be plotted, (2) setup plot, (3) plot data. Let me show this on the example of surface plotting. First we need the data. MathGL use its own class @code{mglData} to handle data arrays (see @ref{Data processing}). This class give ability to handle data arrays by more or less format independent way. So, create it @verbatim int main() { mglData dat(30,40); // data to for plotting for(long i=0;i<30;i++) for(long j=0;j<40;j++) dat.a[i+30*j] = 1/(1+(i-15)*(i-15)/225.+(j-20)*(j-20)/400.); @end verbatim Here I create matrix 30*40 and initialize it by formula. Note, that I use @code{long} type for indexes @var{i}, @var{j} because data arrays can be really large and @code{long} type will automatically provide proper indexing. Next step is setup of the plot. The only setup I need is axis rotation and lighting. @verbatim mglGraph gr; // class for plot drawing gr.Rotate(50,60); // rotate axis gr.Light(true); // enable lighting @end verbatim Everything is ready. And surface can be plotted. @verbatim gr.Surf(dat); // plot surface @end verbatim Basically plot is done. But I decide to add yellow (@samp{y} color, see @ref{Color styles}) contour lines on the surface. To do it I can just add: @verbatim gr.Cont(dat,"y"); // plot yellow contour lines @end verbatim This demonstrate one of base MathGL concept (see, @ref{General concepts}) -- ``new drawing never clears things drawn already''. So, you can just consequently call different plotting functions to obtain ``combined'' plot. For example, if one need to draw axis then he can just call one more plotting function @verbatim gr.Axis(); // draw axis @end verbatim Now picture is ready and we can save it in a file. @verbatim gr.WriteFrame("sample.png"); // save it } @end verbatim To compile your program, you need to specify the linker option @code{-lmgl}. This is enough for a compilation of console program or with external (non-MathGL) window library. If you want to use FLTK or Qt windows provided by MathGL then you need to add the option @code{-lmgl-wnd}. При использовании фортрана необходимо также включить библиотеку @code{-lstdc++}. Кроме того, если библиотека была собрана с опцией @code{enable-double=ON} (по умолчанию в версии 2.1 и более поздних), то все вещественные числа должны быть типа real*8. Это можно включить по умолчанию опцией @code{-fdefault-real-8}. @c ------------------------------------------------------------------ @external{} @node Changes from v.1, Utilities, Quick guide, Overview @section Changes from v.1.* @nav{} There are a lot of changes for v.2. Here I denote only main of them. @itemize @bullet @item mglGraph class is single plotter class instead of mglGraphZB, mglGraphPS and so on. @item Text style and text color positions are swapped. I.e. text style @samp{r:C} give red centered text, but not roman dark cyan text as for v.1.*. @item ColumnPlot() indexing is reverted. @item Move most of arguments of plotting functions into the string parameter and/or options. @item ``Bright'' colors (like @{b8@}) can be used in color schemes and line styles. @item Intensively use pthread internally for parallelization of drawing and data processing. @item Add tick labels rotation and skipping. Add ticks in time/date format. @item New kinds of plots (Tape(), Label(), Cones(), ContV()). Extend existing plots. New primitives (Circle(), Ellipse(), Rhomb(), ...). New plot positioning (MultiPlot(), GridPlot()) @item Improve MGL scripts. Add 'ask' command and allow string concatenation from different lines. @item Export to LaTeX and to 3D formats (OBJ, OFF, STL). @item Add pipes support in utilities (@code{mglconv, mglview}). @end itemize @c ------------------------------------------------------------------ @external{} @node Utilities, Thanks, Changes from v.1, Overview @section Utilities for parsing MGL @nav{} MathGL library provides several tools for parsing MGL scripts. There is tools saving it to bitmap or vectorial images (@code{mglconv}). Tool @code{mglview} show MGL script and allow to rotate and setup the image. Another feature of @code{mglview} is loading *.mgld files (see @code{ExportMGLD()}) for quick viewing 3d pictures. Both tools have similar set of arguments. They can be name of script file or options. You can use @samp{-} as script name for using standard input (i.e. pipes). Options are: @itemize @item @strong{-1} @var{str} set @var{str} as argument $1 for script; @item ... ... @item @strong{-9} @var{str} set @var{str} as argument $9 for script; @item @strong{-L} @var{loc} set locale to @var{loc}; @item @strong{-s} @var{fname} set MGL script for setting up the plot; @item @strong{-h} print help message. @end itemize Additionally @code{mglconv} have following options: @itemize @item @strong{-A} @var{val} add @var{val} into the list of animation parameters; @item @strong{-C} @var{v1}:@var{v2}[:@var{dv}] add values from @var{v1} ot @var{v2} with step @var{dv} (default is 1) into the list of animation parameters; @item @strong{-o} @var{name} set output file name; @item @strong{-n} disable default output (script should save results by itself); @item @strong{-S} @var{val} set set scaling factor for @ref{setsize}; @item @strong{-q} @var{val} set @ref{quality} for output (val=0...9). @end itemize Also you can create animated GIF file or a set of JPEG files with names @samp{frameNNNN.jpg} (here @samp{NNNN} is frame index). Values of the parameter @code{$0} for making animation can be specified inside the script by comment @code{##a val} for each value @code{val} (one comment for one value) or by option(s) @samp{-A val}. Also you can specify a cycle for animation by comment @code{##c v1 v2 dv} or by option @code{-C v1:v2:dv}. In the case of found/specified animation parameters, tool will execute script several times -- once for each value of @code{$0}. MathGL also provide another simple tool @code{mgl.cgi} which parse MGL script from CGI request and send back produced PNG file. Usually this program should be placed in @code{/usr/lib/cgi-bin/}. But you need to put this program by yourself due to possible security issues and difference of Apache server settings. @c ------------------------------------------------------------------ @external{} @node Thanks, , Utilities, Overview @section Благодарности @nav{} @itemize @bullet @item Моя специальная благодарность моей жене за терпение во время написания библиотеки. @item Я благодарен моим соавторам Д. Кулагину и М. Видассову за помощь в разработке MathGL. @item Я благодарен Diego Sejas Viscarra за разработку mgltex, вклад в генерацию фракталов и продуктивные предложения и обсуждения. @item Я благодарен D. Eftaxiopoulos, D. Haley, В. Липатову и С. Плису за создание бинарных пакетов для Linux. @item Я благодарен С. Скобелеву, К. Михайленко, М. Вейсману, A. Прохорову, A. Короткевичу, В. Онучину, С. Плису, Р. Киселеву, A. Иванову, Н. Троицкому and В. Липатову за продуктивные предложения и обсуждения. @item Я благодарен спонсорам М. Вейсману (@url{http://www.jiht.ru/about/structure.php?set_filter_structure=Y&structure_UF_DEPARTMENT=241&filter=Y&set_filter=Y, ОИВТ РАН}) и A. Прохорову (@url{www.datadvance.net, DATADVANCE}). @end itemize Javascript интерфейс был разработан при поддержке компании @url{www.datadvance.net, DATADVANCE}. @external{} mathgl-2.4.4/texinfo/appendix_ru.texi0000644000175000017500000010455613513030041020045 0ustar alastairalastair@nav{} Ниже приведен полный список TeX-их команд, распознаваемых MathGL. Если команда была не распознана, то она будет напечатана как есть с пропущенным символом @samp{\}. Например, @samp{\#} выдаст ``#'', @samp{\\} выдаст ``\'', @samp{\qq} выдаст ``qq''. @strong{Положение символов}: _, ^, @@. @strong{Стиль текста}: \big, \b, \textbf, \i, \textit, \bi, \r, \textrm, \a, \overline, \u, \underline, \w, \wire, #, \color[wkrgbcymhRGBCYMHWlenupqLENUPQ] @strong{Корни}: \sqrt, \sqrt3, \sqrt4 @strong{Дроби}: \frac, \dfrac, \stack, \overset, \underset, \stackr, \stackl @strong{Акценты}: \hat, \tilde, \dot, \ddot, \dddot, \ddddot, \acute, \check, \grave, \vec, \bar, \breve @strong{Специальные символы}: \# (#), \% (%), \& (&), \^ (^). \AA (Å), \AE (Æ), \APLboxquestion (⍰), \APLboxupcaret (⍓), \APLnotbackslash (⍀), \APLnotslash (⌿), \Alpha (Α), \And (&), \Angstrom (Å), \Barv (⫧), \BbbC (ℂ), \BbbGamma (ℾ), \BbbH (ℍ), \BbbN (ℕ), \BbbP (ℙ), \BbbPi (ℿ), \BbbQ (ℚ), \BbbR (ℝ), \BbbZ (ℤ), \Bbbgamma (ℽ), \Bbbpi (ℼ), \Bbbsum (⅀), \Beta (Β), \Bumpeq (≎), \Cap (⋒), \Chi (Χ), \Colon (∷), \Coloneq (⩴), \Cup (⋓), \DDownarrow (⟱), \DH (Ð), \DJ (Đ), \DashV (⫥), \DashVDash (⟚), \Dashv (⫤), \Ddownarrow (⤋), \Delta (Δ), \Digamma (Ϝ), \Doteq (≑), \Downarrow (⇓), \Epsilon (Ε), \Equiv (≣), \Eta (Η), \Eulerconst (ℇ), \Exclam (‼), \Finv (Ⅎ), \Game (⅁), \Gamma (Γ), \Gt (⪢), \Hermaphrodite (⚥), \Im (ℑ), \Iota (Ι), \Kappa (Κ), \Koppa (Ϟ), \L (Ł), \LLeftarrow (⭅), \Lambda (Λ), \Lbrbrak (⟬), \Ldsh (↲), \Leftarrow (⇐), \Leftrightarrow (⇔), \Lleftarrow (⇚), \Longleftarrow (⟸), \Longleftrightarrow (⟺), \Longmapsfrom (⟽), \Longmapsto (⟾), \Longrightarrow (⟹), \Lparengtr (⦕), \Lsh (↰), \Lt (⪡), \Lvzigzag (⧚), \Mapsfrom (⤆), \Mapsto (⤇), \Mu (Μ), \NG (Ŋ), \Nearrow (⇗), \Not (⫬), \Nu (Ν), \Nwarrow (⇖), \O (Ø), \OE (Œ), \Ohorn (Ơ), \Omega (Ω), \Omicron (Ο), \Otimes (⨷), \P (¶), \Phi (Φ), \Pi (Π), \Planckconst (ℎ), \Prec (⪻), \PropertyLine (⅊), \Psi (Ψ), \QED (∎), \Question (⁇), \RRightarrow (⭆), \Rbrbrak (⟭), \Rdsh (↳), \Re (ℜ), \Rho (Ρ), \Rightarrow (⇒), \Rparenless (⦖), \Rrightarrow (⇛), \Rsh (↱), \Rvzigzag (⧛), \S (§), \Sc (⪼), \Searrow (⇘), \Sigma (Σ), \Sqcap (⩎), \Sqcup (⩏), \Stigma (Ϛ), \Subset (⋐), \Supset (⋑), \Swarrow (⇙), \TH (Þ), \Tau (Τ), \Theta (Θ), \UUparrow (⟰), \Uhorn (Ư), \Uparrow (⇑), \Updownarrow (⇕), \Uuparrow (⤊), \VDash (⊫), \Vbar (⫫), \Vdash (⊩), \Vee (⩔), \Vert (‖), \Vvdash (⊪), \Vvert (⦀), \Wedge (⩓), \XBox (☒), \Xi (Ξ), \Yup (⅄), \Zbar (Ƶ), \Zeta (Ζ). \aa (å), \ac (∾), \accurrent (⏦), \acidfree (♾), \acwcirclearrow (⥀), \acwgapcirclearrow (⟲), \acwleftarcarrow (⤹), \acwopencirclearrow (↺), \acwoverarcarrow (⤺), \acwundercurvearrow (⤻), \adots (⋰), \ae (æ), \aleph (ℵ), \alpha (α), \amalg (⨿), \angdnr (⦟), \angle (∠), \angles (⦞), \angleubar (⦤), \approx (≈), \approxeq (≊), \approxeqq (⩰), \approxident (≋), \arceq (≘), \aries (♈), \assert (⊦), \ast (∗), \asteq (⩮), \astrosun (☉), \asymp (≍), \awint (⨑). \bNot (⫭), \backcong (≌), \backdprime (‶), \backepsilon (϶), \backprime (‵), \backsim (∽), \backsimeq (⋍), \backslash (\), \backtrprime (‷), \bagmember (⋿), \barV (⫪), \barcap (⩃), \barcup (⩂), \bardownharpoonleft (⥡), \bardownharpoonright (⥝), \barleftarrow (⇤), \barleftarrowrightarrowbar (↹), \barleftharpoondown (⥖), \barleftharpoonup (⥒), \barovernorthwestarrow (↸), \barrightarrowdiamond (⤠), \barrightharpoondown (⥟), \barrightharpoonup (⥛), \baruparrow (⤒), \barupharpoonleft (⥘), \barupharpoonright (⥔), \barvee (⊽), \barwedge (⊼), \bbrktbrk (⎶), \bdHrule (═), \bdVrule (║), \bdbVbH (╬), \bdbVbh (╫), \bdbVlH (╣), \bdbVlh (╢), \bdbVrH (╠), \bdbVrh (╟), \bdbvbH (╪), \bdbvbh (┼), \bdbvlH (╡), \bdbvlh (┤), \bdbvrH (╞), \bdbvrh (├), \bddVbH (╦), \bddVbh (╥), \bddVlH (╗), \bddVlh (╖), \bddVrH (╔), \bddVrh (╓), \bddvbH (╤), \bddvbh (┬), \bddvlH (╕), \bddvlh (┐), \bddvrH (╒), \bddvrh (┌), \bdhrule (─), \bdnesw (╱), \bdnwse (╲), \bdquadhdash (┈), \bdquadvdash (┊), \bdtriplevdash (┆), \bduVbH (╩), \bduVbh (╨), \bduVlH (╝), \bduVlh (╜), \bduVrH (╚), \bduVrh (╙), \bduvbH (╧), \bduvbh (┴), \bduvlH (╛), \bduvlh (┘), \bduvrH (╘), \bduvrh (└), \bdvrule (│), \because (∵), \benzenr (⏣), \beta (β), \beth (ℶ), \between (≬), \bigblacktriangledown (▼), \bigblacktriangleup (▲), \bigbot (⟘), \bigcap (⋂), \bigcup (⋃), \bigslopedvee (⩗), \bigslopedwedge (⩘), \bigstar (★), \bigtop (⟙), \bigtriangledown (▽), \bigtriangleup (△), \bigvee (⋁), \bigwedge (⋀), \bigwhitestar (☆), \blackcircledownarrow (⧭), \blackcircledrightdot (⚈), \blackcircledsanseight (➑), \blackcircledsansfive (➎), \blackcircledsansfour (➍), \blackcircledsansnine (➒), \blackcircledsansone (➊), \blackcircledsansseven (➐), \blackcircledsanssix (➏), \blackcircledsansten (➓), \blackcircledsansthree (➌), \blackcircledsanstwo (➋), \blackcircledtwodots (⚉), \blackcircleulquadwhite (◕), \blackdiamonddownarrow (⧪), \blackhourglass (⧗), \blackinwhitediamond (◈), \blackinwhitesquare (▣), \blacklefthalfcircle (◖), \blackpointerleft (◄), \blackpointerright (►), \blackrighthalfcircle (◗), \blacksmiley (☻), \blacktriangle (▴), \blacktriangledown (▾), \blacktriangleleft (◀), \blacktriangleright (▶), \blkhorzoval (⬬), \blkvertoval (⬮), \blockfull (█), \blockhalfshaded (▒), \blocklefthalf (▌), \blocklowhalf (▄), \blockqtrshaded (░), \blockrighthalf (▐), \blockthreeqtrshaded (▓), \blockuphalf (▀), \bot (⊥), \botsemicircle (◡), \bowtie (⋈), \box (◻), \boxast (⧆), \boxbar (◫), \boxbox (⧈), \boxbslash (⧅), \boxcircle (⧇), \boxdiag (⧄), \boxdot (⊡), \boxminus (⊟), \boxonbox (⧉), \boxplus (⊞), \boxtimes (⊠), \bsimilarleftarrow (⭁), \bsimilarrightarrow (⭇), \bsolhsub (⟈), \btimes (⨲), \bullet (∙), \bullseye (◎), \bumpeq (≏), \bumpeqq (⪮). \calB (ℬ), \calE (ℰ), \calF (ℱ), \calH (ℋ), \calM (ℳ), \calR (ℛ), \cap (∩), \capdot (⩀), \capwedge (⩄), \caretinsert (‸), \carreturn (⏎), \carriagereturn (↵), \ccwundercurvearrow (⤿), \cdot (⋅), \cdotp (·), \cdots (⋯), \cdprime (ʺ), \checkmark (✓), \chi (χ), \cirE (⧃), \cirbot (⟟), \circ (∘), \circeq (≗), \circfint (⨐), \circlebottomhalfblack (◒), \circledA (Ⓐ), \circledB (Ⓑ), \circledC (Ⓒ), \circledD (Ⓓ), \circledE (Ⓔ), \circledF (Ⓕ), \circledG (Ⓖ), \circledH (Ⓗ), \circledI (Ⓘ), \circledJ (Ⓙ), \circledK (Ⓚ), \circledL (Ⓛ), \circledM (Ⓜ), \circledN (Ⓝ), \circledO (Ⓞ), \circledP (Ⓟ), \circledQ (Ⓠ), \circledR (Ⓡ), \circledS (Ⓢ), \circledT (Ⓣ), \circledU (Ⓤ), \circledV (Ⓥ), \circledW (Ⓦ), \circledX (Ⓧ), \circledY (Ⓨ), \circledZ (Ⓩ), \circleda (ⓐ), \circledast (⊛), \circledb (ⓑ), \circledbullet (⦿), \circledc (ⓒ), \circledcirc (⊚), \circledd (ⓓ), \circleddash (⊝), \circlede (ⓔ), \circledeight (⑧), \circledequal (⊜), \circledf (ⓕ), \circledfive (⑤), \circledfour (④), \circledg (ⓖ), \circledh (ⓗ), \circledi (ⓘ), \circledj (ⓙ), \circledk (ⓚ), \circledl (ⓛ), \circledm (ⓜ), \circledn (ⓝ), \circlednine (⑨), \circledo (ⓞ), \circledone (①), \circledownarrow (⧬), \circledp (ⓟ), \circledparallel (⦷), \circledq (ⓠ), \circledr (ⓡ), \circledrightdot (⚆), \circleds (ⓢ), \circledsanseight (➇), \circledsansfive (➄), \circledsansfour (➃), \circledsansnine (➈), \circledsansone (➀), \circledsansseven (➆), \circledsanssix (➅), \circledsansten (➉), \circledsansthree (➂), \circledsanstwo (➁), \circledseven (⑦), \circledsix (⑥), \circledstar (✪), \circledt (ⓣ), \circledthree (③), \circledtwo (②), \circledtwodots (⚇), \circledu (ⓤ), \circledv (ⓥ), \circledvert (⦶), \circledw (ⓦ), \circledwhitebullet (⦾), \circledx (ⓧ), \circledy (ⓨ), \circledz (ⓩ), \circledzero (⓪), \circlehbar (⦵), \circlelefthalfblack (◐), \circlellquad (◵), \circlelrquad (◶), \circleonleftarrow (⬰), \circleonrightarrow (⇴), \circlerighthalfblack (◑), \circletophalfblack (◓), \circleulquad (◴), \circleurquad (◷), \circleurquadblack (◔), \circlevertfill (◍), \cirmid (⫯), \cirscir (⧂), \clangle (〈), \closedvarcap (⩍), \closedvarcup (⩌), \closedvarcupsmashprod (⩐), \closure (⁐), \cloverleaf (⌘), \clubsuit (♣), \colon (:), \colon (∶), \coloneq (≔), \commaminus (⨩), \complement (∁), \concavediamond (⟡), \concavediamondtickleft (⟢), \concavediamondtickright (⟣), \cong (≅), \congdot (⩭), \conictaper (⌲), \conjunction (☌), \coprod (∐), \cprime (ʹ), \crangle (〉), \csub (⫏), \csube (⫑), \csup (⫐), \csupe (⫒), \cuberoot (∛), \cup (∪), \cupdot (⊍), \cupleftarrow (⊌), \cupvee (⩅), \curlyeqprec (⋞), \curlyeqsucc (⋟), \curlyvee (⋎), \curlywedge (⋏), \curvearrowleft (↶), \curvearrowleftplus (⤽), \curvearrowright (↷), \curvearrowrightminus (⤼), \cwcirclearrow (⥁), \cwgapcirclearrow (⟳), \cwopencirclearrow (↻), \cwrightarcarrow (⤸), \cwundercurvearrow (⤾), \cylcty (⌭). \dag (†), \dagger (†), \daleth (ℸ), \danger (☡), \dashV (⫣), \dashVdash (⟛), \dashcolon (∹), \dashleftharpoondown (⥫), \dashrightharpoondown (⥭), \dashv (⊣), \dbkarow (⤏), \ddag (‡), \ddagger (‡), \ddots (⋱), \ddotseq (⩷), \delta (δ), \dh (ð), \diameter (⌀), \diamond (◇), \diamondbotblack (⬙), \diamondcdot (⟐), \diamondleftarrow (⤝), \diamondleftarrowbar (⤟), \diamondleftblack (⬖), \diamondrightblack (⬗), \diamondsuit (♢), \diamondtopblack (⬘), \dicei (⚀), \diceii (⚁), \diceiii (⚂), \diceiv (⚃), \dicev (⚄), \dicevi (⚅), \digamma (ϝ), \dingasterisk (✽), \dircurrent (⎓), \disin (⋲), \div (÷), \divideontimes (⋇), \dj (đ), \dlcrop (⌍), \doteq (≐), \dotequiv (⩧), \dotminus (∸), \dotplus (∔), \dots (…), \dotsim (⩪), \dotsminusdots (∺), \dottedcircle (◌), \dottedsquare (⬚), \dottimes (⨰), \doublebarvee (⩢), \doublebarwedge (⩞), \doubleplus (⧺), \downarrow (↓), \downarrowbar (⤓), \downarrowbarred (⤈), \downdasharrow (⇣), \downdownarrows (⇊), \downfishtail (⥿), \downharpoonleft (⇃), \downharpoonleftbar (⥙), \downharpoonright (⇂), \downharpoonrightbar (⥕), \downharpoonsleftright (⥥), \downrightcurvedarrow (⤵), \downtriangleleftblack (⧨), \downtrianglerightblack (⧩), \downuparrows (⇵), \downupharpoonsleftright (⥯), \downwhitearrow (⇩), \downzigzagarrow (↯), \dprime (″), \draftingarrow (➛), \drbkarow (⤐), \drcrop (⌌), \dsol (⧶), \dsub (⩤), \dualmap (⧟). \earth (♁), \egsdot (⪘), \eighthnote (♪), \elinters (⏧), \ell (ℓ), \elsdot (⪗), \emdash (—), \emptyset (∅), \emptysetoarr (⦳), \emptysetoarrl (⦴), \emptysetobar (⦱), \emptysetocirc (⦲), \endash (–), \enleadertwodots (‥), \envelope (✉), \eparsl (⧣), \epsilon (ϵ), \eqcirc (≖), \eqcolon (≕), \eqdef (≝), \eqdot (⩦), \eqeq (⩵), \eqeqeq (⩶), \eqgtr (⋝), \eqless (⋜), \eqqgtr (⪚), \eqqless (⪙), \eqqplus (⩱), \eqqsim (⩳), \eqqslantgtr (⪜), \eqqslantless (⪛), \eqsim (≂), \eqslantgtr (⪖), \eqslantless (⪕), \equalleftarrow (⭀), \equalparallel (⋕), \equalrightarrow (⥱), \equiv (≡), \equivDD (⩸), \equivVert (⩨), \equivVvert (⩩), \eqvparsl (⧥), \errbarblackcircle (⧳), \errbarblackdiamond (⧱), \errbarblacksquare (⧯), \errbarcircle (⧲), \errbardiamond (⧰), \errbarsquare (⧮), \eta (η), \euro (€), \exists (∃). \fallingdotseq (≒), \fbowtie (⧓), \fcmp (⨾), \fdiagovnearrow (⤯), \fdiagovrdiag (⤬), \female (♀), \figdash (‒), \fint (⨏), \fisheye (◉), \flat (♭), \fltns (⏥), \forall (∀), \forks (⫝̸), \forksnot (⫝), \forkv (⫙), \fourthroot (∜), \fourvdots (⦙), \fracfiveeighths (⅝), \fracfivesixths (⅚), \fracfourfifths (⅘), \fraconeeighth (⅛), \fraconefifth (⅕), \fraconesixth (⅙), \fraconethird (⅓), \fracseveneights (⅞), \fracslash (⁄), \fracthreeeighths (⅜), \fracthreefifths (⅗), \fractwofifths (⅖), \fractwothirds (⅔), \frakC (ℭ), \frakH (ℌ), \frakZ (ℨ), \frown (⌢), \frownie (☹), \fullouterjoin (⟗). \gamma (γ), \ge (≥), \geq (≥), \geqq (≧), \geqslant (⩾), \gescc (⪩), \gesdot (⪀), \gesdoto (⪂), \gesdotol (⪄), \gesles (⪔), \gets (←), \gg (≫), \ggg (⋙), \gggnest (⫸), \gimel (ℷ), \glE (⪒), \gla (⪥), \gleichstark (⧦), \glj (⪤), \gnapprox (⪊), \gneq (⪈), \gneqq (≩), \gnsim (⋧), \greater (>), \gsime (⪎), \gsiml (⪐), \gtcc (⪧), \gtcir (⩺), \gtlpar (⦠), \gtquest (⩼), \gtrapprox (⪆), \gtrarr (⥸), \gtrdot (⋗), \gtreqless (⋛), \gtreqqless (⪌), \gtrless (≷), \gtrsim (≳), \guillemotleft («), \guillemotright (»), \guilsinglleft (‹), \guilsinglright (›). \harrowextender (⎯), \hatapprox (⩯), \hbar (ℏ), \heartsuit (♡), \hermitmatrix (⊹), \hexagon (⎔), \hexagonblack (⬣), \hiraganano (の), \hknearrow (⤤), \hknwarrow (⤣), \hksearow (⤥), \hkswarow (⤦), \hookleftarrow (↩), \hookrightarrow (↪), \horizbar (―), \hourglass (⧖), \house (⌂), \hrectangle (▭), \hrectangleblack (▬), \hslash (ℏ), \hyphenbullet (⁃), \hzigzag (〰). \iiiint (⨌), \iiint (∭), \iinfin (⧜), \iint (∬), \imageof (⊷), \in (∈), \incare (℅), \increment (∆), \infty (∞), \int (∫), \intBar (⨎), \intbar (⨍), \intbottom (⌡), \intcap (⨙), \intclockwise (∱), \intcup (⨚), \intercal (⊺), \interleave (⫴), \intextender (⎮), \intlharhk (⨗), \intprod (⨼), \intprodr (⨽), \inttop (⌠), \intx (⨘), \inversebullet (◘), \inversewhitecircle (◙), \invnot (⌐), \invwhitelowerhalfcircle (◛), \invwhiteupperhalfcircle (◚), \iota (ι), \ipasupgamma (ˠ), \ipasupl (ˡ), \ipasuprerglotstpp (ˤ), \ipasups (ˢ), \ipasupx (ˣ), \ipaunaspirated (˭), \ipavoicing (ˬ), \isinE (⋹), \isindot (⋵), \isinobar (⋷), \isins (⋴), \isinvb (⋸), \itBbbD (ⅅ), \itBbbd (ⅆ), \itBbbe (ⅇ), \itBbbi (ⅈ), \itBbbj (ⅉ). \jupiter (♃), \kappa (κ), \kernelcontraction (∻), \koppa (ϟ). \l (ł), \lAngle (⟪), \lBrace (⦃), \lBrack (⟦), \lParen (⦅), \lambda (λ), \lambdabar (ƛ), \langle (⟨), \langledot (⦑), \laplac (⧠), \lasp (ʽ), \lat (⪫), \late (⪭), \lbag (⟅), \lblkbrbrak (⦗), \lbrace (@{), \lbracelend (⎩), \lbracemid (⎨), \lbraceuend (⎧), \lbrack ([), \lbrackextender (⎢), \lbracklend (⎣), \lbracklltick (⦏), \lbrackubar (⦋), \lbrackuend (⎡), \lbrackultick (⦍), \lbrbrak (❲), \lceil (⌈), \lcurvyangle (⧼), \ldasharrhead (⇠), \le (≤), \leadsto (↝), \leftarrow (←), \leftarrowapprox (⭊), \leftarrowbackapprox (⭂), \leftarrowbsimilar (⭋), \leftarrowless (⥷), \leftarrowonoplus (⬲), \leftarrowplus (⥆), \leftarrowshortrightarrow (⥃), \leftarrowsimilar (⥳), \leftarrowsubset (⥺), \leftarrowtail (↢), \leftarrowtriangle (⇽), \leftarrowx (⬾), \leftbkarrow (⤌), \leftcurvedarrow (⬿), \leftdasharrow (⇠), \leftdasharrowhead (⇡), \leftdbkarrow (⤎), \leftdbltail (⤛), \leftdotarrow (⬸), \leftdowncurvedarrow (⤶), \leftfishtail (⥼), \leftharpoondown (↽), \leftharpoondownbar (⥞), \leftharpoonsupdown (⥢), \leftharpoonup (↼), \leftharpoonupbar (⥚), \leftharpoonupdash (⥪), \leftleftarrows (⇇), \leftmoon (☾), \leftouterjoin (⟕), \leftrightarrow (↔), \leftrightarrowcircle (⥈), \leftrightarrows (⇆), \leftrightarrowtriangle (⇿), \leftrightharpoondowndown (⥐), \leftrightharpoondownup (⥋), \leftrightharpoons (⇋), \leftrightharpoonsdown (⥧), \leftrightharpoonsup (⥦), \leftrightharpoonupdown (⥊), \leftrightharpoonupup (⥎), \leftrightsquigarrow (↭), \leftsquigarrow (↜), \leftsquigarrow (⇜), \lefttail (⤙), \leftthreearrows (⬱), \leftthreetimes (⋋), \leftwhitearrow (⇦), \leq (≤), \leqq (≦), \leqqslant (⫹), \leqqslant (⫺), \leqslant (⩽), \lescc (⪨), \lesdot (⩿), \lesdoto (⪁), \lesdotor (⪃), \lesges (⪓), \less (<), \lessapprox (⪅), \lessdot (⋖), \lesseqgtr (⋚), \lesseqqgtr (⪋), \lessgtr (≶), \lesssim (≲), \lfbowtie (⧑), \lfloor (⌊), \lftimes (⧔), \lgE (⪑), \lgblkcircle (⬤), \lgblksquare (⬛), \lgwhtcircle (◯), \lgwhtsquare (⬜), \lhd (⊲), \linefeed (↴), \ll (≪), \llangle (⦉), \llarc (◟), \llblacktriangle (◣), \llcorner (⌞), \lll (⋘), \lllnest (⫷), \llparenthesis (⦇), \lltriangle (◺), \lmoustache (⎰), \lnapprox (⪉), \lneq (⪇), \lneqq (≨), \lnsim (⋦), \longdashv (⟞), \longdivision (⟌), \longleftarrow (⟵), \longleftrightarrow (⟷), \longleftsquigarrow (⬳), \longmapsfrom (⟻), \longmapsto (⟼), \longrightarrow (⟶), \longrightsquigarrow (⟿), \looparrowleft (↫), \looparrowright (↬), \lowint (⨜), \lozenge (◊), \lozengeminus (⟠), \lparenextender (⎜), \lparenlend (⎝), \lparenless (⦓), \lparenuend (⎛), \lq (‘), \lrarc (◞), \lrblacktriangle (◢), \lrcorner (⌟), \lrtriangle (◿), \lrtriangleeq (⧡), \lsime (⪍), \lsimg (⪏), \lsqhook (⫍), \ltcc (⪦), \ltcir (⩹), \ltimes (⋉), \ltlarr (⥶), \ltquest (⩻), \ltrivb (⧏), \lvboxline (⎸), \lvzigzag (⧘). \male (♂), \maltese (✠), \mapsdown (↧), \mapsfrom (↤), \mapsto (↦), \mapsup (↥), \mdblkdiamond (⬥), \mdblklozenge (⬧), \mdblkrcl (⚫), \mdblksquare (◼), \mdlgblkcircle (●), \mdlgblkdiamond (◆), \mdlgblklozenge (⧫), \mdlgblksquare (■), \mdlgwhtcircle (○), \mdlgwhtdiamond (◇), \mdlgwhtsquare (□), \mdsmblkcircle (⦁), \mdsmblksquare (◾), \mdsmwhtcircl (⚬), \mdsmwhtsquare (◽), \mdwhtcircl (⚪), \mdwhtdiamond (⬦), \mdwhtlozenge (⬨), \mdwhtsquare (◻), \measangledltosw (⦯), \measangledrtose (⦮), \measangleldtosw (⦫), \measanglelutonw (⦩), \measanglerdtose (⦪), \measanglerutone (⦨), \measangleultonw (⦭), \measangleurtone (⦬), \measeq (≞), \measuredangle (∡), \measuredangleleft (⦛), \measuredrightangle (⊾), \medblackstar (⭑), \medmathspace ( ), \medwhitestar (⭐), \mercury (☿), \mho (℧), \mid (∣), \midbarvee (⩝), \midbarwedge (⩜), \midcir (⫰), \minus (−), \minusdot (⨪), \minusfdots (⨫), \minusrdots (⨬), \mlcp (⫛), \models (⊧), \mp (∓), \mu (μ), \multimap (⊸), \multimapinv (⟜). \nHdownarrow (⇟), \nHuparrow (⇞), \nLeftarrow (⇍), \nLeftrightarrow (⇎), \nRightarrow (⇏), \nVDash (⊯), \nVdash (⊮), \nVleftarrow (⇺), \nVleftarrowtail (⬺), \nVleftrightarrow (⇼), \nVrightarrow (⇻), \nVrightarrowtail (⤕), \nVtwoheadleftarrow (⬵), \nVtwoheadleftarrowtail (⬽), \nVtwoheadrightarrow (⤁), \nVtwoheadrightarrowtail (⤘), \nabla (∇), \napprox (≉), \nasymp (≭), \natural (♮), \ncong (≇), \ne (≠), \nearrow (↗), \neg (¬), \neovnwarrow (⤱), \neovsearrow (⤮), \neptune (♆), \neq (≠), \nequiv (≢), \neswarrow (⤢), \neuter (⚲), \nexists (∄), \ng (ŋ), \ngeq (≱), \ngtr (≯), \ngtrless (≹), \ngtrsim (≵), \nhVvert (⫵), \nhpar (⫲), \ni (∋), \niobar (⋾), \nis (⋼), \nisd (⋺), \nleftarrow (↚), \nleftrightarrow (↮), \nleq (≰), \nless (≮), \nlessgtr (≸), \nlesssim (≴), \nmid (∤), \nni (∌), \nobreakhyphen (‑), \notin (∉), \nparallel (∦), \npolint (⨔), \nprec (⊀), \npreccurlyeq (⋠), \nrightarrow (↛), \nsim (≁), \nsime (≄), \nsqsubseteq (⋢), \nsqsupseteq (⋣), \nsubset (⊄), \nsubseteq (⊈), \nsucc (⊁), \nsucccurlyeq (⋡), \nsupset (⊅), \nsupseteq (⊉), \ntriangleleft (⋪), \ntrianglelefteq (⋬), \ntriangleright (⋫), \ntrianglerighteq (⋭), \nu (ν), \nvDash (⊭), \nvLeftarrow (⤂), \nvLeftrightarrow (⤄), \nvRightarrow (⤃), \nvdash (⊬), \nvinfty (⧞), \nvleftarrow (⇷), \nvleftarrowtail (⬹), \nvleftrightarrow (⇹), \nvrightarrow (⇸), \nvrightarrowtail (⤔), \nvtwoheadleftarrow (⬴), \nvtwoheadleftarrowtail (⬼), \nvtwoheadrightarrow (⤀), \nvtwoheadrightarrowtail (⤗), \nwarrow (↖), \nwovnearrow (⤲), \nwsearrow (⤡). \o (ø), \obar (⌽), \obot (⦺), \obrbrak (⏠), \obslash (⦸), \odiv (⨸), \odot (⊙), \odotslashdot (⦼), \oe (œ), \ogreaterthan (⧁), \ohorn (ơ), \oiiint (∰), \oiint (∯), \oint (∮), \ointctrclockwise (∳), \olcross (⦻), \oldKoppa (Ϙ), \oldkoppa (ϙ), \olessthan (⧀), \omega (ω), \omicron (ο), \ominus (⊖), \operp (⦹), \oplus (⊕), \opluslhrim (⨭), \oplusrhrim (⨮), \origof (⊶), \oslash (⊘), \otimes (⊗), \otimeshat (⨶), \otimeslhrim (⨴), \otimesrhrim (⨵), \overbrace (⏞), \overbracket (⎴), \overline (‾), \overparen (⏜), \owns (∋). \parallel (∥), \parallelogram (▱), \parallelogramblack (▰), \parsim (⫳), \partial (∂), \partialmeetcontraction (⪣), \pentagon (⬠), \pentagonblack (⬟), \perp (⟂), \perps (⫡), \phi (ϕ), \phone (☎), \pi (π), \pitchfork (⋔), \plusdot (⨥), \pluseqq (⩲), \plushat (⨣), \plussim (⨦), \plussubtwo (⨧), \plustrif (⨨), \pluto (♇), \pm (±), \pointnt (⨕), \postalmark (〒), \prec (≺), \precapprox (⪷), \preccurlyeq (≼), \preceq (⪯), \preceqq (⪳), \precnapprox (⪹), \precneq (⪱), \precneqq (⪵), \precnsim (⋨), \precsim (≾), \prime (′), \prod (∏), \profalar (⌮), \profline (⌒), \profsurf (⌓), \propto (∝), \prurel (⊰), \psi (ψ), \pullback (⟓), \pushout (⟔). \qprime (⁗), \quarternote (♩), \questeq (≟), \quotdblbase („), \quotdblright (‟), \quotsinglbase (‚), \quotsinglright (‛). \rAngle (⟫), \rBrace (⦄), \rBrack (⟧), \rParen (⦆), \rangle (⟩), \rangledot (⦒), \rangledownzigzagarrow (⍼), \rasp (ʼ), \rbag (⟆), \rblkbrbrak (⦘), \rbrace (@}), \rbracelend (⎭), \rbracemid (⎬), \rbraceuend (⎫), \rbrack (]), \rbrackextender (⎥), \rbracklend (⎦), \rbracklrtick (⦎), \rbrackubar (⦌), \rbrackuend (⎤), \rbrackurtick (⦐), \rbrbrak (❳), \rceil (⌉), \rcurvyangle (⧽), \rdiagovfdiag (⤫), \rdiagovsearrow (⤰), \recorder (⌕), \revangle (⦣), \revangleubar (⦥), \revemptyset (⦰), \revnmid (⫮), \rfbowtie (⧒), \rfloor (⌋), \rftimes (⧕), \rhd (⊳), \rho (ρ), \righarrowbsimilar (⭌), \rightangle (∟), \rightanglemdot (⦝), \rightanglesqr (⦜), \rightarrow (→), \rightarrowapprox (⥵), \rightarrowbackapprox (⭈), \rightarrowbar (⇥), \rightarrowdiamond (⤞), \rightarrowgtr (⭃), \rightarrowonoplus (⟴), \rightarrowplus (⥅), \rightarrowshortleftarrow (⥂), \rightarrowsimilar (⥴), \rightarrowsupset (⭄), \rightarrowtail (↣), \rightarrowtriangle (⇾), \rightarrowx (⥇), \rightbkarrow (⤍), \rightcurvedarrow (⤳), \rightdasharrow (⇢), \rightdbltail (⤜), \rightdotarrow (⤑), \rightdowncurvedarrow (⤷), \rightfishtail (⥽), \rightharpoondown (⇁), \rightharpoondownbar (⥗), \rightharpoonsupdown (⥤), \rightharpoonup (⇀), \rightharpoonupbar (⥓), \rightharpoonupdash (⥬), \rightimply (⥰), \rightleftarrows (⇄), \rightleftharpoons (⇌), \rightleftharpoonsdown (⥩), \rightleftharpoonsup (⥨), \rightmoon (☽), \rightouterjoin (⟖), \rightpentagon (⭔), \rightpentagonblack (⭓), \rightrightarrows (⇉), \rightsquigarrow (↝), \rightsquigarrow (⇝), \righttail (⤚), \rightthreearrows (⇶), \rightthreetimes (⋌), \rightwhitearrow (⇨), \ringplus (⨢), \risingdotseq (≓), \rmoustache (⎱), \rparenextender (⎟), \rparengtr (⦔), \rparenlend (⎠), \rparenuend (⎞), \rppolint (⨒), \rq (’), \rrangle (⦊), \rrparenthesis (⦈), \rsolbar (⧷), \rsqhook (⫎), \rsub (⩥), \rtimes (⋊), \rtriltri (⧎), \ruledelayed (⧴), \rvboxline (⎹), \rvzigzag (⧙). \sampi (ϡ), \sansLmirrored (⅃), \sansLturned (⅂), \saturn (♄), \scissors (✂), \scpolint (⨓), \scrB (ℬ), \scrE (ℰ), \scrF (ℱ), \scrH (ℋ), \scrI (ℐ), \scrL (ℒ), \scrM (ℳ), \scrR (ℛ), \scre (ℯ), \scrg (ℊ), \scro (ℴ), \scurel (⊱), \searrow (↘), \seovnearrow (⤭), \setminus (∖), \setminus (⧵), \sharp (♯), \shortdowntack (⫟), \shortleftarrow (←), \shortlefttack (⫞), \shortrightarrow (→), \shortrightarrowleftarrow (⥄), \shortuptack (⫠), \shuffle (⧢), \sigma (σ), \silon (υ), \silon (ϒ), \sim (∼), \simeq (≃), \simgE (⪠), \simgtr (⪞), \similarleftarrow (⭉), \similarrightarrow (⥲), \simlE (⪟), \simless (⪝), \simminussim (⩬), \simneqq (≆), \simplus (⨤), \simrdots (⩫), \sinewave (∿), \slash (∕), \smallblacktriangleleft (◂), \smallblacktriangleright (▸), \smalldiamond (⋄), \smallin (∊), \smallint (∫), \smallni (∍), \smallsetminus (∖), \smalltriangleleft (◃), \smalltriangleright (▹), \smashtimes (⨳), \smblkdiamond (⬩), \smblklozenge (⬪), \smblksquare (▪), \smeparsl (⧤), \smile (⌣), \smiley (☺), \smt (⪪), \smte (⪬), \smwhitestar (⭒), \smwhtcircle (◦), \smwhtlozenge (⬫), \smwhtsquare (▫), \spadesuit (♠), \sphericalangle (∢), \sphericalangleup (⦡), \sqcap (⊓), \sqcup (⊔), \sqint (⨖), \sqlozenge (⌑), \sqrt (√), \sqrt3 (∛), \sqrt4 (∜), \sqrtbottom (⎷), \sqsubset (⊏), \sqsubseteq (⊑), \sqsubsetneq (⋤), \sqsupset (⊐), \sqsupseteq (⊒), \sqsupsetneq (⋥), \squarecrossfill (▩), \squaregrayfill (▩), \squarehfill (▤), \squarehvfill (▦), \squareleftblack (◧), \squareleftblack (◨), \squarellblack (⬕), \squarellquad (◱), \squarelrblack (◪), \squarelrquad (◲), \squareneswfill (▨), \squarenwsefill (▧), \squareulblack (◩), \squareulquad (◰), \squareurblack (⬔), \squareurquad (◳), \squarevfill (▥), \squoval (▢), \ss (ß), \star (⋆), \stareq (≛), \sterling (£), \stigma (ϛ), \strns (⏤), \subedot (⫃), \submult (⫁), \subrarr (⥹), \subset (⊂), \subsetapprox (⫉), \subsetcirc (⟃), \subsetdot (⪽), \subseteq (⊆), \subseteqq (⫅), \subsetneq (⊊), \subsetneqq (⫋), \subsetplus (⪿), \subsim (⫇), \subsub (⫕), \subsup (⫓), \succ (≻), \succapprox (⪸), \succcurlyeq (≽), \succeq (⪰), \succeqq (⪴), \succnapprox (⪺), \succneq (⪲), \succneqq (⪶), \succnsim (⋩), \succsim (≿), \sum (∑), \sumbottom (⎳), \sumint (⨋), \sumtop (⎲), \sun (☼), \supdsub (⫘), \supedot (⫄), \suphsol (⟉), \suphsub (⫗), \suplarr (⥻), \supmult (⫂), \supn (ⁿ), \supset (⊃), \supsetapprox (⫊), \supsetcirc (⟄), \supsetdot (⪾), \supseteq (⊇), \supseteqq (⫆), \supsetneq (⊋), \supsetneqq (⫌), \supsetplus (⫀), \supsim (⫈), \supsub (⫔), \supsup (⫖), \surd (√), \swarrow (↙). \talloblong (⫾), \target (⌖), \tau (τ), \taurus (♉), \testhookx (ᶍ), \textAsterisks (⁑), \textacute (ˊ), \textadvanced (˖), \textain (ʿ), \textasciiacute (´), \textasciicircum (^), \textasciidieresis (¨), \textasciigrave (`), \textasciimacron (¯), \textasciitilde (~), \textasterisklow (⁎), \textbackdprime (‶), \textbackprime (‵), \textbacktrprime (‷), \textbardotlessj (ɟ), \textbardotlessjvar (ʄ), \textbarglotstop (ʡ), \textbari (ɨ), \textbarl (ƚ), \textbaro (ɵ), \textbarrevglotstop (ʢ), \textbaru (ʉ), \textbeltl (ɬ), \textbenttailyogh (ƺ), \textbreve (˘), \textbrokenbar (¦), \textbullet (•), \textbullseye (ʘ), \textcent (¢), \textcircledP (℗), \textcloseepsilon (ʚ), \textcloseomega (ɷ), \textcloserevepsilon (ɞ), \textcopyright (©), \textcrb (ƀ), \textcrh (ħ), \textcrinvglotstop (ƾ), \textcrlambda (ƛ), \textcrtwo (ƻ), \textctc (ɕ), \textctd (ȡ), \textctesh (ʆ), \textctj (ʝ), \textctl (ȴ), \textctn (ȵ), \textctt (ȶ), \textctyogh (ʓ), \textctz (ʑ), \textcurrency (¤), \textdctzlig (ʥ), \textdegree (°), \textdiscount (⁒), \textdollar ($), \textdotaccent (˙), \textdotlessj (ȷ), \textdoubleacute (˝), \textdoublebarpipe (ǂ), \textdoublepipe (ǁ), \textdprime (″), \textdptr (˅), \textdyoghlig (ʤ), \textdzlig (ʣ), \textepsilon (ɛ), \textesh (ʃ), \textestimated (℮), \textexclam (ǃ), \textexclamdown (¡), \textfishhookr (ɾ), \textflorin (ƒ), \textfranc (₣), \textgamma (ɣ), \textglotstop (ʔ), \textgrave (ˋ), \texthalflength (ˑ), \texthamza (ʾ), \texthen (ꜧ), \textheng (ꜧ), \texthooks (ᶊ), \texthookz (ᶎ), \texthtb (ɓ), \texthtc (ƈ), \texthtd (ɗ), \texthtg (ɠ), \texthth (ɦ), \texththeng (ɧ), \texthtk (ƙ), \texthtp (ƥ), \texthtq (ʠ), \texthtscg (ʛ), \texthtt (ƭ), \texthvlig (ƕ), \texthyphen (‐), \textinvglotstop (ʖ), \textinvscr (ʁ), \textiota (ɩ), \textlengthmark (ː), \textlhalfring (˓), \textlhookd (ᶁ), \textlhookk (ᶄ), \textlhookl (ᶅ), \textlhookt (ƫ), \textlhti (ɿ), \textlira (₤), \textlonglegr (ɼ), \textlongy (ʮ), \textlongy (ʯ), \textlooptoprevesh (ƪ), \textlowacute (ˏ), \textlowered (˕), \textlowgrave (ˎ), \textlowmacron (ˍ), \textlptr (˂), \textltailm (ɱ), \textltailn (ɲ), \textltilde (ɫ), \textlyoghlig (ɮ), \textmacron (ˉ), \textmu (µ), \textnumero (№), \textogonek (˛), \textohm (Ω), \textonehalf (½), \textonequarter (¼), \textonesuperior (¹), \textopeno (ɔ), \textordfeminine (ª), \textordmasculine (º), \textovercross (˟), \textoz (℥), \textpertenthousand (‱), \textperthousand (‰), \textpesetas (₧), \textphi (ɸ), \textpipe (ǀ), \textprime (′), \textprimstress (ˈ), \textqprime (⁗), \textquestiondown (¿), \textquotedbl ("), \textquotedblleft (“), \textquotedblright (”), \textraised (˔), \textraiseglotstop (ˀ), \textraiserevglotstop (ˁ), \textramshorns (ɤ), \textrecipe (℞), \textreferencemark (※), \textregistered (®), \textretracted (˗), \textreve (ɘ), \textrevepsilon (ɜ), \textrevglotstop (ʕ), \textrhalfring (˒), \textrhookrevepsilon (ɝ), \textrhookschwa (ɚ), \textrhoticity (˞), \textringaccent (˚), \textrptr (˃), \textrtaild (ɖ), \textrtaill (ɭ), \textrtailn (ɳ), \textrtailr (ɽ), \textrtails (ʂ), \textrtailt (ʈ), \textrtailz (ʐ), \textsca (ᴀ), \textscb (ʙ), \textsce (ᴇ), \textscg (ɢ), \textsch (ʜ), \textschwa (ə), \textsci (ɪ), \textscl (ʟ), \textscn (ɴ), \textscoelig (ɶ), \textscr (ʀ), \textscripta (ɑ), \textscriptg (ɡ), \textscriptv (ʋ), \textscu (ᴜ), \textscy (ʏ), \textsecstress (ˌ), \textsemicolonreversed (⁏), \textsilon (Υ), \textsmalltilde (˜), \textstretchcvar (ʗ), \textsubw (w), \textsuph (ʰ), \textsuphth (ʱ), \textsupinvscr (ʶ), \textsupj (ʲ), \textsupr (ʳ), \textsupturnr (ʴ), \textsupturnrrtail (ʵ), \textsupw (ʷ), \textsupy (ʸ), \texttctctlig (ʧ), \texttctctlig (ʨ), \textthreequarters (¾), \textthreesuperior (³), \texttrademark (™), \texttrprime (‴), \texttslig (ʦ), \textturna (ɐ), \textturncomma (ʻ), \textturnh (ɥ), \textturnk (ʞ), \textturnlonglegr (ɺ), \textturnm (ɯ), \textturnmrleg (ɰ), \textturnr (ɹ), \textturnrrtail (ɻ), \textturnscripta (ɒ), \textturnt (ʇ), \textturnv (ʌ), \textturnw (ʍ), \textturny (ʎ), \texttwosuperior (²), \textupsilon (ʊ), \textuptr (˄), \textvibyi (ʅ), \textvisiblespace (␣), \textyogh (ʒ), \th (þ), \therefore (∴), \thermod (⧧), \theta (θ), \thickapprox (≈), \thicksim (∼), \threedangle (⟀), \threedotcolon (⫶), \tieconcat (⁀), \tieinfty (⧝), \times (×), \timesbar (⨱), \tminus (⧿), \to (→), \toea (⤨), \tona (⤧), \tonebarextrahigh (˥), \tonebarextralow (˩), \tonebarhigh (˦), \tonebarlow (˨), \tonebarmid (˧), \top (⊤), \topbot (⌶), \topcir (⫱), \topfork (⫚), \topsemicircle (◠), \tosa (⤩), \towa (⤪), \tplus (⧾), \trapezium (⏢), \trianglecdot (◬), \triangledown (▿), \triangleexclam (⚠), \triangleleft (◁), \triangleleftblack (◭), \trianglelefteq (⊴), \triangleminus (⨺), \triangleodot (⧊), \triangleplus (⨹), \triangleq (≜), \triangleright (▷), \trianglerightblack (◮), \trianglerighteq (⊵), \triangles (⧌), \triangleserifs (⧍), \triangletimes (⨻), \triangleubar (⧋), \tripleplus (⧻), \trprime (‴), \turnangle (⦢), \turnediota (℩), \turnednot (⌙), \twocaps (⩋), \twocups (⩊), \twoheaddownarrow (↡), \twoheadleftarrow (↞), \twoheadleftarrowtail (⬻), \twoheadleftdbkarrow (⬷), \twoheadmapsfrom (⬶), \twoheadmapsto (⤅), \twoheadrightarrow (↠), \twoheadrightarrowtail (⤖), \twoheaduparrow (↟), \twoheaduparrowcircle (⥉), \twolowline (‗), \twonotes (♫), \typecolon (⦂). \ubrbrak (⏡), \uhorn (ư), \ularc (◜), \ulblacktriangle (◤), \ulcorner (⌜), \ulcrop (⌏), \ultriangle (◸), \uminus (⩁), \underbrace (⏟), \underbracket (⎵), \underparen (⏝), \unlhd (⊴), \unrhd (⊵), \upand (⅋), \uparrow (↑), \uparrowbarred (⤉), \uparrowoncircle (⦽), \updasharrow (⇢), \updownarrow (↕), \updownarrowbar (↨), \updownarrows (⇅), \updownharpoonleftleft (⥑), \updownharpoonleftright (⥍), \updownharpoonrightleft (⥌), \updownharpoonrightright (⥏), \updownharpoonsleftright (⥮), \upfishtail (⥾), \upharpoonleft (↿), \upharpoonleftbar (⥠), \upharpoonright (↾), \upharpoonrightbar (⥜), \upharpoonsleftright (⥣), \upin (⟒), \upint (⨛), \uplus (⊎), \uprightcurvearrow (⤴), \upuparrows (⇈), \upwhitearrow (⇧), \urarc (◝), \urblacktriangle (◥), \urcorner (⌝), \urcrop (⌎), \urtriangle (◹). \v (ˇ), \vBar (⫨), \vBarv (⫩), \vDash (⊨), \vDdash (⫢), \varTheta (ϴ), \varVdash (⫦), \varbarwedge (⌅), \varbeta (ϐ), \varclubsuit (♧), \vardiamondsuit (♦), \vardoublebarwedge (⌆), \varepsilon (ε), \varheartsuit (♥), \varhexagon (⬡), \varhexagonblack (⬢), \varhexagonlrbonds (⌬), \varin (∈), \varisinobar (⋶), \varisins (⋳), \varkappa (ϰ), \varlrtriangle (⊿), \varni (∋), \varniobar (⋽), \varnis (⋻), \varnothing (∅), \varointclockwise (∲), \varphi (φ), \varpi (ϖ), \varpropto (∝), \varrho (ϱ), \varrowextender (⏐), \varsigma (ς), \varspadesuit (♤), \varstar (✶), \vartheta (ϑ), \vartriangle (▵), \vartriangleleft (⊲), \vartriangleright (⊳), \varveebar (⩡), \vbraceextender (⎪), \vbrtri (⧐), \vdash (⊢), \vdots (⋮), \vectimes (⨯), \vee (∨), \veebar (⊻), \veedot (⟇), \veedoublebar (⩣), \veeeq (≚), \veemidvert (⩛), \veeodot (⩒), \veeonvee (⩖), \veeonwedge (⩙), \vert (|), \viewdata (⌗), \vlongdash (⟝), \vrectangle (▯), \vrectangleblack (▮), \vysmlblksquare (⬝), \vysmlwhtsquare (⬞), \vzigzag (⦚). \watchicon (⌚), \wedge (∧), \wedgebar (⩟), \wedgedot (⟑), \wedgedoublebar (⩠), \wedgemidvert (⩚), \wedgeodot (⩑), \wedgeonwedge (⩕), \wedgeq (≙), \whitearrowupfrombar (⇪), \whiteinwhitetriangle (⟁), \whitepointerleft (◅), \whitepointerright (▻), \whitesquaretickleft (⟤), \whitesquaretickright (⟥), \whthorzoval (⬭), \whtvertoval (⬯), \wideangledown (⦦), \wideangleup (⦧), \wp (℘), \wr (≀). \xbsol (⧹), \xi (ξ), \xsol (⧸), \yen (¥), \zeta (ζ), \zpipe (⨠), Я БУДУ КРАЙНЕ ПРИЗНАТЕЛЕН ЕСЛИ КТО-НИБУДЬ ПРОВЕРИТ СООТВЕТСТВИЕ ВСЕХ ИМЕН ПРАВИЛЬНЫМ ТЕХ-ИМ СИМВОЛАМ. mathgl-2.4.4/texinfo/classes.pdf0000644000175000017500000003127013513030041016754 0ustar alastairalastair%PDF-1.5 % 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream x\ߏ7~¬wpl>.ˁr{G$E+ LYHȟ_vtt7;"Sx_UʞH|0Z)FNoۯeC#[V~[k(+?>koUWZ(mU, tZ!c{}>W ZTL} k['pΨ۫櫟^\ܼ>曫#&[_ 5)qF9VX-|қB|TrdK6^_>?^};ǚuV{,"R@&~0F>b܋wwn Kh[޵:/'1lj9t |&0N(s pE"x%JU!l~T!㧗?VA V ǚk"oo nWG=UBE"`B4E*u"'aFP6o"Zm!YJC)~rJ]Z4 3Lh;a(=VFa,'bg|c vbޞ:dhOtĞrj'7VhT,0%s;J8-jV:mӴ UkhA1"B #4`nz ( ;hH,$b'xg뫢p3w8A?1.Z\&4l&/`rÜ(mqqļxQa >YĊ 9z82Bfߔ,Lhy 1a$_3^~QMu q 0$RH1l[+p%! I)TU(X3a)N}Es^cTT<$eUr8b's}R/P 8qqdWpDZ%EVn.|r{fXVc8LI-oZ÷ #6;ru+'|ThZBDN۸ӵ& &)z>ph(:#F{p> H=ݘx-7H .}77OCn.Z6}Lz_8XT`g0gRDp:KjzmnL鄲cM+vZBbU+{8+1ccF B6ID&0LŇ#6c-'V]/ݴJsz }V_ u ;hǹcIҞϸ(.: ©s ϩczN˂OPT2o'p9c1fW9eB%&$}6(QjAMp5sTmWBi_UfviX_pt0\HС^w\\~xsㅐvdS  ZwC@ ex]]wrt5~Ej,ET2P|UMF#:w1d4S@o_/YCZ[Q3LX]k,C2!Yr<%^H|ܖ!ǖ/.ŞI!_x{׋z{^š :Њdӡ`yk)k(M!jXXG94抆Cu>P! 4GKEZ'Zñ6ѣ9HYܑ(Є5hcБFZ'lD~՝^b,VQI%9ڟ<|J$jcpض6Ǫ"E?$ԔsPTiu~J""6 kT*;GZăo@.} ά~vMF$<x˻^g~e.}9#JnEr[E, Svf&LQ `}Y0_4 Ml$8 endstream endobj 4 0 obj 3053 endobj 2 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> /Font << /f-0-0 5 0 R >> >> endobj 6 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 1077.165283 992.125977 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /I true /CS /DeviceRGB >> /Resources 2 0 R >> endobj 7 0 obj << /Length 8 0 R /Filter /FlateDecode /Length1 10536 >> stream xz xTEnUG; yw'tBxƄF8N%hIA$!" Bd;GF虈ҕv'Afsw|N޻j蝹V׿C(! wSvg$`%4mC^roB!IwBeaь\0ޓ}3_\O, ;sV'B55+AeޛtCq߁xӦv`BRT=0eQߨ*͝^O^NI)PDiUkDF5Q8Qw&8x1#s}N_!' KY~N(9JI2HU\z$kYq18#4Msjyء)F+&ңW5f:]9Ȍy:Xkwlt ʌ8S=SSyחJwI1m⸜q("N_fl 'ѭ)>O?+ki?QZTbr-5;lP=wN_\|/8g-x73Im -&J]t4&%\m%k$CRQ9]ڌsqٙq=e$J $IoHKKKҊV$%%y|+קU]IKlĢ"o44[0"hogJ={efݛ;'kAׇQܦ#cWXVaygZp;^}U{iiͦ_nViR1ITcLRRbaILjƏhXT2:N;yH'4^44"ZOpes3AuؿEoP4tF%]jtt,/Ҏ9sTNIt_ǴJJJ W(eL1 Xv@,Amu&6C|S_ %K*aﰝfؾ &|qKx>Qȵ@8I0OP'!J.P0*8QgFUc'Ԡ>GUǎӬhyĺ0hfڊvb2 <6bŬdqi@:Z=4by*IνZ6ɦ}/ІtCp%'DBRH{ 1S擇h1aeYAWjZT*I%ĶfYlRju֢ ą,2-z7-yWo UcFXEc b b)X ũj@ijΊO鬹`9hѬCъg ?v;+LaN5a~#r1-|aQjT i@"@\#c=Zar*^ի kͳDKϱ f9|\%WZ@lxm5^f>U+jVd-f`!H,V "mZb_` QK}n?h}ӤӔ!Gȹ`~|[)E5l.t:MB O &5B[kM͉Ɔ9]! a VSwObibUxYm!q(#[k$`Է%/?aÞ=6<GoS0HOKXph P xWqT&2ɳ:X(\x$``;}>G߈M-y˯9wo5QuߞPɘqI}>9|ɗ?i UeC_H 5O-R|԰8cNDii!¾V'\ZчƓ]QՎ^:3葤`vjzu=T7+\,65.vKtp)<< * ԙfd\ؑfw.O¤P U]{C\@'͉:DVFlktEPhhYniن4@,D Ldf3]bD'7%zjPq6` B[%ʵ)( ]U`tV{^fXo06(5` |.E5F<-z^R߆?G Z,t<yN;ԇA]k8?>lahxA&YiB +İ:ԝp))1dLd͛pM;DF7UnlRs+Ll&貳tVz9+<(cjV@K, "@gEPj657"ѪTHE]km+1qYisY3꨻L\7PircHv s(-qS_1.SI*A:8:w]t Jw;6,kK%Ɍ@O0!!J4 =P`9YLP@}֪Sk44S_E7-BgH#^5`O5۸-ab-WYqBBII%}6K_-֗uPAcL'Fѥv{[˒: ~ؒL8iWSp?:Il4!<wx&kAZ*& fCMDŋT?rlJ7<3˞[0EʟBN!{@#]k;讈!m>D)bIRh%zQb)J%%g*J]6E>%ټU<WK^7uK'O^oQ~+ܴOXF FA*e.a 1ANswh몹jn,$ =Ζrw@ClY'LqM+z>Pr |EhOm{c2hagVrm^mXeYf8$'l$?2nh)B+-7R;Ya~3don8Nڙ5R0@ l%VPXlXC EtaXtB37P4qcax&ɍ,$9dY@ZTcȷyagAgEt[sB2Z7'G@||je_WY 8ԅe8ݮB^q3@ԅ%Ab*Hf2˭CyTa&&RxTLnѰ3I, ,2 C>B SBv/W  ע7M]|k,b  wrN<=¶…NGمÝFQ =MwSp$DP, ,ҔT5UKսh/6e3|>_,\RDݩ>sen.xk#,:.=AI#rCEVwr&-Z->xQGYaĤ =G7A5h;hE܆Lr\v9xiylc󆬼m0 -/eCSo?__8 iϓׄs5\myV_0é5;Lơ$ۍɲաXv<~nhfC.m߿O`@L23%l6lw$eT. %N%O's )%݆D\1@줄1-;7՛Kni1$Ut4m؞s_(qn[6<ڎw8AOoW?>Lc4ЏxkT,.nMB0ruv"WVd 7Ei'e7G<"OcHl$xAt7bb 2kޢt5ur,#:da-!g#WXrqa>%~),!ƋXrm5DoFh$"틟>j6OzhZO 7rb)9/bޅd$d l>d'''ķ ,dr+\"'!GZ5d<F:ʿ$sirRIG㵋vreƐg0*:?XjџFN0j#vc'![Gɶ E!ޏpcYKHd5!XYUB6<:lž:a1jOMؚi0t!3M&i}aQxAV@ Mn~΄*G; ᪄v[%\w,p&ko׹pIW1J^!.4=s I8 V9 /K+𱄏BÙaa)?%|G Hx_©Jx>Q'>̈́YQP'- oJxC^pL«j%"jVE˯L//#/őɁ8/ᰄ?T! /JpPxط%a Go=[.x6vG*amO[6 O[aS1bk2R.!po6 qFa( #G8H`#0$ !0X- r_GA@ @7 !?h~6+!GBnѧ zrnmme̛,"SMa6att ]:ENi~fHC"R#oR$$G[IM*$@ т 6b&FBFKEK—b#-!R pIʺ g.8BD%جQ&O["p.A4 xkAbq +.>[7so. endstream endobj 8 0 obj 7513 endobj 9 0 obj << /Length 10 0 R /Filter /FlateDecode >> stream x]RN0+|JR츕J\z! ؛: 8$gc{qŔy Z0<]r qLE2q LEŇy> SѶ|!N=Ƙ%Gc:2_tnMힺ;)ny}\w\xdV:)Ls(wHE[U[öݯQEDV=cR5W=x<'77rJ-x+E+;ihЬ#r^/>  </fFx܏p%4;-٬ds8SO[<ϋʓKoRm #3&yJo7 endstream endobj 10 0 obj 395 endobj 11 0 obj << /Type /FontDescriptor /FontName /BTTTRY+DejaVuSans /FontFamily (DejaVu Sans) /Flags 32 /FontBBox [ -1020 -415 1680 1166 ] /ItalicAngle 0 /Ascent 928 /Descent -235 /CapHeight 1166 /StemV 80 /StemH 80 /FontFile2 7 0 R >> endobj 5 0 obj << /Type /Font /Subtype /TrueType /BaseFont /BTTTRY+DejaVuSans /FirstChar 32 /LastChar 120 /FontDescriptor 11 0 R /Encoding /WinAnsiEncoding /Widths [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 684 686 698 770 631 575 774 0 294 0 655 557 862 0 0 603 787 694 0 610 731 684 988 685 0 0 0 0 0 0 500 0 612 0 0 634 615 0 634 633 277 0 0 277 974 633 611 634 0 411 520 392 633 591 817 591 ] /ToUnicode 9 0 R >> endobj 1 0 obj << /Type /Pages /Kids [ 6 0 R ] /Count 1 >> endobj 12 0 obj << /Creator (cairo 1.13.1 (http://cairographics.org)) /Producer (cairo 1.13.1 (http://cairographics.org)) >> endobj 13 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 14 0000000000 65535 f 0000012371 00000 n 0000003168 00000 n 0000000015 00000 n 0000003145 00000 n 0000011904 00000 n 0000003277 00000 n 0000003506 00000 n 0000011114 00000 n 0000011137 00000 n 0000011610 00000 n 0000011633 00000 n 0000012436 00000 n 0000012564 00000 n trailer << /Size 14 /Root 13 0 R /Info 12 0 R >> startxref 12617 %%EOF mathgl-2.4.4/texinfo/copyright.texi0000644000175000017500000000070313513030041017524 0ustar alastairalastairCopyright @copyright{} 2008-2012 Alexey A. Balakin. @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License.'' @end quotation mathgl-2.4.4/texinfo/mathgl.texi0000644000175000017500000000000013513030041016756 0ustar alastairalastairmathgl-2.4.4/texinfo/symbols_ru.texi0000644000175000017500000004653513513030041017727 0ustar alastairalastair@nav{} This appendix contain the full list of symbols (characters) used by MathGL for setting up plot. Also it contain sections for full list of hot-keys supported by mglview tool and by UDAV program. @menu * Symbols for styles:: * Hot-keys for mglview:: * Hot-keys for UDAV:: @end menu @c ------------------------------------------------------------------ @external{} @node Symbols for styles, Hot-keys for mglview, , Symbols and hot-keys @section Symbols for styles @nav{} Below is full list of all characters (symbols) which MathGL use for setting up the plot. @table @samp @item space ' ' empty line style (see @ref{Line styles}); empty color in @ref{chart}. @item ! set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting}; set to disable ticks tuning in @ref{axis} and @ref{colorbar}; set to draw @ref{grid} lines at subticks coordinates too; define complex variable/expression in MGL script if placed at beginning. @item # set to use solid marks (see @ref{Line styles}) or solid @ref{error} boxes; set to draw wired plot for @ref{axial}, @ref{surf3}, @ref{surf3a}, @ref{surf3c}, @ref{triplot}, @ref{quadplot}, @ref{area}, @ref{region}, @ref{bars}, @ref{barh}, @ref{tube}, @ref{tape}, @ref{cone}, @ref{boxs} and draw boundary only for @ref{circle}, @ref{ellipse}, @ref{rhomb}; set to draw also mesh lines for @ref{surf}, @ref{surfc}, @ref{surfa}, @ref{dens}, @ref{densx}, @ref{densy}, @ref{densz}, @ref{dens3}, or boundary for @ref{chart}, @ref{facex}, @ref{facey}, @ref{facez}, @ref{rect}; set to draw boundary and box for @ref{legend}, @ref{title}, or grid lines for @ref{table}; set to draw grid for @ref{radar}; set to start flow threads and pipes from edges only for @ref{flow}, @ref{pipe}; set to use whole are for axis range in @ref{subplot}, @ref{inplot}; change text color inside a string (see @ref{Font styles}); start comment in @ref{MGL scripts} or in @ref{Command options}. @item $ denote parameter of @ref{MGL scripts}. @item % set color scheme along 2 coordinates @ref{Color scheme}; operation in @ref{Textual formulas}. @item & set to pass long integer number in tick template @ref{xtick}, @ref{ytick}, @ref{ztick}, @ref{ctick}; specifier of drawing user-defined symbols as mark (see @ref{Line styles}); operation in @ref{Textual formulas}. @item @quoteright{} denote string in @ref{MGL scripts} or in @ref{Command options}. @item * one of marks (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); set to start flow threads from 2d array inside data (see @ref{flow}); operation in @ref{Textual formulas}. @item + one of marks (see @ref{Line styles}) or kind of @ref{error} boxes; one of mask for face filling (see @ref{Color scheme}); set to print @samp{+} for positive numbers in @ref{axis}, @ref{label}, @ref{table}; operation of increasing last character value in MGL strings; operation in @ref{Textual formulas}. @item , separator for color positions (see @ref{Color styles}) or items in a list concatenation of MGL string with another string or numerical value. @item - solid line style (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); place entries horizontally in @ref{legend}; set to use usual @samp{-} for negative numbers in @ref{axis}, @ref{label}, @ref{table}; operation in @ref{Textual formulas}. @item . one of marks (see @ref{Line styles}) or kind of @ref{error} boxes; set to draw hachures instead of arrows for @ref{vect}, @ref{vect3}; set to use dots instead of faces for @ref{cloud}, @ref{torus}, @ref{axial}, @ref{surf3}, @ref{surf3a}, @ref{surf3c}, @ref{surf}, @ref{surfa}, @ref{surfc}, @ref{dens}, @ref{map}; delimiter of fractional parts for numbers. @item / operation in @ref{Textual formulas}. @item : line dashing style (see @ref{Line styles}); stop color scheme parsing (see @ref{Color scheme}); range operation in @ref{MGL scripts}; style for @ref{axis}; separator of commands in @ref{MGL scripts}. @item ; line dashing style (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); start of an option in @ref{MGL scripts} or in @ref{Command options}; separator of equations in @ref{ode}; separator of labels in @ref{iris}. @item < one of marks (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); style of @ref{subplot} and @ref{inplot}; set position of @ref{colorbar}; style of @ref{vect}, @ref{vect3}; align left in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc}; operation in @ref{Textual formulas}. @item > one of marks (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); style of @ref{subplot} and @ref{inplot}; set position of @ref{colorbar}; style of @ref{vect}, @ref{vect3}; align right in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc}; operation in @ref{Textual formulas}. @item = line dashing style (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); set to use equidistant columns for @ref{table}; set to use color gradient for @ref{vect}, @ref{vect3}; operation in @ref{Textual formulas}. @item @@ set to draw box around text for @ref{text} and similar functions; set to draw boundary and fill it for @ref{circle}, @ref{ellipse}, @ref{rhomb}; set to fill faces for @ref{box}; set to draw large semitransparent mark instead of error box for @ref{error}; set to draw edges for @ref{cone}; set to draw filled boxes for @ref{boxs}; reduce text size inside a string (see @ref{Font styles}); operation in @ref{Textual formulas}. @item ^ one of marks (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}); style of @ref{subplot} and @ref{inplot}; set position of @ref{colorbar}; set outer position for @ref{legend}; inverse default position for @ref{axis}; switch to upper index inside a string (see @ref{Font styles}); align center in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc}; operation in @ref{Textual formulas}. @item _ empty arrow style (see @ref{Line styles}); disable drawing of tick labels for @ref{axis}; style of @ref{subplot} and @ref{inplot}; set position of @ref{colorbar}; set to draw contours at bottom for @ref{cont}, @ref{contf}, @ref{contd}, @ref{contv}, @ref{tricont}; switch to lower index inside a string (see @ref{Font styles}). @item [] contain symbols excluded from color scheme parsing (see @ref{Color scheme}); operation of getting n-th character from MGL string. @item @{@} contain extended specification of color (see @ref{Color styles}), dashing (see @ref{Line styles}) or mask (see @ref{Color scheme}); denote special operation in @ref{MGL scripts}; denote 'meta-symbol' for LaTeX like string parsing (see @ref{Font styles}). @item | line dashing style (see @ref{Line styles}); set to use sharp color scheme (see @ref{Color scheme}); set to limit width by subplot width for @ref{table}; delimiter in @ref{list} command; operation in @ref{Textual formulas}. @item \ string continuation symbol on next line for @ref{MGL scripts}. @item ~ disable drawing of tick labels for @ref{axis} and @ref{colorbar}; disable first segment in @ref{lamerey}; reduce number of segments in @ref{plot} and @ref{tens}; one of mask for face filling (see @ref{Color scheme}). @item 0,1,2,3,4,5,6,7,8,9 line width (see @ref{Line styles}); brightness of a color (see @ref{Color styles}); precision of numbers in @ref{axis}, @ref{label}, @ref{table}; kind of smoothing (for digits 1,3,5) in @ref{smooth}; digits for a value. @item 4,6,8 set to draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}. @item A,B,C,D,E,F,a,b,c,d,e,f can be hex-digit for color specification if placed inside @{@} (see @ref{Color styles}). @item A arrow style (see @ref{Line styles}); set to use absolute position in whole picture for @ref{text}, @ref{colorbar}, @ref{legend}. @item a set to use absolute position in subplot for @ref{text}; style of @ref{plot}, @ref{radar}, @ref{tens}, @ref{area}, @ref{region} to draw segments between points outside of axis range; style of @ref{bars}, @ref{barh}, @ref{cones}. @item B dark blue color (see @ref{Color styles}). @item b blue color (see @ref{Color styles}); bold font face if placed after @samp{:} (see @ref{Font styles}). @item C dark cyan color (see @ref{Color styles}); align text to center if placed after @samp{:} (see @ref{Font styles}). @item c cyan color (see @ref{Color styles}); name of color axis; cosine transform for @ref{transform}. @item D arrow style (see @ref{Line styles}); one of mask for face filling (see @ref{Color scheme}). @item d one of marks (see @ref{Line styles}) or kind of @ref{error} boxes; one of mask for face filling (see @ref{Color scheme}); start hex-dash description if placed inside @{@} (see @ref{Line styles}). @item E dark green-yellow color (see @ref{Color styles}). @item e green-yellow color (see @ref{Color styles}). @item F set fixed bar widths in @ref{bars}, @ref{barh}; set LaTeX-like format for numbers in @ref{axis}, @ref{label}, @ref{table}. @item f style of @ref{bars}, @ref{barh}; style of @ref{vect}, @ref{vect3}; set fixed format for numbers in @ref{axis}, @ref{label}, @ref{table}; Fourier transform for @ref{transform}. @item G dark green color (see @ref{Color styles}). @item g green color (see @ref{Color styles}). @item H dark gray color (see @ref{Color styles}). @item h gray color (see @ref{Color styles}); Hankel transform for @ref{transform}. @item I arrow style (see @ref{Line styles}); set @ref{colorbar} position near boundary. @item i line dashing style (see @ref{Line styles}); italic font face if placed after @samp{:} (see @ref{Font styles}). set to use inverse values for @ref{cloud}, @ref{pipe}, @ref{dew}; set to fill only area with y1