mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:35:59 +00:00
[WINESYNC] d3dx9: Don't expose struct d3dx9_base_effect outside effect.c.
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org> wine commit id baf4aaa359c75715e7840b4c045fdb22adf2bc8a by Michael Stefaniuc <mstefani@winehq.org>
This commit is contained in:
parent
81c4bfa714
commit
a639b63404
4 changed files with 28 additions and 31 deletions
|
@ -342,7 +342,7 @@ struct d3dx_shared_data
|
||||||
ULONG64 update_version;
|
ULONG64 update_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct d3dx9_base_effect;
|
struct d3dx_effect;
|
||||||
|
|
||||||
static inline BOOL is_top_level_parameter(struct d3dx_parameter *param)
|
static inline BOOL is_top_level_parameter(struct d3dx_parameter *param)
|
||||||
{
|
{
|
||||||
|
@ -375,7 +375,7 @@ static inline BOOL is_param_dirty(struct d3dx_parameter *param, ULONG64 update_v
|
||||||
return is_top_level_param_dirty(param->top_level_param, update_version);
|
return is_top_level_param_dirty(param->top_level_param, update_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
|
struct d3dx_parameter *get_parameter_by_name(struct d3dx_effect *effect,
|
||||||
struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
|
struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#ifdef __REACTOS__
|
#ifdef __REACTOS__
|
||||||
|
@ -388,7 +388,7 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
|
||||||
#define SET_D3D_STATE(base_effect, args...) SET_D3D_STATE_(base_effect->manager, base_effect->device, args)
|
#define SET_D3D_STATE(base_effect, args...) SET_D3D_STATE_(base_effect->manager, base_effect->device, args)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code,
|
HRESULT d3dx_create_param_eval(struct d3dx_effect *effect, void *byte_code,
|
||||||
unsigned int byte_code_size, D3DXPARAMETER_TYPE type,
|
unsigned int byte_code_size, D3DXPARAMETER_TYPE type,
|
||||||
struct d3dx_param_eval **peval, ULONG64 *version_counter,
|
struct d3dx_param_eval **peval, ULONG64 *version_counter,
|
||||||
const char **skip_constants, unsigned int skip_constants_count) DECLSPEC_HIDDEN;
|
const char **skip_constants, unsigned int skip_constants_count) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -514,7 +514,7 @@ static struct d3dx_parameter *get_valid_parameter(struct d3dx_effect *effect, D3
|
||||||
return handle_param;
|
return handle_param;
|
||||||
|
|
||||||
return effect->base_effect.flags & D3DXFX_LARGEADDRESSAWARE
|
return effect->base_effect.flags & D3DXFX_LARGEADDRESSAWARE
|
||||||
? NULL : get_parameter_by_name(&effect->base_effect, NULL, parameter);
|
? NULL : get_parameter_by_name(effect, NULL, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_state(struct d3dx_state *state)
|
static void free_state(struct d3dx_state *state)
|
||||||
|
@ -842,7 +842,7 @@ static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_effect *
|
||||||
switch (*part++)
|
switch (*part++)
|
||||||
{
|
{
|
||||||
case '.':
|
case '.':
|
||||||
return get_parameter_by_name(&effect->base_effect, temp_parameter, part);
|
return get_parameter_by_name(effect, temp_parameter, part);
|
||||||
|
|
||||||
case '\0':
|
case '\0':
|
||||||
TRACE("Returning parameter %p\n", temp_parameter);
|
TRACE("Returning parameter %p\n", temp_parameter);
|
||||||
|
@ -861,7 +861,6 @@ static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_effect *
|
||||||
static struct d3dx_parameter *get_annotation_by_name(struct d3dx_effect *effect, unsigned int count,
|
static struct d3dx_parameter *get_annotation_by_name(struct d3dx_effect *effect, unsigned int count,
|
||||||
struct d3dx_parameter *annotations, const char *name)
|
struct d3dx_parameter *annotations, const char *name)
|
||||||
{
|
{
|
||||||
struct d3dx9_base_effect *base = &effect->base_effect;
|
|
||||||
UINT i, length;
|
UINT i, length;
|
||||||
struct d3dx_parameter *temp_parameter;
|
struct d3dx_parameter *temp_parameter;
|
||||||
const char *part;
|
const char *part;
|
||||||
|
@ -887,7 +886,7 @@ static struct d3dx_parameter *get_annotation_by_name(struct d3dx_effect *effect,
|
||||||
switch (*part++)
|
switch (*part++)
|
||||||
{
|
{
|
||||||
case '.':
|
case '.':
|
||||||
return get_parameter_by_name(base, temp_parameter, part);
|
return get_parameter_by_name(effect, temp_parameter, part);
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
return get_parameter_element_by_name(effect, temp_parameter, part);
|
return get_parameter_element_by_name(effect, temp_parameter, part);
|
||||||
|
@ -903,10 +902,9 @@ static struct d3dx_parameter *get_annotation_by_name(struct d3dx_effect *effect,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
|
struct d3dx_parameter *get_parameter_by_name(struct d3dx_effect* effect,
|
||||||
struct d3dx_parameter *parameter, const char *name)
|
struct d3dx_parameter *parameter, const char *name)
|
||||||
{
|
{
|
||||||
struct d3dx_effect *effect = base->effect;
|
|
||||||
struct d3dx_parameter *temp_parameter;
|
struct d3dx_parameter *temp_parameter;
|
||||||
unsigned int name_len, param_name_len;
|
unsigned int name_len, param_name_len;
|
||||||
unsigned int i, count, length;
|
unsigned int i, count, length;
|
||||||
|
@ -915,7 +913,7 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
|
||||||
const char *part;
|
const char *part;
|
||||||
char *full_name;
|
char *full_name;
|
||||||
|
|
||||||
TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
|
TRACE("effect %p, parameter %p, name %s.\n", effect, parameter, debugstr_a(name));
|
||||||
|
|
||||||
if (!name || !*name) return NULL;
|
if (!name || !*name) return NULL;
|
||||||
|
|
||||||
|
@ -976,7 +974,7 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
|
||||||
switch (*part++)
|
switch (*part++)
|
||||||
{
|
{
|
||||||
case '.':
|
case '.':
|
||||||
return get_parameter_by_name(base, temp_parameter, part);
|
return get_parameter_by_name(effect, temp_parameter, part);
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
return get_parameter_element_by_name(effect, temp_parameter, part);
|
return get_parameter_element_by_name(effect, temp_parameter, part);
|
||||||
|
@ -2025,7 +2023,7 @@ static D3DXHANDLE WINAPI d3dx_effect_GetParameterByName(ID3DXEffect *iface, D3DX
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = get_parameter_handle(get_parameter_by_name(&effect->base_effect, param, name));
|
handle = get_parameter_handle(get_parameter_by_name(effect, param, name));
|
||||||
TRACE("Returning parameter %p.\n", handle);
|
TRACE("Returning parameter %p.\n", handle);
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -5725,7 +5723,6 @@ static HRESULT d3dx9_create_object(struct d3dx9_base_effect *base, struct d3dx_o
|
||||||
static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx_state *state,
|
static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx_state *state,
|
||||||
const char **skip_constants, unsigned int skip_constants_count)
|
const char **skip_constants, unsigned int skip_constants_count)
|
||||||
{
|
{
|
||||||
struct d3dx9_base_effect *base = &effect->base_effect;
|
|
||||||
DWORD string_size;
|
DWORD string_size;
|
||||||
struct d3dx_parameter *param = &state->parameter;
|
struct d3dx_parameter *param = &state->parameter;
|
||||||
struct d3dx_object *object = &effect->objects[param->object_id];
|
struct d3dx_object *object = &effect->objects[param->object_id];
|
||||||
|
@ -5735,7 +5732,7 @@ static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx
|
||||||
TRACE("Parsing array entry selection state for parameter %p.\n", param);
|
TRACE("Parsing array entry selection state for parameter %p.\n", param);
|
||||||
|
|
||||||
string_size = *(DWORD *)ptr;
|
string_size = *(DWORD *)ptr;
|
||||||
state->referenced_param = get_parameter_by_name(base, NULL, ptr + 4);
|
state->referenced_param = get_parameter_by_name(effect, NULL, ptr + 4);
|
||||||
if (state->referenced_param)
|
if (state->referenced_param)
|
||||||
{
|
{
|
||||||
TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
|
TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
|
||||||
|
@ -5749,7 +5746,7 @@ static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx
|
||||||
|
|
||||||
if (string_size % sizeof(DWORD))
|
if (string_size % sizeof(DWORD))
|
||||||
FIXME("Unaligned string_size %u.\n", string_size);
|
FIXME("Unaligned string_size %u.\n", string_size);
|
||||||
if (FAILED(ret = d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1,
|
if (FAILED(ret = d3dx_create_param_eval(effect, (DWORD *)(ptr + string_size) + 1,
|
||||||
object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, ¶m->param_eval,
|
object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, ¶m->param_eval,
|
||||||
get_version_counter_ptr(effect), NULL, 0)))
|
get_version_counter_ptr(effect), NULL, 0)))
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -5770,7 +5767,7 @@ static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx
|
||||||
{
|
{
|
||||||
TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
|
TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
|
||||||
object = &effect->objects[param->members[i].object_id];
|
object = &effect->objects[param->members[i].object_id];
|
||||||
if (FAILED(ret = d3dx_create_param_eval(base, object->data, object->size, param->type,
|
if (FAILED(ret = d3dx_create_param_eval(effect, object->data, object->size, param->type,
|
||||||
¶m->members[i].param_eval, get_version_counter_ptr(effect),
|
¶m->members[i].param_eval, get_version_counter_ptr(effect),
|
||||||
skip_constants, skip_constants_count)))
|
skip_constants, skip_constants_count)))
|
||||||
break;
|
break;
|
||||||
|
@ -5889,7 +5886,7 @@ static HRESULT d3dx_parse_resource(struct d3dx_effect *effect, const char *data,
|
||||||
{
|
{
|
||||||
if (FAILED(hr = d3dx9_create_object(base, object)))
|
if (FAILED(hr = d3dx9_create_object(base, object)))
|
||||||
return hr;
|
return hr;
|
||||||
if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
|
if (FAILED(hr = d3dx_create_param_eval(effect, object->data, object->size, param->type,
|
||||||
¶m->param_eval, get_version_counter_ptr(effect),
|
¶m->param_eval, get_version_counter_ptr(effect),
|
||||||
skip_constants, skip_constants_count)))
|
skip_constants, skip_constants_count)))
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -5903,7 +5900,7 @@ static HRESULT d3dx_parse_resource(struct d3dx_effect *effect, const char *data,
|
||||||
state->type = ST_FXLC;
|
state->type = ST_FXLC;
|
||||||
if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
|
if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
|
||||||
return hr;
|
return hr;
|
||||||
if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
|
if (FAILED(hr = d3dx_create_param_eval(effect, object->data, object->size, param->type,
|
||||||
¶m->param_eval, get_version_counter_ptr(effect), NULL, 0)))
|
¶m->param_eval, get_version_counter_ptr(effect), NULL, 0)))
|
||||||
return hr;
|
return hr;
|
||||||
break;
|
break;
|
||||||
|
@ -5920,7 +5917,7 @@ static HRESULT d3dx_parse_resource(struct d3dx_effect *effect, const char *data,
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
|
TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
|
||||||
state->referenced_param = get_parameter_by_name(base, NULL, object->data);
|
state->referenced_param = get_parameter_by_name(effect, NULL, object->data);
|
||||||
if (state->referenced_param)
|
if (state->referenced_param)
|
||||||
{
|
{
|
||||||
struct d3dx_parameter *refpar = state->referenced_param;
|
struct d3dx_parameter *refpar = state->referenced_param;
|
||||||
|
@ -5932,7 +5929,7 @@ static HRESULT d3dx_parse_resource(struct d3dx_effect *effect, const char *data,
|
||||||
|
|
||||||
if (!refpar->param_eval)
|
if (!refpar->param_eval)
|
||||||
{
|
{
|
||||||
if (FAILED(hr = d3dx_create_param_eval(base, refobj->data, refobj->size,
|
if (FAILED(hr = d3dx_create_param_eval(effect, refobj->data, refobj->size,
|
||||||
refpar->type, &refpar->param_eval, get_version_counter_ptr(effect),
|
refpar->type, &refpar->param_eval, get_version_counter_ptr(effect),
|
||||||
skip_constants, skip_constants_count)))
|
skip_constants, skip_constants_count)))
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -6296,7 +6293,7 @@ static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
|
||||||
for (i = 0; i < skip_constants_count; ++i)
|
for (i = 0; i < skip_constants_count; ++i)
|
||||||
{
|
{
|
||||||
struct d3dx_parameter *param;
|
struct d3dx_parameter *param;
|
||||||
param = get_parameter_by_name(base, NULL, skip_constants[i]);
|
param = get_parameter_by_name(effect, NULL, skip_constants[i]);
|
||||||
if (param)
|
if (param)
|
||||||
{
|
{
|
||||||
for (j = 0; j < base->technique_count; ++j)
|
for (j = 0; j < base->technique_count; ++j)
|
||||||
|
|
|
@ -865,7 +865,7 @@ static HRESULT init_set_constants_param(struct d3dx_const_tab *const_tab, ID3DXC
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab *out,
|
static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab *out,
|
||||||
struct d3dx9_base_effect *base, const char **skip_constants,
|
struct d3dx_effect *effect, const char **skip_constants,
|
||||||
unsigned int skip_constants_count, struct d3dx_preshader *pres)
|
unsigned int skip_constants_count, struct d3dx_preshader *pres)
|
||||||
{
|
{
|
||||||
ID3DXConstantTable *ctab;
|
ID3DXConstantTable *ctab;
|
||||||
|
@ -910,7 +910,7 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab
|
||||||
}
|
}
|
||||||
if (FAILED(hr = get_ctab_constant_desc(ctab, hc, &cdesc[index], &constantinfo_reserved)))
|
if (FAILED(hr = get_ctab_constant_desc(ctab, hc, &cdesc[index], &constantinfo_reserved)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
inputs_param[index] = get_parameter_by_name(base, NULL, cdesc[index].Name);
|
inputs_param[index] = get_parameter_by_name(effect, NULL, cdesc[index].Name);
|
||||||
if (!inputs_param[index])
|
if (!inputs_param[index])
|
||||||
{
|
{
|
||||||
WARN("Could not find parameter %s in effect.\n", cdesc[index].Name);
|
WARN("Could not find parameter %s in effect.\n", cdesc[index].Name);
|
||||||
|
@ -1115,7 +1115,7 @@ static void dump_preshader(struct d3dx_preshader *pres)
|
||||||
dump_ins(&pres->regs, &pres->ins[i]);
|
dump_ins(&pres->regs, &pres->ins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, unsigned int count, struct d3dx9_base_effect *base)
|
static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, unsigned int count, struct d3dx_effect *effect)
|
||||||
{
|
{
|
||||||
unsigned int *p;
|
unsigned int *p;
|
||||||
unsigned int i, j, const_count;
|
unsigned int i, j, const_count;
|
||||||
|
@ -1182,7 +1182,7 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u
|
||||||
|
|
||||||
saved_word = *ptr;
|
saved_word = *ptr;
|
||||||
*ptr = 0xfffe0000;
|
*ptr = 0xfffe0000;
|
||||||
hr = get_constants_desc(ptr, &pres->inputs, base, NULL, 0, NULL);
|
hr = get_constants_desc(ptr, &pres->inputs, effect, NULL, 0, NULL);
|
||||||
*ptr = saved_word;
|
*ptr = saved_word;
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1235,7 +1235,7 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, unsigned int byte_code_size,
|
HRESULT d3dx_create_param_eval(struct d3dx_effect *effect, void *byte_code, unsigned int byte_code_size,
|
||||||
D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out, ULONG64 *version_counter,
|
D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out, ULONG64 *version_counter,
|
||||||
const char **skip_constants, unsigned int skip_constants_count)
|
const char **skip_constants, unsigned int skip_constants_count)
|
||||||
{
|
{
|
||||||
|
@ -1246,8 +1246,8 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte
|
||||||
unsigned int count, pres_size;
|
unsigned int count, pres_size;
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
|
|
||||||
TRACE("base_effect %p, byte_code %p, byte_code_size %u, type %u, peval_out %p.\n",
|
TRACE("effect %p, byte_code %p, byte_code_size %u, type %u, peval_out %p.\n",
|
||||||
base_effect, byte_code, byte_code_size, type, peval_out);
|
effect, byte_code, byte_code_size, type, peval_out);
|
||||||
|
|
||||||
count = byte_code_size / sizeof(unsigned int);
|
count = byte_code_size / sizeof(unsigned int);
|
||||||
if (!byte_code || !count)
|
if (!byte_code || !count)
|
||||||
|
@ -1297,7 +1297,7 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte
|
||||||
pres_size = count;
|
pres_size = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr && FAILED(ret = parse_preshader(&peval->pres, ptr, pres_size, base_effect)))
|
if (ptr && FAILED(ret = parse_preshader(&peval->pres, ptr, pres_size, effect)))
|
||||||
{
|
{
|
||||||
FIXME("Failed parsing preshader, byte code for analysis follows.\n");
|
FIXME("Failed parsing preshader, byte code for analysis follows.\n");
|
||||||
dump_bytecode(byte_code, byte_code_size);
|
dump_bytecode(byte_code, byte_code_size);
|
||||||
|
@ -1306,7 +1306,7 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte
|
||||||
|
|
||||||
if (shader)
|
if (shader)
|
||||||
{
|
{
|
||||||
if (FAILED(ret = get_constants_desc(shader_ptr, &peval->shader_inputs, base_effect,
|
if (FAILED(ret = get_constants_desc(shader_ptr, &peval->shader_inputs, effect,
|
||||||
skip_constants, skip_constants_count, &peval->pres)))
|
skip_constants, skip_constants_count, &peval->pres)))
|
||||||
{
|
{
|
||||||
TRACE("Could not get shader constant table, hr %#x.\n", ret);
|
TRACE("Could not get shader constant table, hr %#x.\n", ret);
|
||||||
|
|
|
@ -15,4 +15,4 @@ files: {include/d3dx9.h: sdk/include/dxsdk/d3dx9.h, include/d3dx9anim.h: sdk/inc
|
||||||
include/d3dx9mesh.h: sdk/include/dxsdk/d3dx9mesh.h, include/d3dx9of.h: sdk/include/dxsdk/d3dx9of.h,
|
include/d3dx9mesh.h: sdk/include/dxsdk/d3dx9mesh.h, include/d3dx9of.h: sdk/include/dxsdk/d3dx9of.h,
|
||||||
include/d3dx9shader.h: sdk/include/dxsdk/d3dx9shader.h, include/d3dx9shape.h: sdk/include/dxsdk/d3dx9shape.h,
|
include/d3dx9shader.h: sdk/include/dxsdk/d3dx9shader.h, include/d3dx9shape.h: sdk/include/dxsdk/d3dx9shape.h,
|
||||||
include/d3dx9tex.h: sdk/include/dxsdk/d3dx9tex.h, include/d3dx9xof.h: sdk/include/dxsdk/d3dx9xof.h}
|
include/d3dx9tex.h: sdk/include/dxsdk/d3dx9tex.h, include/d3dx9xof.h: sdk/include/dxsdk/d3dx9xof.h}
|
||||||
tags: {wine: 09770370c0b9159d3324684146544b6f441e4889}
|
tags: {wine: baf4aaa359c75715e7840b4c045fdb22adf2bc8a}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue